1# The CompilerRT build system requires CMake version 2.8.8 or higher in order 2# to use its support for building convenience "libraries" as a collection of 3# .o files. This is particularly useful in producing larger, more complex 4# runtime libraries. 5 6include(BuiltinTests) 7include(CheckIncludeFile) 8include(CheckCXXSourceCompiles) 9include(GNUInstallDirs) 10include(ExtendPath) 11include(CompilerRTDarwinUtils) 12 13check_include_file(unwind.h HAVE_UNWIND_H) 14 15# Used by sanitizer_common and tests. 16check_include_file(rpc/xdr.h HAVE_RPC_XDR_H) 17if (NOT HAVE_RPC_XDR_H) 18 set(HAVE_RPC_XDR_H 0) 19endif() 20 21# Top level target used to build all compiler-rt libraries. 22add_custom_target(compiler-rt ALL) 23add_custom_target(install-compiler-rt) 24add_custom_target(install-compiler-rt-stripped) 25set_property( 26 TARGET 27 compiler-rt 28 install-compiler-rt 29 install-compiler-rt-stripped 30 PROPERTY 31 FOLDER "Compiler-RT Misc" 32) 33 34# Setting these variables from an LLVM build is sufficient that compiler-rt can 35# construct the output paths, so it can behave as if it were in-tree here. 36if (LLVM_LIBRARY_OUTPUT_INTDIR AND LLVM_RUNTIME_OUTPUT_INTDIR AND PACKAGE_VERSION) 37 set(LLVM_TREE_AVAILABLE On) 38endif() 39 40if (LLVM_TREE_AVAILABLE) 41 # Compute the Clang version from the LLVM version. 42 # FIXME: We should be able to reuse CLANG_VERSION_MAJOR variable calculated 43 # in Clang cmake files, instead of copying the rules here. 44 string(REGEX MATCH "^[0-9]+" CLANG_VERSION_MAJOR 45 ${PACKAGE_VERSION}) 46 # Setup the paths where compiler-rt runtimes and headers should be stored. 47 set(COMPILER_RT_OUTPUT_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/clang/${CLANG_VERSION_MAJOR}) 48 set(COMPILER_RT_EXEC_OUTPUT_DIR ${LLVM_RUNTIME_OUTPUT_INTDIR}) 49 set(COMPILER_RT_INSTALL_PATH lib${LLVM_LIBDIR_SUFFIX}/clang/${CLANG_VERSION_MAJOR}) 50 option(COMPILER_RT_INCLUDE_TESTS "Generate and build compiler-rt unit tests." 51 ${LLVM_INCLUDE_TESTS}) 52 option(COMPILER_RT_ENABLE_WERROR "Fail and stop if warning is triggered" 53 ${LLVM_ENABLE_WERROR}) 54 55 # Use just-built Clang to compile/link tests on all platforms. 56 if (CMAKE_CROSSCOMPILING) 57 if (CMAKE_HOST_WIN32) 58 set(_host_executable_suffix ".exe") 59 else() 60 set(_host_executable_suffix "") 61 endif() 62 else() 63 set(_host_executable_suffix ${CMAKE_EXECUTABLE_SUFFIX}) 64 endif() 65 set(COMPILER_RT_TEST_COMPILER 66 ${LLVM_RUNTIME_OUTPUT_INTDIR}/clang${_host_executable_suffix}) 67 set(COMPILER_RT_TEST_CXX_COMPILER 68 ${LLVM_RUNTIME_OUTPUT_INTDIR}/clang++${_host_executable_suffix}) 69else() 70 # Take output dir and install path from the user. 71 set(COMPILER_RT_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR} CACHE PATH 72 "Path where built compiler-rt libraries should be stored.") 73 set(COMPILER_RT_EXEC_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/bin CACHE PATH 74 "Path where built compiler-rt executables should be stored.") 75 set(COMPILER_RT_INSTALL_PATH "" CACHE PATH 76 "Prefix for directories where built compiler-rt artifacts should be installed.") 77 option(COMPILER_RT_INCLUDE_TESTS "Generate and build compiler-rt unit tests." OFF) 78 option(COMPILER_RT_ENABLE_WERROR "Fail and stop if warning is triggered" OFF) 79 # Use a host compiler to compile/link tests. 80 set(COMPILER_RT_TEST_COMPILER ${CMAKE_C_COMPILER} CACHE PATH "Compiler to use for testing") 81 set(COMPILER_RT_TEST_CXX_COMPILER ${CMAKE_CXX_COMPILER} CACHE PATH "C++ Compiler to use for testing") 82endif() 83 84if("${COMPILER_RT_TEST_COMPILER}" MATCHES "clang[+]*$") 85 set(COMPILER_RT_TEST_COMPILER_ID Clang) 86elseif("${COMPILER_RT_TEST_COMPILER}" MATCHES "clang.*.exe$") 87 set(COMPILER_RT_TEST_COMPILER_ID Clang) 88else() 89 set(COMPILER_RT_TEST_COMPILER_ID GNU) 90endif() 91 92if(NOT DEFINED COMPILER_RT_OS_DIR) 93 if(ANDROID) 94 # The CMAKE_SYSTEM_NAME for Android is Android, but the OS is Linux and the 95 # driver will search for compiler-rt libraries in the "linux" directory. 96 set(COMPILER_RT_OS_DIR linux) 97 else() 98 string(TOLOWER ${CMAKE_SYSTEM_NAME} COMPILER_RT_OS_DIR) 99 endif() 100endif() 101if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE) 102 set(COMPILER_RT_OUTPUT_LIBRARY_DIR 103 ${COMPILER_RT_OUTPUT_DIR}/lib) 104 extend_path(default_install_path "${COMPILER_RT_INSTALL_PATH}" lib) 105 set(COMPILER_RT_INSTALL_LIBRARY_DIR "${default_install_path}" CACHE PATH 106 "Path where built compiler-rt libraries should be installed.") 107else(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE) 108 set(COMPILER_RT_OUTPUT_LIBRARY_DIR 109 ${COMPILER_RT_OUTPUT_DIR}/lib/${COMPILER_RT_OS_DIR}) 110 extend_path(default_install_path "${COMPILER_RT_INSTALL_PATH}" "lib/${COMPILER_RT_OS_DIR}") 111 set(COMPILER_RT_INSTALL_LIBRARY_DIR "${default_install_path}" CACHE PATH 112 "Path where built compiler-rt libraries should be installed.") 113endif() 114extend_path(default_install_path "${COMPILER_RT_INSTALL_PATH}" "${CMAKE_INSTALL_BINDIR}") 115set(COMPILER_RT_INSTALL_BINARY_DIR "${default_install_path}" CACHE PATH 116 "Path where built compiler-rt executables should be installed.") 117extend_path(default_install_path "${COMPILER_RT_INSTALL_PATH}" "${CMAKE_INSTALL_INCLUDEDIR}") 118set(COMPILER_RT_INSTALL_INCLUDE_DIR "${default_install_path}" CACHE PATH 119 "Path where compiler-rt headers should be installed.") 120extend_path(default_install_path "${COMPILER_RT_INSTALL_PATH}" "${CMAKE_INSTALL_DATADIR}") 121set(COMPILER_RT_INSTALL_DATA_DIR "${default_install_path}" CACHE PATH 122 "Path where compiler-rt data files should be installed.") 123 124if(APPLE) 125 # On Darwin if /usr/include/c++ doesn't exist, the user probably has Xcode but 126 # not the command line tools (or is using macOS 10.14 or newer). If this is 127 # the case, we need to find the OS X sysroot to pass to clang. 128 if(NOT EXISTS /usr/include/c++) 129 execute_process(COMMAND xcrun -sdk macosx --show-sdk-path 130 OUTPUT_VARIABLE OSX_SYSROOT 131 ERROR_QUIET 132 OUTPUT_STRIP_TRAILING_WHITESPACE) 133 if (NOT OSX_SYSROOT OR NOT EXISTS ${OSX_SYSROOT}) 134 message(WARNING "Detected OSX_SYSROOT ${OSX_SYSROOT} does not exist") 135 else() 136 message(STATUS "Found OSX_SYSROOT: ${OSX_SYSROOT}") 137 set(OSX_SYSROOT_FLAG "-isysroot${OSX_SYSROOT}") 138 endif() 139 else() 140 set(OSX_SYSROOT_FLAG "") 141 endif() 142 143 try_compile_only(COMPILER_RT_HAS_DARWIN_TARGET_VARIANT_FLAG 144 FLAGS 145 "-target" "x86_64-apple-macos10.15" 146 "-darwin-target-variant" "x86_64-apple-ios13.1-macabi" 147 "-Werror") 148 option(COMPILER_RT_ENABLE_MACCATALYST "Enable building for Mac Catalyst" ${COMPILER_RT_HAS_DARWIN_TARGET_VARIANT_FLAG}) 149 150 # Don't enable COMPILER_RT_ENABLE_IOS if we can't find the sdk dir. 151 # This can happen when you only have the commandline tools installed 152 # which doesn't come with the iOS SDK. 153 find_darwin_sdk_dir(HAS_IOS_SDK "iphoneos") 154 set(COMPILER_RT_ENABLE_IOS_DEFAULT On) 155 if("${HAS_IOS_SDK}" STREQUAL "") 156 message(WARNING "iOS SDK not found! Building compiler-rt without iOS support.") 157 set(COMPILER_RT_ENABLE_IOS_DEFAULT Off) 158 endif() 159 option(COMPILER_RT_ENABLE_IOS "Enable building for iOS" ${COMPILER_RT_ENABLE_IOS_DEFAULT}) 160 161 option(COMPILER_RT_ENABLE_WATCHOS "Enable building for watchOS - Experimental" Off) 162 option(COMPILER_RT_ENABLE_TVOS "Enable building for tvOS - Experimental" Off) 163 164else() 165 option(COMPILER_RT_DEFAULT_TARGET_ONLY "Build builtins only for the default target" Off) 166endif() 167 168if(WIN32 AND NOT MINGW AND NOT CYGWIN) 169 set(CMAKE_SHARED_LIBRARY_PREFIX_C "") 170 set(CMAKE_SHARED_LIBRARY_PREFIX_CXX "") 171 set(CMAKE_STATIC_LIBRARY_PREFIX_C "") 172 set(CMAKE_STATIC_LIBRARY_PREFIX_CXX "") 173 set(CMAKE_STATIC_LIBRARY_SUFFIX_C ".lib") 174 set(CMAKE_STATIC_LIBRARY_SUFFIX_CXX ".lib") 175endif() 176 177macro(test_targets) 178 # Find and run MSVC (not clang-cl) and get its version. This will tell clang-cl 179 # what version of MSVC to pretend to be so that the STL works. 180 set(MSVC_VERSION_FLAG "") 181 if (MSVC) 182 execute_process(COMMAND "$ENV{VSINSTALLDIR}/VC/bin/cl.exe" 183 OUTPUT_QUIET 184 ERROR_VARIABLE MSVC_COMPAT_VERSION 185 ) 186 string(REGEX REPLACE "^.*Compiler Version ([0-9.]+) for .*$" "\\1" 187 MSVC_COMPAT_VERSION "${MSVC_COMPAT_VERSION}") 188 if (MSVC_COMPAT_VERSION MATCHES "^[0-9].+$") 189 set(MSVC_VERSION_FLAG "-fms-compatibility-version=${MSVC_COMPAT_VERSION}") 190 # Add this flag into the host build if this is clang-cl. 191 if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") 192 append("${MSVC_VERSION_FLAG}" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) 193 elseif (COMPILER_RT_TEST_COMPILER_ID MATCHES "Clang") 194 # Add this flag to test compiles to suppress clang's auto-detection 195 # logic. 196 append("${MSVC_VERSION_FLAG}" COMPILER_RT_TEST_COMPILER_CFLAGS) 197 endif() 198 endif() 199 endif() 200 201 # Generate the COMPILER_RT_SUPPORTED_ARCH list. 202 if(ANDROID) 203 # Examine compiler output to determine target architecture. 204 detect_target_arch() 205 set(COMPILER_RT_OS_SUFFIX "-android") 206 elseif(NOT APPLE) # Supported archs for Apple platforms are generated later 207 if(COMPILER_RT_DEFAULT_TARGET_ONLY) 208 add_default_target_arch(${COMPILER_RT_DEFAULT_TARGET_ARCH}) 209 elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "i[2-6]86|x86|amd64") 210 if(NOT MSVC) 211 test_target_arch(x86_64 "" "-m64") 212 test_target_arch(i386 __i386__ "-m32") 213 else() 214 if (CMAKE_SIZEOF_VOID_P EQUAL 4) 215 test_target_arch(i386 "" "") 216 else() 217 test_target_arch(x86_64 "" "") 218 endif() 219 endif() 220 elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "loongarch64") 221 test_target_arch(loongarch64 "" "") 222 elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "powerpc64le|ppc64le") 223 test_target_arch(powerpc64le "" "-m64") 224 elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "powerpc") 225 test_target_arch(powerpc "" "-m32") 226 test_target_arch(powerpc64 "" "-m64") 227 elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "s390x") 228 test_target_arch(s390x "" "") 229 elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "sparc") 230 test_target_arch(sparc "" "-m32") 231 test_target_arch(sparcv9 "" "-m64") 232 elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "mips") 233 # FIXME: Ideally, we would build the N32 library too. 234 if("${COMPILER_RT_MIPS_EL}" AND ("${COMPILER_RT_MIPS32R6}" OR "${COMPILER_RT_MIPS64R6}")) 235 test_target_arch(mipsel "" "-mips32r6" "-mabi=32" "-D_LARGEFILE_SOURCE" "-D_FILE_OFFSET_BITS=64") 236 test_target_arch(mips64el "" "-mips64r6" "-mabi=64") 237 elseif("${COMPILER_RT_MIPS_EL}") 238 test_target_arch(mipsel "" "-mips32r2" "-mabi=32" "-D_LARGEFILE_SOURCE" "-D_FILE_OFFSET_BITS=64") 239 test_target_arch(mips64el "" "-mips64r2" "-mabi=64") 240 elseif("${COMPILER_RT_MIPS32R6}" OR "${COMPILER_RT_MIPS64R6}") 241 test_target_arch(mips "" "-mips32r6" "-mabi=32" "-D_LARGEFILE_SOURCE" "-D_FILE_OFFSET_BITS=64") 242 test_target_arch(mips64 "" "-mips64r6" "-mabi=64") 243 else() 244 test_target_arch(mips "" "-mips32r2" "-mabi=32" "-D_LARGEFILE_SOURCE" "-D_FILE_OFFSET_BITS=64") 245 test_target_arch(mips64 "" "-mips64r2" "-mabi=64") 246 endif() 247 elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "arm") 248 if(WIN32) 249 test_target_arch(arm "" "" "") 250 else() 251 test_target_arch(armv4t "" "-march=armv4t" "-mfloat-abi=soft") 252 test_target_arch(armv6m "" "-march=armv6m" "-mfloat-abi=soft") 253 test_target_arch(arm "" "-march=armv7-a" "-mfloat-abi=soft") 254 test_target_arch(armhf "" "-march=armv7-a" "-mfloat-abi=hard") 255 endif() 256 elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "avr") 257 test_target_arch(avr "__AVR__" "--target=avr") 258 elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "aarch32") 259 test_target_arch(aarch32 "" "-march=armv8-a") 260 elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "aarch64") 261 test_target_arch(aarch64 "" "-march=armv8-a") 262 elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "riscv32") 263 test_target_arch(riscv32 "" "") 264 elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "riscv64") 265 test_target_arch(riscv64 "" "") 266 elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "wasm32") 267 test_target_arch(wasm32 "" "--target=wasm32-unknown-unknown") 268 elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "wasm64") 269 test_target_arch(wasm64 "" "--target=wasm64-unknown-unknown") 270 elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "ve") 271 test_target_arch(ve "__ve__" "--target=ve-unknown-none") 272 endif() 273 set(COMPILER_RT_OS_SUFFIX "") 274 endif() 275endmacro() 276