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