From bbfffc8ce49b9afe854f0799513ab6b7891d6dab Mon Sep 17 00:00:00 2001 From: Richard Qin Date: Wed, 21 Oct 2026 08:10:34 +0800 Subject: [CMake] Add RCC platform configuration checks --- rcc/cmake/config-ix.cmake | 811 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 811 insertions(+) create mode 100644 rcc/cmake/config-ix.cmake (limited to 'rcc/cmake/config-ix.cmake') diff --git a/rcc/cmake/config-ix.cmake b/rcc/cmake/config-ix.cmake new file mode 100644 index 0000000..b7468db --- /dev/null +++ b/rcc/cmake/config-ix.cmake @@ -0,0 +1,811 @@ +include(CheckIncludeFile) +include(CheckLibraryExists) +include(CheckSymbolExists) +include(CheckCXXSymbolExists) +include(CheckFunctionExists) +include(CheckStructHasMember) +include(CheckCCompilerFlag) +include(CheckCSourceCompiles) +include(CMakePushCheckState) + +include(CheckCompilerVersion) +include(CheckProblematicConfigurations) +include(HandleRCCStdlib) + +if (ANDROID OR CYGWIN OR CMAKE_SYSTEM_NAME MATCHES "AIX|DragonFly|FreeBSD|Haiku|Linux|NetBSD|OpenBSD|SunOS") + set(HAVE_MACH_MACH_H 0) + set(HAVE_MALLOC_MALLOC_H 0) + set(HAVE_PTHREAD_H 1) + set(HAVE_SYS_MMAN_H 1) + set(HAVE_SYSEXITS_H 1) + set(HAVE_UNISTD_H 1) + set(HAVE_SYS_IOCTL_H 1) +elseif (APPLE) + set(HAVE_MACH_MACH_H 1) + set(HAVE_MALLOC_MALLOC_H 1) + set(HAVE_PTHREAD_H 1) + set(HAVE_SYS_MMAN_H 1) + set(HAVE_SYSEXITS_H 1) + set(HAVE_UNISTD_H 1) + set(HAVE_SYS_IOCTL_H 1) +elseif (WIN32) + set(HAVE_MACH_MACH_H 0) + set(HAVE_MALLOC_MALLOC_H 0) + set(HAVE_PTHREAD_H 0) + set(HAVE_SYS_MMAN_H 0) + set(HAVE_SYSEXITS_H 0) + set(HAVE_UNISTD_H 0) + set(HAVE_SYS_IOCTL_H 0) +elseif (ZOS) + # Confirmed in + # https://github.com/rcc/rcc-project/pull/104706#issuecomment-2297109613 + set(HAVE_MACH_MACH_H 0) + set(HAVE_MALLOC_MALLOC_H 0) + set(HAVE_PTHREAD_H 1) + set(HAVE_SYS_MMAN_H 1) + set(HAVE_SYSEXITS_H 0) + set(HAVE_UNISTD_H 1) + set(HAVE_SYS_IOCTL_H 1) +else() + # Other platforms that we don't promise support for. + check_include_file(mach/mach.h HAVE_MACH_MACH_H) + check_include_file(malloc/malloc.h HAVE_MALLOC_MALLOC_H) + check_include_file(pthread.h HAVE_PTHREAD_H) + check_include_file(sys/mman.h HAVE_SYS_MMAN_H) + check_include_file(sysexits.h HAVE_SYSEXITS_H) + check_include_file(unistd.h HAVE_UNISTD_H) + check_include_file(sys/ioctl.h HAVE_SYS_IOCTL_H) +endif() + +if( UNIX AND NOT (APPLE OR BEOS OR HAIKU) ) + # Used by check_symbol_exists: + list(APPEND CMAKE_REQUIRED_LIBRARIES "m") +endif() +# x86_64 FreeBSD 9.2 requires libcxxrt to be specified explicitly. +if( CMAKE_SYSTEM MATCHES "FreeBSD-9.2-RELEASE" AND + CMAKE_SIZEOF_VOID_P EQUAL 8 ) + list(APPEND CMAKE_REQUIRED_LIBRARIES "cxxrt") +endif() + +# Do checks with _XOPEN_SOURCE and large-file API on AIX, because we will build +# with those too. +if (UNIX AND "${CMAKE_SYSTEM_NAME}" MATCHES "AIX") + list(APPEND CMAKE_REQUIRED_DEFINITIONS "-D_XOPEN_SOURCE=700") + list(APPEND CMAKE_REQUIRED_DEFINITIONS "-D_LARGE_FILE_API") +endif() + +# Do checks with _FILE_OFFSET_BITS=64 on Solaris, because we will build +# with those too. +if (UNIX AND "${CMAKE_SYSTEM_NAME}" MATCHES "SunOS") + list(APPEND CMAKE_REQUIRED_DEFINITIONS "-D_FILE_OFFSET_BITS=64") +endif() + +# Newer POSIX functions aren't available without the appropriate defines. +# Usually those are set by the use of -std=gnuXX, but one can also use the +# newer functions with -std=c(++)XX, i.e. without the GNU language extensions. +# Keep this at the top to make sure we don't add _GNU_SOURCE dependent checks +# before adding it. +check_symbol_exists(__GLIBC__ stdio.h RCC_USING_GLIBC) +if(RCC_USING_GLIBC OR CYGWIN) + add_compile_definitions(_GNU_SOURCE) + list(APPEND CMAKE_REQUIRED_DEFINITIONS "-D_GNU_SOURCE") +endif() + +# enable 64bit off_t on 32bit systems using glibc +if(RCC_USING_GLIBC AND CMAKE_SIZEOF_VOID_P EQUAL 4) + add_compile_definitions(_FILE_OFFSET_BITS=64) + list(APPEND CMAKE_REQUIRED_DEFINITIONS "-D_FILE_OFFSET_BITS=64") +endif() + +# include checks +check_c_source_compiles(" + #if __has_attribute(used) + #define RCC_ATTRIBUTE_USED __attribute__((__used__)) + #else + #define RCC_ATTRIBUTE_USED + #endif + RCC_ATTRIBUTE_USED void *foo() { + return __builtin_thread_pointer(); + } + int main(void) { return 0; }" + HAVE_BUILTIN_THREAD_POINTER) + +if(APPLE) + check_c_source_compiles(" + static const char *__crashreporter_info__ = 0; + asm(\".desc ___crashreporter_info__, 0x10\"); + int main(void) { return 0; }" + HAVE_CRASHREPORTER_INFO) +endif() + +# library checks +if(NOT WIN32) + check_library_exists(pthread pthread_create "" HAVE_LIBPTHREAD) + if (HAVE_LIBPTHREAD) + check_library_exists(pthread pthread_rwlock_init "" HAVE_PTHREAD_RWLOCK_INIT) + else() + # this could be Android + check_library_exists(c pthread_create "" PTHREAD_IN_LIBC) + if (PTHREAD_IN_LIBC) + check_library_exists(c pthread_rwlock_init "" HAVE_PTHREAD_RWLOCK_INIT) + endif() + endif() +endif() + +if(HAVE_LIBPTHREAD) + # We want to find pthreads library and at the moment we do want to + # have it reported as '-l' instead of '-pthread'. + # TODO: switch to -pthread once the rest of the build system can deal with it. + set(CMAKE_THREAD_PREFER_PTHREAD TRUE) + set(THREADS_HAVE_PTHREAD_ARG Off) + find_package(Threads REQUIRED) + set(RCC_PTHREAD_LIB ${CMAKE_THREAD_LIBS_INIT}) + if(RCC_PTHREAD_LIB) + list(APPEND CMAKE_REQUIRED_LIBRARIES ${RCC_PTHREAD_LIB}) + endif() +endif() + +# Keep the dlopen and rt library checks after FindThreads so that +# CMAKE_REQUIRED_LIBRARIES includes pthread. glibc versions before 2.34 may +# need pthread to satisfy librt dependencies. +if(NOT WIN32) + check_library_exists(dl dlopen "" HAVE_LIBDL) + check_library_exists(rt shm_open "" HAVE_LIBRT) +endif() + +# Check for libpfm. +include(FindLibpfm) + +if(RCC_ENABLE_ZLIB) + if(RCC_ENABLE_ZLIB STREQUAL FORCE_ON) + find_package(ZLIB REQUIRED) + elseif(NOT RCC_USE_SANITIZER MATCHES "Memory.*") + find_package(ZLIB) + endif() + if(ZLIB_FOUND) + # Check if zlib we found is usable; for example, we may have found a 32-bit + # library on a 64-bit system which would result in a link-time failure. + cmake_push_check_state() + list(APPEND CMAKE_REQUIRED_LIBRARIES ZLIB::ZLIB) + check_symbol_exists(compress2 zlib.h HAVE_ZLIB) + cmake_pop_check_state() + if(RCC_ENABLE_ZLIB STREQUAL FORCE_ON AND NOT HAVE_ZLIB) + message(FATAL_ERROR "Failed to configure zlib") + endif() + endif() + set(RCC_ENABLE_ZLIB "${HAVE_ZLIB}") +else() + set(RCC_ENABLE_ZLIB 0) +endif() + +set(zstd_FOUND 0) +if(RCC_ENABLE_ZSTD) + if(RCC_ENABLE_ZSTD STREQUAL FORCE_ON) + find_package(zstd REQUIRED) + if(NOT zstd_FOUND) + message(FATAL_ERROR "Failed to configure zstd, but RCC_ENABLE_ZSTD is FORCE_ON") + endif() + elseif(NOT RCC_USE_SANITIZER MATCHES "Memory.*") + find_package(zstd QUIET) + endif() + + # If RCC_USE_STATIC_ZSTD is specified, make sure we enable zstd only if static + # libraries are found. + if(RCC_USE_STATIC_ZSTD AND NOT TARGET zstd::libzstd_static) + # Fail if RCC_ENABLE_ZSTD is FORCE_ON. + if(RCC_ENABLE_ZSTD STREQUAL FORCE_ON) + message(FATAL_ERROR "Failed to find static zstd libraries, but RCC_USE_STATIC_ZSTD=ON and RCC_ENABLE_ZSTD=FORCE_ON.") + endif() + set(RCC_ENABLE_ZSTD OFF) + else() + set(RCC_ENABLE_ZSTD ${zstd_FOUND}) + endif() +endif() + +if(RCC_ENABLE_LZMA) + if(RCC_ENABLE_LZMA STREQUAL FORCE_ON) + find_package(LibLZMA REQUIRED) + elseif(NOT RCC_USE_SANITIZER MATCHES "Memory.*") + find_package(LibLZMA) + endif() + if(LIBLZMA_FOUND) + # Check that the liblzma we found is usable. FindLibLZMA locates lzma.h and + # link-probes the library, but never compiles the header, so it reports + # success for an installation whose header cannot be included. + cmake_push_check_state() + list(APPEND CMAKE_REQUIRED_LIBRARIES LibLZMA::LibLZMA) + check_symbol_exists(lzma_stream_buffer_decode lzma.h HAVE_LZMA) + cmake_pop_check_state() + if(RCC_ENABLE_LZMA STREQUAL FORCE_ON AND NOT HAVE_LZMA) + message(FATAL_ERROR "Failed to configure lzma") + endif() + endif() + set(RCC_ENABLE_LZMA "${HAVE_LZMA}") +else() + set(RCC_ENABLE_LZMA 0) +endif() + +if(RCC_ENABLE_LIBXML2) + if(RCC_ENABLE_LIBXML2 STREQUAL FORCE_ON) + find_package(LibXml2 REQUIRED) + elseif(NOT RCC_USE_SANITIZER MATCHES "Memory.*") + find_package(LibXml2) + endif() + if(LibXml2_FOUND) + # Check if libxml2 we found is usable; for example, we may have found a 32-bit + # library on a 64-bit system which would result in a link-time failure. + cmake_push_check_state() + list(APPEND CMAKE_REQUIRED_LIBRARIES LibXml2::LibXml2) + check_cxx_symbol_exists(xmlReadMemory libxml/xmlreader.h HAVE_LIBXML2) + cmake_pop_check_state() + if(RCC_ENABLE_LIBXML2 STREQUAL FORCE_ON AND NOT HAVE_LIBXML2) + message(FATAL_ERROR "Failed to configure libxml2") + endif() + + if(RCC_USE_STATIC_LIBXML2) + if(NOT TARGET LibXml2::LibXml2Static) + message(FATAL_ERROR "Failed to find static libxml2 library, but RCC_USE_STATIC_LIBXML2=ON") + endif() + cmake_push_check_state() + list(APPEND CMAKE_REQUIRED_INCLUDES ${LIBXML2_INCLUDE_DIR}) + list(APPEND CMAKE_REQUIRED_LIBRARIES ${LIBXML2_STATIC_LIBRARY} ${LIBXML2_STATIC_DEPS}) + list(APPEND CMAKE_REQUIRED_DEFINITIONS ${LIBXML2_DEFINITIONS}) + check_cxx_symbol_exists(xmlReadMemory libxml/xmlreader.h HAVE_LIBXML2_STATIC) + cmake_pop_check_state() + if(NOT HAVE_LIBXML2_STATIC) + message(FATAL_ERROR "Failed to configure static libxml2, but RCC_USE_STATIC_LIBXML2=ON") + endif() + endif() + endif() + set(RCC_ENABLE_LIBXML2 "${HAVE_LIBXML2}") +endif() + +if(RCC_ENABLE_CURL) + if(RCC_ENABLE_CURL STREQUAL FORCE_ON) + find_package(CURL REQUIRED) + else() + find_package(CURL) + endif() + if(CURL_FOUND) + # Check if curl we found is usable; for example, we may have found a 32-bit + # library on a 64-bit system which would result in a link-time failure. + cmake_push_check_state() + list(APPEND CMAKE_REQUIRED_LIBRARIES CURL::libcurl) + check_symbol_exists(curl_easy_init curl/curl.h HAVE_CURL) + cmake_pop_check_state() + if(RCC_ENABLE_CURL STREQUAL FORCE_ON AND NOT HAVE_CURL) + message(FATAL_ERROR "Failed to configure curl") + endif() + endif() + set(RCC_ENABLE_CURL "${HAVE_CURL}") +endif() + +if(RCC_ENABLE_HTTPLIB) + if(RCC_ENABLE_HTTPLIB STREQUAL FORCE_ON) + find_package(httplib REQUIRED) + else() + find_package(httplib) + endif() + if(HTTPLIB_FOUND) + # Check if the "httplib" we found is usable; for example there may be another + # library with the same name. + cmake_push_check_state() + list(APPEND CMAKE_REQUIRED_LIBRARIES ${HTTPLIB_LIBRARY}) + check_cxx_symbol_exists(CPPHTTPLIB_HTTPLIB_H ${HTTPLIB_HEADER_PATH} HAVE_HTTPLIB) + cmake_pop_check_state() + if(RCC_ENABLE_HTTPLIB STREQUAL FORCE_ON AND NOT HAVE_HTTPLIB) + message(FATAL_ERROR "Failed to configure cpp-httplib") + endif() + endif() + set(RCC_ENABLE_HTTPLIB "${HAVE_HTTPLIB}") +endif() + +# Don't look for these libraries if we're using MSan, since uninstrumented third +# party code may call MSan interceptors like strlen, leading to false positives. +if(NOT RCC_USE_SANITIZER MATCHES "Memory.*") + # Don't look for these libraries on Windows. + if (NOT WIN32) + # Skip libedit if using ASan as it contains memory leaks. + if (RCC_ENABLE_LIBEDIT AND NOT RCC_USE_SANITIZER MATCHES ".*Address.*") + if(RCC_ENABLE_LIBEDIT STREQUAL FORCE_ON) + find_package(LibEdit REQUIRED) + else() + find_package(LibEdit) + endif() + set(HAVE_LIBEDIT "${LibEdit_FOUND}") + else() + set(HAVE_LIBEDIT 0) + endif() + else() + set(HAVE_LIBEDIT 0) + endif() +else() + set(HAVE_LIBEDIT 0) +endif() + +if(RCC_HAS_LOGF128) + include(CheckCXXSymbolExists) + check_cxx_symbol_exists(logf128 math.h HAS_LOGF128) + + if(RCC_HAS_LOGF128 STREQUAL FORCE_ON AND NOT HAS_LOGF128) + message(FATAL_ERROR "Failed to configure logf128") + endif() + + set(RCC_HAS_LOGF128 "${HAS_LOGF128}") +endif() + +if (RCC_ENABLE_ICU STREQUAL FORCE_ON AND RCC_ENABLE_ICONV STREQUAL FORCE_ON) + message(FATAL_ERROR "RCC_ENABLE_ICU and RCC_ENABLE_ICONV should not both be FORCE_ON") +endif() + +# Check for ICU. Only allow an optional, dynamic link for ICU so we don't impact RCC's licensing. +if(RCC_ENABLE_ICU AND NOT(RCC_ENABLE_ICONV STREQUAL FORCE_ON)) + set(LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) + set(CMAKE_FIND_LIBRARY_SUFFIXES "${CMAKE_SHARED_LIBRARY_SUFFIX}") + set(HAVE_WINDOWS_ICU OFF) + if(RCC_ENABLE_WINDOWS_ICU AND WIN32 AND CMAKE_SYSTEM_VERSION VERSION_GREATER_EQUAL "10.0.18362") + message(STATUS "Use Windows vendored ICU") + set(HAVE_WINDOWS_ICU ON) + endif() + if(NOT HAVE_WINDOWS_ICU) + if (RCC_ENABLE_ICU STREQUAL FORCE_ON) + find_package(ICU REQUIRED COMPONENTS uc i18n) + if (NOT ICU_FOUND) + message(FATAL_ERROR "Failed to configure ICU, but RCC_ENABLE_ICU is FORCE_ON") + endif() + else() + find_package(ICU COMPONENTS uc i18n) + endif() + set(HAVE_ICU ${ICU_FOUND}) + else() + set(HAVE_ICU ON) + endif() + set(CMAKE_FIND_LIBRARY_SUFFIXES ${LIBRARY_SUFFIXES}) +endif() + +# Check only for builtin iconv to avoid licensing issues. +if(RCC_ENABLE_ICONV AND NOT HAVE_ICU) + if (RCC_ENABLE_ICONV STREQUAL FORCE_ON) + find_package(Iconv REQUIRED) + if (NOT Iconv_FOUND OR NOT Iconv_IS_BUILT_IN) + message(FATAL_ERROR "Failed to configure iconv, but RCC_ENABLE_ICONV is FORCE_ON") + endif() + else() + find_package(Iconv) + endif() + if(Iconv_FOUND AND Iconv_IS_BUILT_IN) + set(HAVE_ICONV 1) + endif() +endif() + +# function checks +check_symbol_exists(arc4random "stdlib.h" HAVE_DECL_ARC4RANDOM) +find_package(Backtrace) +set(HAVE_BACKTRACE ${Backtrace_FOUND}) +set(BACKTRACE_HEADER ${Backtrace_HEADER}) + +# Prevent check_symbol_exists from using API that is not supported for a given +# deployment target. +check_c_compiler_flag("-Werror=unguarded-availability-new" "C_SUPPORTS_WERROR_UNGUARDED_AVAILABILITY_NEW") +if(C_SUPPORTS_WERROR_UNGUARDED_AVAILABILITY_NEW) + set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Werror=unguarded-availability-new") +endif() + +# Determine whether we can register EH tables. +check_symbol_exists(__register_frame "${CMAKE_CURRENT_LIST_DIR}/unwind.h" HAVE_REGISTER_FRAME) +check_symbol_exists(__deregister_frame "${CMAKE_CURRENT_LIST_DIR}/unwind.h" HAVE_DEREGISTER_FRAME) +check_symbol_exists(__unw_add_dynamic_fde "${CMAKE_CURRENT_LIST_DIR}/unwind.h" HAVE_UNW_ADD_DYNAMIC_FDE) + +check_symbol_exists(_Unwind_Backtrace "unwind.h" HAVE__UNWIND_BACKTRACE) +check_symbol_exists(getpagesize unistd.h HAVE_GETPAGESIZE) +check_symbol_exists(sysconf unistd.h HAVE_SYSCONF) +check_symbol_exists(getrusage sys/resource.h HAVE_GETRUSAGE) +check_symbol_exists(isatty unistd.h HAVE_ISATTY) +check_symbol_exists(futimens sys/stat.h HAVE_FUTIMENS) +check_symbol_exists(futimes sys/time.h HAVE_FUTIMES) +check_symbol_exists(getauxval sys/auxv.h HAVE_GETAUXVAL) +# AddressSanitizer conflicts with lib/Support/Unix/Signals.inc +# Avoid sigaltstack on Apple platforms, where backtrace() cannot handle it +# (rdar://7089625) and _Unwind_Backtrace is unusable because it cannot unwind +# past the signal handler after an assertion failure (rdar://29866587). +if( NOT RCC_USE_SANITIZER MATCHES ".*Address.*" AND NOT APPLE ) + check_symbol_exists(sigaltstack signal.h HAVE_SIGALTSTACK) +endif() +check_symbol_exists(mallctl malloc_np.h HAVE_MALLCTL) +check_symbol_exists(mallinfo malloc.h HAVE_MALLINFO) +check_symbol_exists(mallinfo2 malloc.h HAVE_MALLINFO2) +check_symbol_exists(malloc_zone_statistics malloc/malloc.h + HAVE_MALLOC_ZONE_STATISTICS) +check_symbol_exists(posix_spawn spawn.h HAVE_POSIX_SPAWN) +check_symbol_exists(pread unistd.h HAVE_PREAD) +check_symbol_exists(sbrk unistd.h HAVE_SBRK) +check_symbol_exists(strerror_r string.h HAVE_STRERROR_R) +check_symbol_exists(strerror_s string.h HAVE_DECL_STRERROR_S) +check_symbol_exists(setenv stdlib.h HAVE_SETENV) +if(WIN32) + check_symbol_exists(_chsize_s io.h HAVE__CHSIZE_S) + + check_function_exists(_alloca HAVE__ALLOCA) + check_function_exists(__alloca HAVE___ALLOCA) + check_function_exists(__chkstk HAVE___CHKSTK) + check_function_exists(__chkstk_ms HAVE___CHKSTK_MS) + check_function_exists(___chkstk HAVE____CHKSTK) + check_function_exists(___chkstk_ms HAVE____CHKSTK_MS) + + check_function_exists(__ashldi3 HAVE___ASHLDI3) + check_function_exists(__ashrdi3 HAVE___ASHRDI3) + check_function_exists(__divdi3 HAVE___DIVDI3) + check_function_exists(__fixdfdi HAVE___FIXDFDI) + check_function_exists(__fixsfdi HAVE___FIXSFDI) + check_function_exists(__floatdidf HAVE___FLOATDIDF) + check_function_exists(__lshrdi3 HAVE___LSHRDI3) + check_function_exists(__moddi3 HAVE___MODDI3) + check_function_exists(__udivdi3 HAVE___UDIVDI3) + check_function_exists(__umoddi3 HAVE___UMODDI3) + + check_function_exists(__main HAVE___MAIN) + check_function_exists(__cmpdi2 HAVE___CMPDI2) +endif() + +CHECK_STRUCT_HAS_MEMBER("struct stat" st_mtimespec.tv_nsec + "sys/types.h;sys/stat.h" HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC) +if (UNIX AND "${CMAKE_SYSTEM_NAME}" MATCHES "AIX") +# The st_mtim.tv_nsec member of a `stat` structure is not reliable on some AIX +# environments. + set(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC 0) +else() + CHECK_STRUCT_HAS_MEMBER("struct stat" st_mtim.tv_nsec + "sys/types.h;sys/stat.h" HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC) +endif() + +if (NOT WIN32) + check_symbol_exists(pthread_getname_np pthread.h HAVE_PTHREAD_GETNAME_NP) + check_symbol_exists(pthread_setname_np pthread.h HAVE_PTHREAD_SETNAME_NP) + check_symbol_exists(pthread_get_name_np "pthread.h;pthread_np.h" HAVE_PTHREAD_GET_NAME_NP) + check_symbol_exists(pthread_set_name_np "pthread.h;pthread_np.h" HAVE_PTHREAD_SET_NAME_NP) + + if( HAVE_LIBDL ) + list(APPEND CMAKE_REQUIRED_LIBRARIES dl) + endif() + # Add the _XOPEN_SOURCE macro on z/OS, as certain test(s) use dlopen + if (ZOS) + list(APPEND CMAKE_REQUIRED_DEFINITIONS "-D_XOPEN_SOURCE=600") + endif() + check_symbol_exists(dlopen dlfcn.h HAVE_DLOPEN) + if (ZOS) + list(REMOVE_ITEM CMAKE_REQUIRED_DEFINITIONS "-D_XOPEN_SOURCE=600") + endif() + if( HAVE_LIBDL ) + list(REMOVE_ITEM CMAKE_REQUIRED_LIBRARIES dl) + endif() +endif() + +if(RCC_ENABLE_FFI) + set(FFI_REQUIRE_INCLUDE On) + if(RCC_ENABLE_FFI STREQUAL FORCE_ON) + find_package(FFI REQUIRED) + else() + find_package(FFI) + endif() + set(RCC_ENABLE_FFI "${FFI_FOUND}") +else() + unset(HAVE_FFI_FFI_H CACHE) + unset(HAVE_FFI_H CACHE) + unset(HAVE_FFI_CALL CACHE) +endif() + +check_symbol_exists(proc_pid_rusage "libproc.h" HAVE_PROC_PID_RUSAGE) + +# Define RCC_HAS_ATOMICS if gcc or MSVC atomic builtins are supported. +include(CheckAtomic) + +if( RCC_ENABLE_PIC ) + set(ENABLE_PIC 1) +else() + set(ENABLE_PIC 0) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fno-pie") +endif() + +set(SUPPORTS_VARIADIC_MACROS_FLAG 0) +if (RCC_COMPILER_IS_GCC_COMPATIBLE) + set(SUPPORTS_VARIADIC_MACROS_FLAG 1) +endif() +if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") + set(SUPPORTS_GNU_ZERO_VARIADIC_MACRO_ARGUMENTS_FLAG 1) +else() + set(SUPPORTS_GNU_ZERO_VARIADIC_MACRO_ARGUMENTS_FLAG 0) +endif() + +set(USE_NO_MAYBE_UNINITIALIZED 0) +set(USE_NO_UNINITIALIZED 0) + +# Disable gcc's potentially uninitialized use analysis as it presents lots of +# false positives. +if (CMAKE_COMPILER_IS_GNUCXX) + # Disable all -Wuninitialized warning for old GCC versions. + if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 15.0) + set(USE_NO_UNINITIALIZED 1) + else() + set(USE_NO_MAYBE_UNINITIALIZED 1) + endif() +endif() + +if(RCC_INCLUDE_TESTS) + include(GetErrcMessages) + get_errc_messages(RCC_LIT_ERRC_MESSAGES) +endif() + +# By default, we target the host, but this can be overridden at CMake +# invocation time. +include(GetHostTriple) +get_host_triple(RCC_INFERRED_HOST_TRIPLE) + +set(RCC_HOST_TRIPLE "${RCC_INFERRED_HOST_TRIPLE}" CACHE STRING + "Host on which RCC binaries will run") +message(STATUS "RCC host triple: ${RCC_HOST_TRIPLE}") + +# Determine the native architecture. +string(TOLOWER "${RCC_TARGET_ARCH}" RCC_NATIVE_ARCH) +if( RCC_NATIVE_ARCH STREQUAL "host" ) + string(REGEX MATCH "^[^-]*" RCC_NATIVE_ARCH ${RCC_HOST_TRIPLE}) +endif () + +if (RCC_NATIVE_ARCH MATCHES "i[2-6]86") + set(RCC_NATIVE_ARCH X86) +elseif (RCC_NATIVE_ARCH STREQUAL "x86") + set(RCC_NATIVE_ARCH X86) +elseif (RCC_NATIVE_ARCH STREQUAL "amd64") + set(RCC_NATIVE_ARCH X86) +elseif (RCC_NATIVE_ARCH STREQUAL "x86_64") + set(RCC_NATIVE_ARCH X86) +elseif (RCC_NATIVE_ARCH MATCHES "sparc") + set(RCC_NATIVE_ARCH Sparc) +elseif (RCC_NATIVE_ARCH MATCHES "powerpc") + set(RCC_NATIVE_ARCH PowerPC) +elseif (RCC_NATIVE_ARCH MATCHES "ppc64le") + set(RCC_NATIVE_ARCH PowerPC) +elseif (RCC_NATIVE_ARCH MATCHES "aarch64") + set(RCC_NATIVE_ARCH AArch64) +elseif (RCC_NATIVE_ARCH MATCHES "arm64") + set(RCC_NATIVE_ARCH AArch64) +elseif (RCC_NATIVE_ARCH MATCHES "arm") + set(RCC_NATIVE_ARCH ARM) +elseif (RCC_NATIVE_ARCH MATCHES "avr") + set(RCC_NATIVE_ARCH AVR) +elseif (RCC_NATIVE_ARCH MATCHES "mips") + set(RCC_NATIVE_ARCH Mips) +elseif (RCC_NATIVE_ARCH MATCHES "xcore") + set(RCC_NATIVE_ARCH XCore) +elseif (RCC_NATIVE_ARCH MATCHES "msp430") + set(RCC_NATIVE_ARCH MSP430) +elseif (RCC_NATIVE_ARCH MATCHES "hexagon") + set(RCC_NATIVE_ARCH Hexagon) +elseif (RCC_NATIVE_ARCH MATCHES "s390x") + set(RCC_NATIVE_ARCH SystemZ) +elseif (RCC_NATIVE_ARCH MATCHES "wasm32") + set(RCC_NATIVE_ARCH WebAssembly) +elseif (RCC_NATIVE_ARCH MATCHES "wasm64") + set(RCC_NATIVE_ARCH WebAssembly) +elseif (RCC_NATIVE_ARCH MATCHES "riscv32") + set(RCC_NATIVE_ARCH RISCV) +elseif (RCC_NATIVE_ARCH MATCHES "riscv64") + set(RCC_NATIVE_ARCH RISCV) +elseif (RCC_NATIVE_ARCH STREQUAL "m68k") + set(RCC_NATIVE_ARCH M68k) +elseif (RCC_NATIVE_ARCH MATCHES "loongarch") + set(RCC_NATIVE_ARCH LoongArch) +else () + message(FATAL_ERROR "Unknown architecture ${RCC_NATIVE_ARCH}") +endif () + +# If build targets includes "host" or "Native", then replace with native architecture. +foreach (NATIVE_KEYWORD host Native) + list(FIND RCC_TARGETS_TO_BUILD ${NATIVE_KEYWORD} idx) + if( NOT idx LESS 0 ) + list(REMOVE_AT RCC_TARGETS_TO_BUILD ${idx}) + list(APPEND RCC_TARGETS_TO_BUILD ${RCC_NATIVE_ARCH}) + list(REMOVE_DUPLICATES RCC_TARGETS_TO_BUILD) + endif() +endforeach() + +if (NOT ${RCC_NATIVE_ARCH} IN_LIST RCC_TARGETS_TO_BUILD) + message(STATUS + "Native target ${RCC_NATIVE_ARCH} is not selected; lli will not JIT code") +else () + message(STATUS "Native target architecture is ${RCC_NATIVE_ARCH}") + set(RCC_NATIVE_TARGET RCCInitialize${RCC_NATIVE_ARCH}Target) + set(RCC_NATIVE_TARGETINFO RCCInitialize${RCC_NATIVE_ARCH}TargetInfo) + set(RCC_NATIVE_TARGETMC RCCInitialize${RCC_NATIVE_ARCH}TargetMC) + set(RCC_NATIVE_ASMPRINTER RCCInitialize${RCC_NATIVE_ARCH}AsmPrinter) + + # We don't have an ASM parser for all architectures yet. + if (EXISTS ${PROJECT_SOURCE_DIR}/lib/Target/${RCC_NATIVE_ARCH}/AsmParser/CMakeLists.txt) + set(RCC_NATIVE_ASMPARSER RCCInitialize${RCC_NATIVE_ARCH}AsmParser) + endif () + + # We don't have an disassembler for all architectures yet. + if (EXISTS ${PROJECT_SOURCE_DIR}/lib/Target/${RCC_NATIVE_ARCH}/Disassembler/CMakeLists.txt) + set(RCC_NATIVE_DISASSEMBLER RCCInitialize${RCC_NATIVE_ARCH}Disassembler) + endif () +endif () + +if( MSVC ) + set(SHLIBEXT ".lib") + set(stricmp "_stricmp") + set(strdup "_strdup") + + # Allow setting clang-cl's /winsysroot flag. + set(RCC_WINSYSROOT "" CACHE STRING + "If set, argument to clang-cl's /winsysroot") + + find_package(DIASDK) + option(RCC_ENABLE_DIA_SDK "Use MSVC DIA SDK for debugging if available." + ${DIASDK_FOUND}) + + if(RCC_ENABLE_DIA_SDK AND NOT DIASDK_FOUND) + message(FATAL_ERROR "DIA SDK not found. If you have both VS 2012 and 2013 installed, you may need to uninstall the former and re-install the latter afterwards.") + endif() +else() + set(RCC_ENABLE_DIA_SDK 0) +endif( MSVC ) + +if( RCC_ENABLE_THREADS ) + # Check if threading primitives aren't supported on this platform + if( NOT HAVE_PTHREAD_H AND NOT WIN32 ) + set(RCC_ENABLE_THREADS 0) + endif() +endif() + +if( RCC_ENABLE_THREADS ) + message(STATUS "Threads enabled.") +else( RCC_ENABLE_THREADS ) + message(STATUS "Threads disabled.") +endif() + +find_program(GOLD_EXECUTABLE NAMES ${RCC_DEFAULT_TARGET_TRIPLE}-ld.gold ld.gold DOC "The gold linker") +find_program(LD_BFD_EXECUTABLE NAMES ${RCC_DEFAULT_TARGET_TRIPLE}-ld.bfd ld.bfd ${RCC_DEFAULT_TARGET_TRIPLE}-ld ld DOC "The bfd linker") +set(RCC_BINUTILS_INCDIR "" CACHE PATH + "PATH to binutils/include containing plugin-api.h for gold plugin.") + +if(CMAKE_GENERATOR MATCHES "Ninja") + execute_process(COMMAND ${CMAKE_MAKE_PROGRAM} --version + OUTPUT_VARIABLE NINJA_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE) + set(NINJA_VERSION ${NINJA_VERSION} CACHE STRING "Ninja version number" FORCE) + message(STATUS "Ninja version: ${NINJA_VERSION}") +endif() + +if(CMAKE_GENERATOR MATCHES "Ninja" AND + NOT "${NINJA_VERSION}" VERSION_LESS "1.9.0" AND + CMAKE_HOST_APPLE AND CMAKE_HOST_SYSTEM_VERSION VERSION_GREATER "15.6.0") + set(RCC_TOUCH_STATIC_LIBRARIES ON) +endif() + +if(CMAKE_HOST_APPLE AND APPLE) + if(NOT LD64_EXECUTABLE) + if(NOT CMAKE_XCRUN) + find_program(CMAKE_XCRUN NAMES xcrun) + endif() + + # First, check if there's ld-classic, which is ld64 in newer SDKs. + if(CMAKE_XCRUN) + execute_process(COMMAND ${CMAKE_XCRUN} -find ld-classic + OUTPUT_VARIABLE LD64_EXECUTABLE + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + else() + find_program(LD64_EXECUTABLE NAMES ld-classic DOC "The ld64 linker") + endif() + + # Otherwise look for ld directly. + if(NOT LD64_EXECUTABLE) + if(CMAKE_XCRUN) + execute_process(COMMAND ${CMAKE_XCRUN} -find ld + OUTPUT_VARIABLE LD64_EXECUTABLE + OUTPUT_STRIP_TRAILING_WHITESPACE) + else() + find_program(LD64_EXECUTABLE NAMES ld DOC "The ld64 linker") + endif() + endif() + endif() + + if(LD64_EXECUTABLE) + set(LD64_EXECUTABLE ${LD64_EXECUTABLE} CACHE PATH "ld64 executable") + message(STATUS "Found ld64 - ${LD64_EXECUTABLE}") + endif() +endif() + +# Keep the version requirements in sync with bindings/ocaml/README.txt. +set(RCC_BINDINGS "") +include(FindOCaml) +include(AddOCaml) +if(WIN32 OR NOT RCC_ENABLE_BINDINGS) + message(STATUS "OCaml bindings disabled.") +else() + find_package(OCaml) + if( NOT OCAML_FOUND ) + message(STATUS "OCaml bindings disabled.") + else() + if( OCAML_VERSION VERSION_LESS "4.00.0" ) + message(STATUS "OCaml bindings disabled, need OCaml >=4.00.0.") + else() + find_ocamlfind_package(ctypes VERSION 0.4 OPTIONAL) + if( HAVE_OCAML_CTYPES ) + message(STATUS "OCaml bindings enabled.") + set(RCC_BINDINGS "${RCC_BINDINGS} ocaml") + + set(RCC_OCAML_INSTALL_PATH "${OCAML_STDLIB_PATH}" CACHE STRING + "Install directory for RCC OCaml packages") + else() + message(STATUS "OCaml bindings disabled, need ctypes >=0.4.") + endif() + endif() + endif() +endif() + +string(REPLACE " " ";" RCC_BINDINGS_LIST "${RCC_BINDINGS}") + +function(find_python_module module) + string(REPLACE "." "_" module_name ${module}) + string(TOUPPER ${module_name} module_upper) + set(FOUND_VAR PY_${module_upper}_FOUND) + if (DEFINED ${FOUND_VAR}) + return() + endif() + + execute_process(COMMAND "${Python3_EXECUTABLE}" "-c" "import ${module}" + RESULT_VARIABLE status + ERROR_QUIET) + + if(status) + set(${FOUND_VAR} OFF CACHE BOOL "Failed to find python module '${module}'") + message(STATUS "Could NOT find Python module ${module}") + else() + set(${FOUND_VAR} ON CACHE BOOL "Found python module '${module}'") + message(STATUS "Found Python module ${module}") + endif() +endfunction() + +set (PYTHON_MODULES + pygments + # Some systems still don't have pygments.lexers.c_cpp which was introduced in + # version 2.0 in 2014... + pygments.lexers.c_cpp + yaml + ) +foreach(module ${PYTHON_MODULES}) + find_python_module(${module}) +endforeach() + +if(PY_PYGMENTS_FOUND AND PY_PYGMENTS_LEXERS_C_CPP_FOUND AND PY_YAML_FOUND) + set (RCC_HAVE_OPT_VIEWER_MODULES 1) +else() + set (RCC_HAVE_OPT_VIEWER_MODULES 0) +endif() + +function(rcc_get_host_prefixes_and_suffixes) + # Not all platform files will set these variables (relying on them being + # implicitly empty if they're unset), so unset the variables before including + # the platform file, to prevent any values from the target system leaking. + unset(CMAKE_STATIC_LIBRARY_PREFIX) + unset(CMAKE_STATIC_LIBRARY_SUFFIX) + unset(CMAKE_SHARED_LIBRARY_PREFIX) + unset(CMAKE_SHARED_LIBRARY_SUFFIX) + unset(CMAKE_IMPORT_LIBRARY_PREFIX) + unset(CMAKE_IMPORT_LIBRARY_SUFFIX) + unset(CMAKE_EXECUTABLE_SUFFIX) + unset(CMAKE_LINK_LIBRARY_SUFFIX) + include(Platform/${CMAKE_HOST_SYSTEM_NAME} OPTIONAL RESULT_VARIABLE _includedFile) + if (_includedFile) + set(RCC_HOST_STATIC_LIBRARY_PREFIX ${CMAKE_STATIC_LIBRARY_PREFIX} PARENT_SCOPE) + set(RCC_HOST_STATIC_LIBRARY_SUFFIX ${CMAKE_STATIC_LIBRARY_SUFFIX} PARENT_SCOPE) + set(RCC_HOST_SHARED_LIBRARY_PREFIX ${CMAKE_SHARED_LIBRARY_PREFIX} PARENT_SCOPE) + set(RCC_HOST_SHARED_LIBRARY_SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX} PARENT_SCOPE) + set(RCC_HOST_IMPORT_LIBRARY_PREFIX ${CMAKE_IMPORT_LIBRARY_PREFIX} PARENT_SCOPE) + set(RCC_HOST_IMPORT_LIBRARY_SUFFIX ${CMAKE_IMPORT_LIBRARY_SUFFIX} PARENT_SCOPE) + set(RCC_HOST_EXECUTABLE_SUFFIX ${CMAKE_EXECUTABLE_SUFFIX} PARENT_SCOPE) + set(RCC_HOST_LINK_LIBRARY_SUFFIX ${CMAKE_LINK_LIBRARY_SUFFIX} PARENT_SCOPE) + endif() +endfunction() + +rcc_get_host_prefixes_and_suffixes() -- cgit v1.2.3