aboutsummaryrefslogtreecommitdiff
path: root/cmake
diff options
context:
space:
mode:
authorLasse Collin <lasse.collin@tukaani.org>2020-03-11 13:05:29 +0200
committerLasse Collin <lasse.collin@tukaani.org>2020-03-11 13:05:29 +0200
commit1acc48794364606c9091cae6fa56db75a1325114 (patch)
tree724c726a04570ff3c5ecbf6066cc00170c3841a7 /cmake
parentBuild: Add support for --no-po4a option to autogen.sh. (diff)
downloadxz-1acc48794364606c9091cae6fa56db75a1325114.tar.xz
Build: Add very limited experimental CMake support.
This version matches CMake files in the master branch (commit 265daa873c0d871f5f23f9b56e133a6f20045a0a) except that this omits two source files that aren't in v5.2 and in the beginning of CMakeLists.txt the first paragraph in the comment is slightly different to point out possible issues in building shared liblzma.
Diffstat (limited to 'cmake')
-rw-r--r--cmake/tuklib_common.cmake49
-rw-r--r--cmake/tuklib_cpucores.cmake175
-rw-r--r--cmake/tuklib_integer.cmake102
-rw-r--r--cmake/tuklib_mbstr.cmake20
-rw-r--r--cmake/tuklib_physmem.cmake150
-rw-r--r--cmake/tuklib_progname.cmake19
6 files changed, 515 insertions, 0 deletions
diff --git a/cmake/tuklib_common.cmake b/cmake/tuklib_common.cmake
new file mode 100644
index 00000000..088a3cb1
--- /dev/null
+++ b/cmake/tuklib_common.cmake
@@ -0,0 +1,49 @@
+#
+# tuklib_common.cmake - common functions and macros for tuklib_*.cmake files
+#
+# Author: Lasse Collin
+#
+# This file has been put into the public domain.
+# You can do whatever you want with this file.
+#
+
+function(tuklib_add_definitions TARGET_OR_ALL DEFINITIONS)
+ # DEFINITIONS may be an empty string/list but it's fine here. There is
+ # no need to quote ${DEFINITIONS} as empty arguments are fine here.
+ if(TARGET_OR_ALL STREQUAL "ALL")
+ add_compile_definitions(${DEFINITIONS})
+ else()
+ target_compile_definitions("${TARGET_OR_ALL}" PRIVATE ${DEFINITIONS})
+ endif()
+endfunction()
+
+function(tuklib_add_definition_if TARGET_OR_ALL VAR)
+ if(${VAR})
+ tuklib_add_definitions("${TARGET_OR_ALL}" "${VAR}")
+ endif()
+endfunction()
+
+# This is an over-simplified version of AC_USE_SYSTEM_EXTENSIONS in Autoconf
+# or gl_USE_SYSTEM_EXTENSIONS in gnulib.
+macro(tuklib_use_system_extensions TARGET_OR_ALL)
+ if(NOT WIN32)
+ # FIXME? The Solaris-specific __EXTENSIONS__ should be conditional
+ # even on Solaris. See gnulib: git log m4/extensions.m4.
+ # FIXME? gnulib and autoconf.git has lots of new stuff.
+ tuklib_add_definitions("${TARGET_OR_ALL}"
+ _GNU_SOURCE
+ __EXTENSIONS__
+ _POSIX_PTHREAD_SEMANTICS
+ _TANDEM_SOURCE
+ _ALL_SOURCE
+ )
+
+ list(APPEND CMAKE_REQUIRED_DEFINITIONS
+ -D_GNU_SOURCE
+ -D__EXTENSIONS__
+ -D_POSIX_PTHREAD_SEMANTICS
+ -D_TANDEM_SOURCE
+ -D_ALL_SOURCE
+ )
+ endif()
+endmacro()
diff --git a/cmake/tuklib_cpucores.cmake b/cmake/tuklib_cpucores.cmake
new file mode 100644
index 00000000..5844e4b2
--- /dev/null
+++ b/cmake/tuklib_cpucores.cmake
@@ -0,0 +1,175 @@
+#
+# tuklib_cpucores.cmake - see tuklib_cpucores.m4 for description and comments
+#
+# Author: Lasse Collin
+#
+# This file has been put into the public domain.
+# You can do whatever you want with this file.
+#
+
+include("${CMAKE_CURRENT_LIST_DIR}/tuklib_common.cmake")
+include(CheckCSourceCompiles)
+include(CheckIncludeFile)
+
+function(tuklib_cpucores_internal_check)
+ if(WIN32 OR CYGWIN)
+ # Nothing to do, the tuklib_cpucores.c handles it.
+ set(TUKLIB_CPUCORES_DEFINITIONS "" CACHE INTERNAL "")
+ return()
+ endif()
+
+ # glibc-based systems (GNU/Linux and GNU/kFreeBSD) have
+ # sched_getaffinity(). The CPU_COUNT() macro was added in glibc 2.9.
+ # glibc 2.9 is old enough that if someone uses the code on older glibc,
+ # the fallback to sysconf() should be good enough.
+ #
+ # NOTE: This required that _GNU_SOURCE is defined. We assume that whatever
+ # feature test macros the caller wants to use are already set in
+ # CMAKE_REQUIRED_DEFINES and in the target defines.
+ check_c_source_compiles("
+ #include <sched.h>
+ int main(void)
+ {
+ cpu_set_t cpu_mask;
+ sched_getaffinity(0, sizeof(cpu_mask), &cpu_mask);
+ return CPU_COUNT(&cpu_mask);
+ }
+ "
+ TUKLIB_CPUCORES_SCHED_GETAFFINITY)
+ if(TUKLIB_CPUCORES_SCHED_GETAFFINITY)
+ set(TUKLIB_CPUCORES_DEFINITIONS
+ "TUKLIB_CPUCORES_SCHED_GETAFFINITY"
+ CACHE INTERNAL "")
+ return()
+ endif()
+
+ # FreeBSD has both cpuset and sysctl. Look for cpuset first because
+ # it's a better approach.
+ #
+ # This test would match on GNU/kFreeBSD too but it would require
+ # -lfreebsd-glue when linking and thus in the current form this would
+ # fail on GNU/kFreeBSD. The above test for sched_getaffinity() matches
+ # on GNU/kFreeBSD so the test below should never run on that OS.
+ check_c_source_compiles("
+ #include <sys/param.h>
+ #include <sys/cpuset.h>
+ int main(void)
+ {
+ cpuset_t set;
+ cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1,
+ sizeof(set), &set);
+ return 0;
+ }
+ "
+ TUKLIB_CPUCORES_CPUSET)
+ if(TUKLIB_CPUCORES_CPUSET)
+ set(TUKLIB_CPUCORES_DEFINITIONS "HAVE_PARAM_H;TUKLIB_CPUCORES_CPUSET"
+ CACHE INTERNAL "")
+ return()
+ endif()
+
+ # On OS/2, both sysconf() and sysctl() pass the tests in this file,
+ # but only sysctl() works. On QNX it's the opposite: only sysconf() works
+ # (although it assumes that _POSIX_SOURCE, _XOPEN_SOURCE, and
+ # _POSIX_C_SOURCE are undefined or alternatively _QNX_SOURCE is defined).
+ #
+ # We test sysctl() first and intentionally break the sysctl() test on QNX
+ # so that sysctl() is never used on QNX.
+ check_include_file(sys/param.h HAVE_SYS_PARAM_H)
+ if(HAVE_SYS_PARAM_H)
+ list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_SYS_PARAM_H)
+ endif()
+ check_c_source_compiles("
+ #ifdef __QNX__
+ compile error
+ #endif
+ #ifdef HAVE_SYS_PARAM_H
+ # include <sys/param.h>
+ #endif
+ #include <sys/sysctl.h>
+ int main(void)
+ {
+ int name[2] = { CTL_HW, HW_NCPU };
+ int cpus;
+ size_t cpus_size = sizeof(cpus);
+ sysctl(name, 2, &cpus, &cpus_size, NULL, 0);
+ return 0;
+ }
+ "
+ TUKLIB_CPUCORES_SYSCTL)
+ if(TUKLIB_CPUCORES_SYSCTL)
+ if(HAVE_SYS_PARAM_H)
+ set(TUKLIB_CPUCORES_DEFINITIONS
+ "HAVE_PARAM_H;TUKLIB_CPUCORES_SYSCTL"
+ CACHE INTERNAL "")
+ else()
+ set(TUKLIB_CPUCORES_DEFINITIONS
+ "TUKLIB_CPUCORES_SYSCTL"
+ CACHE INTERNAL "")
+ endif()
+ return()
+ endif()
+
+ # Many platforms support sysconf().
+ check_c_source_compiles("
+ #include <unistd.h>
+ int main(void)
+ {
+ long i;
+ #ifdef _SC_NPROCESSORS_ONLN
+ /* Many systems using sysconf() */
+ i = sysconf(_SC_NPROCESSORS_ONLN);
+ #else
+ /* IRIX */
+ i = sysconf(_SC_NPROC_ONLN);
+ #endif
+ return 0;
+ }
+ "
+ TUKLIB_CPUCORES_SYSCONF)
+ if(TUKLIB_CPUCORES_SYSCONF)
+ set(TUKLIB_CPUCORES_DEFINITIONS "TUKLIB_CPUCORES_SYSCONF"
+ CACHE INTERNAL "")
+ return()
+ endif()
+
+ # HP-UX
+ check_c_source_compiles("
+ #include <sys/param.h>
+ #include <sys/pstat.h>
+ int main(void)
+ {
+ struct pst_dynamic pst;
+ pstat_getdynamic(&pst, sizeof(pst), 1, 0);
+ (void)pst.psd_proc_cnt;
+ return 0;
+ }
+ "
+ TUKLIB_CPUCORES_PSTAT_GETDYNAMIC)
+ if(TUKLIB_CPUCORES_PSTAT_GETDYNAMIC)
+ set(TUKLIB_CPUCORES_DEFINITIONS "TUKLIB_CPUCORES_PSTAT_GETDYNAMIC"
+ CACHE INTERNAL "")
+ return()
+ endif()
+endfunction()
+
+function(tuklib_cpucores TARGET_OR_ALL)
+ if(NOT DEFINED CACHE{TUKLIB_CPUCORES_FOUND})
+ message(STATUS
+ "Checking how to detect the number of available CPU cores")
+ tuklib_cpucores_internal_check()
+
+ if(DEFINED CACHE{TUKLIB_CPUCORES_DEFINITIONS})
+ set(TUKLIB_CPUCORES_FOUND 1 CACHE INTERNAL "")
+ else()
+ set(TUKLIB_CPUCORES_FOUND 0 CACHE INTERNAL "")
+ message(WARNING
+ "No method to detect the number of CPU cores was found")
+ endif()
+ endif()
+
+ if(TUKLIB_CPUCORES_FOUND)
+ tuklib_add_definitions("${TARGET_OR_ALL}"
+ "${TUKLIB_CPUCORES_DEFINITIONS}")
+ endif()
+endfunction()
diff --git a/cmake/tuklib_integer.cmake b/cmake/tuklib_integer.cmake
new file mode 100644
index 00000000..d7e2e28c
--- /dev/null
+++ b/cmake/tuklib_integer.cmake
@@ -0,0 +1,102 @@
+#
+# tuklib_integer.cmake - see tuklib_integer.m4 for description and comments
+#
+# Author: Lasse Collin
+#
+# This file has been put into the public domain.
+# You can do whatever you want with this file.
+#
+
+include("${CMAKE_CURRENT_LIST_DIR}/tuklib_common.cmake")
+include(TestBigEndian)
+include(CheckCSourceCompiles)
+include(CheckIncludeFile)
+include(CheckSymbolExists)
+
+function(tuklib_integer TARGET_OR_ALL)
+ # Check for endianness. Unlike the Autoconf's AC_C_BIGENDIAN, this doesn't
+ # support Apple universal binaries. The CMake module will leave the
+ # variable unset so we can catch that situation here instead of continuing
+ # as if we were little endian.
+ test_big_endian(WORDS_BIGENDIAN)
+ if(NOT DEFINED WORDS_BIGENDIAN)
+ message(FATAL_ERROR "Cannot determine endianness")
+ endif()
+ tuklib_add_definition_if("${TARGET_OR_ALL}" WORDS_BIGENDIAN)
+
+ # Look for a byteswapping method.
+ check_c_source_compiles("
+ int main(void)
+ {
+ __builtin_bswap16(1);
+ __builtin_bswap32(1);
+ __builtin_bswap64(1);
+ return 0;
+ }
+ "
+ HAVE___BUILTIN_BSWAPXX)
+ if(HAVE___BUILTIN_BSWAPXX)
+ tuklib_add_definitions("${TARGET_OR_ALL}" HAVE___BUILTIN_BSWAPXX)
+ else()
+ check_include_file(byteswap.h HAVE_BYTESWAP_H)
+ if(HAVE_BYTESWAP_H)
+ tuklib_add_definitions("${TARGET_OR_ALL}" HAVE_BYTESWAP_H)
+ check_symbol_exists(bswap_16 byteswap.h HAVE_BSWAP_16)
+ tuklib_add_definition_if("${TARGET_OR_ALL}" HAVE_BSWAP_16)
+ check_symbol_exists(bswap_32 byteswap.h HAVE_BSWAP_32)
+ tuklib_add_definition_if("${TARGET_OR_ALL}" HAVE_BSWAP_32)
+ check_symbol_exists(bswap_64 byteswap.h HAVE_BSWAP_64)
+ tuklib_add_definition_if("${TARGET_OR_ALL}" HAVE_BSWAP_64)
+ else()
+ check_include_file(sys/endian.h HAVE_SYS_ENDIAN_H)
+ if(HAVE_SYS_ENDIAN_H)
+ tuklib_add_definitions("${TARGET_OR_ALL}" HAVE_SYS_ENDIAN_H)
+ else()
+ check_include_file(sys/byteorder.h HAVE_SYS_BYTEORDER_H)
+ tuklib_add_definition_if("${TARGET_OR_ALL}"
+ HAVE_SYS_BYTEORDER_H)
+ endif()
+ endif()
+ endif()
+
+ # 16-bit and 32-bit unaligned access is fast on x86(-64),
+ # big endian PowerPC, and usually on 32/64-bit ARM too.
+ # There are others too and ARM could be a false match.
+ #
+ # Guess the default value for the option.
+ # CMake's ability to give info about the target arch seems bad.
+ # The the same arch can have different name depending on the OS.
+ #
+ # FIXME: The regex is based on guessing, not on factual information!
+ #
+ # NOTE: Compared to the Autoconf test, this lacks the GCC/Clang test
+ # on ARM and always assumes that unaligned is fast on ARM.
+ set(FAST_UNALIGNED_GUESS OFF)
+ if(CMAKE_SYSTEM_PROCESSOR MATCHES
+ "[Xx3456]86|^[Xx]64|^[Aa][Mm][Dd]64|^[Aa][Rr][Mm]|^aarch|^powerpc|^ppc")
+ if(NOT WORDS_BIGENDIAN OR
+ NOT CMAKE_SYSTEM_PROCESSOR MATCHES "^powerpc|^ppc")
+ set(FAST_UNALIGNED_GUESS ON)
+ endif()
+ endif()
+ option(TUKLIB_FAST_UNALIGNED_ACCESS
+ "Enable if the system supports *fast* unaligned memory access \
+with 16-bit and 32-bit integers."
+ "${FAST_UNALIGNED_GUESS}")
+ tuklib_add_definition_if("${TARGET_OR_ALL}" TUKLIB_FAST_UNALIGNED_ACCESS)
+
+ # Unsafe type punning:
+ option(TUKLIB_USE_UNSAFE_TYPE_PUNNING
+ "This introduces strict aliasing violations and \
+may result in broken code. However, this might improve performance \
+in some cases, especially with old compilers \
+(e.g. GCC 3 and early 4.x on x86, GCC < 6 on ARMv6 and ARMv7)."
+ OFF)
+ tuklib_add_definition_if("${TARGET_OR_ALL}" TUKLIB_USE_UNSAFE_TYPE_PUNNING)
+
+ # Check for GCC/Clang __builtin_assume_aligned().
+ check_c_source_compiles(
+ "int main(void) { __builtin_assume_aligned(\"\", 1); return 0; }"
+ HAVE___BUILTIN_ASSUME_ALIGNED)
+ tuklib_add_definition_if("${TARGET_OR_ALL}" HAVE___BUILTIN_ASSUME_ALIGNED)
+endfunction()
diff --git a/cmake/tuklib_mbstr.cmake b/cmake/tuklib_mbstr.cmake
new file mode 100644
index 00000000..e073be6a
--- /dev/null
+++ b/cmake/tuklib_mbstr.cmake
@@ -0,0 +1,20 @@
+#
+# tuklib_mbstr.cmake - see tuklib_mbstr.m4 for description and comments
+#
+# Author: Lasse Collin
+#
+# This file has been put into the public domain.
+# You can do whatever you want with this file.
+#
+
+include("${CMAKE_CURRENT_LIST_DIR}/tuklib_common.cmake")
+include(CheckSymbolExists)
+
+function(tuklib_mbstr TARGET_OR_ALL)
+ check_symbol_exists(mbrtowc wchar.h HAVE_MBRTOWC)
+ tuklib_add_definition_if("${TARGET_OR_ALL}" HAVE_MBRTOWC)
+
+ # NOTE: wcwidth() requires _GNU_SOURCE or _XOPEN_SOURCE on GNU/Linux.
+ check_symbol_exists(wcwidth wchar.h HAVE_WCWIDTH)
+ tuklib_add_definition_if("${TARGET_OR_ALL}" HAVE_WCWIDTH)
+endfunction()
diff --git a/cmake/tuklib_physmem.cmake b/cmake/tuklib_physmem.cmake
new file mode 100644
index 00000000..ea5bcc46
--- /dev/null
+++ b/cmake/tuklib_physmem.cmake
@@ -0,0 +1,150 @@
+#
+# tuklib_physmem.cmake - see tuklib_physmem.m4 for description and comments
+#
+# NOTE: Compared tuklib_physmem.m4, this lacks support for Tru64, IRIX, and
+# Linux sysinfo() (usually sysconf() is used on GNU/Linux).
+#
+# Author: Lasse Collin
+#
+# This file has been put into the public domain.
+# You can do whatever you want with this file.
+#
+
+include("${CMAKE_CURRENT_LIST_DIR}/tuklib_common.cmake")
+include(CheckCSourceCompiles)
+include(CheckIncludeFile)
+
+function(tuklib_physmem_internal_check)
+ # Shortcut on Windows:
+ if(WIN32 OR CYGWIN)
+ # Nothing to do, the tuklib_physmem.c handles it.
+ set(TUKLIB_PHYSMEM_DEFINITIONS "" CACHE INTERNAL "")
+ return()
+ endif()
+
+ # Full check for special cases:
+ check_c_source_compiles("
+ #if defined(_WIN32) || defined(__CYGWIN__) || defined(__OS2__) \
+ || defined(__DJGPP__) || defined(__VMS) \
+ || defined(AMIGA) || defined(__AROS__) || defined(__QNX__)
+ int main(void) { return 0; }
+ #else
+ compile error
+ #endif
+ "
+ TUKLIB_PHYSMEM_SPECIAL)
+ if(TUKLIB_PHYSMEM_SPECIAL)
+ # Nothing to do, the tuklib_physmem.c handles it.
+ set(TUKLIB_PHYSMEM_DEFINITIONS "" CACHE INTERNAL "")
+ return()
+ endif()
+
+ # Look for AIX-specific solution before sysconf(), because the test
+ # for sysconf() will pass on AIX but won't actually work
+ # (sysconf(_SC_PHYS_PAGES) compiles but always returns -1 on AIX).
+ check_c_source_compiles("
+ #include <sys/systemcfg.h>
+ int main(void)
+ {
+ (void)_system_configuration.physmem;
+ return 0;
+ }
+ "
+ TUKLIB_PHYSMEM_AIX)
+ if(TUKLIB_PHYSMEM_AIX)
+ set(TUKLIB_PHYSMEM_DEFINITIONS "TUKLIB_PHYSMEM_AIX" CACHE INTERNAL "")
+ return()
+ endif()
+
+ # sysconf()
+ check_c_source_compiles("
+ #include <unistd.h>
+ int main(void)
+ {
+ long i;
+ i = sysconf(_SC_PAGESIZE);
+ i = sysconf(_SC_PHYS_PAGES);
+ return 0;
+ }
+ "
+ TUKLIB_PHYSMEM_SYSCONF)
+ if(TUKLIB_PHYSMEM_SYSCONF)
+ set(TUKLIB_PHYSMEM_DEFINITIONS "TUKLIB_PHYSMEM_SYSCONF"
+ CACHE INTERNAL "")
+ return()
+ endif()
+
+ # sysctl()
+ check_include_file(sys/param.h HAVE_SYS_PARAM_H)
+ if(HAVE_SYS_PARAM_H)
+ list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_SYS_PARAM_H)
+ endif()
+
+ check_c_source_compiles("
+ #ifdef HAVE_SYS_PARAM_H
+ # include <sys/param.h>
+ #endif
+ #include <sys/sysctl.h>
+ int main(void)
+ {
+ int name[2] = { CTL_HW, HW_PHYSMEM };
+ unsigned long mem;
+ size_t mem_ptr_size = sizeof(mem);
+ sysctl(name, 2, &mem, &mem_ptr_size, NULL, 0);
+ return 0;
+ }
+ "
+ TUKLIB_PHYSMEM_SYSCTL)
+ if(TUKLIB_PHYSMEM_SYSCTL)
+ if(HAVE_SYS_PARAM_H)
+ set(TUKLIB_PHYSMEM_DEFINITIONS
+ "HAVE_PARAM_H;TUKLIB_PHYSMEM_SYSCTL"
+ CACHE INTERNAL "")
+ else()
+ set(TUKLIB_PHYSMEM_DEFINITIONS
+ "TUKLIB_PHYSMEM_SYSCTL"
+ CACHE INTERNAL "")
+ endif()
+ return()
+ endif()
+
+ # HP-UX
+ check_c_source_compiles("
+ #include <sys/param.h>
+ #include <sys/pstat.h>
+ int main(void)
+ {
+ struct pst_static pst;
+ pstat_getstatic(&pst, sizeof(pst), 1, 0);
+ (void)pst.physical_memory;
+ (void)pst.page_size;
+ return 0;
+ }
+ "
+ TUKLIB_PHYSMEM_PSTAT_GETSTATIC)
+ if(TUKLIB_PHYSMEM_PSTAT_GETSTATIC)
+ set(TUKLIB_PHYSMEM_DEFINITIONS "TUKLIB_PHYSMEM_PSTAT_GETSTATIC"
+ CACHE INTERNAL "")
+ return()
+ endif()
+endfunction()
+
+function(tuklib_physmem TARGET_OR_ALL)
+ if(NOT DEFINED CACHE{TUKLIB_PHYSMEM_FOUND})
+ message(STATUS "Checking how to detect the amount of physical memory")
+ tuklib_physmem_internal_check()
+
+ if(DEFINED CACHE{TUKLIB_PHYSMEM_DEFINITIONS})
+ set(TUKLIB_PHYSMEM_FOUND 1 CACHE INTERNAL "")
+ else()
+ set(TUKLIB_PHYSMEM_FOUND 0 CACHE INTERNAL "")
+ message(WARNING
+ "No method to detect the amount of physical memory was found")
+ endif()
+ endif()
+
+ if(TUKLIB_PHYSMEM_FOUND)
+ tuklib_add_definitions("${TARGET_OR_ALL}"
+ "${TUKLIB_PHYSMEM_DEFINITIONS}")
+ endif()
+endfunction()
diff --git a/cmake/tuklib_progname.cmake b/cmake/tuklib_progname.cmake
new file mode 100644
index 00000000..0fa1d3d7
--- /dev/null
+++ b/cmake/tuklib_progname.cmake
@@ -0,0 +1,19 @@
+#
+# tuklib_progname.cmake - see tuklib_progname.m4 for description and comments
+#
+# Author: Lasse Collin
+#
+# This file has been put into the public domain.
+# You can do whatever you want with this file.
+#
+
+include("${CMAKE_CURRENT_LIST_DIR}/tuklib_common.cmake")
+include(CheckSymbolExists)
+
+function(tuklib_progname TARGET_OR_ALL)
+ # NOTE: This glibc extension requires _GNU_SOURCE.
+ check_symbol_exists(program_invocation_name errno.h
+ HAVE_DECL_PROGRAM_INVOCATION_NAME)
+ tuklib_add_definition_if("${TARGET_OR_ALL}"
+ HAVE_DECL_PROGRAM_INVOCATION_NAME)
+endfunction()