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(CheckIncludeFile) 7check_include_file(unwind.h HAVE_UNWIND_H) 8 9# Top level target used to build all compiler-rt libraries. 10add_custom_target(compiler-rt ALL) 11set_target_properties(compiler-rt PROPERTIES FOLDER "Compiler-RT Misc") 12 13# Setting these variables from an LLVM build is sufficient that compiler-rt can 14# construct the output paths, so it can behave as if it were in-tree here. 15if (LLVM_LIBRARY_OUTPUT_INTDIR AND LLVM_RUNTIME_OUTPUT_INTDIR AND PACKAGE_VERSION) 16 set(LLVM_TREE_AVAILABLE On) 17endif() 18 19if (LLVM_TREE_AVAILABLE) 20 # Compute the Clang version from the LLVM version. 21 # FIXME: We should be able to reuse CLANG_VERSION variable calculated 22 # in Clang cmake files, instead of copying the rules here. 23 string(REGEX MATCH "[0-9]+\\.[0-9]+(\\.[0-9]+)?" CLANG_VERSION 24 ${PACKAGE_VERSION}) 25 # Setup the paths where compiler-rt runtimes and headers should be stored. 26 set(COMPILER_RT_OUTPUT_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/clang/${CLANG_VERSION}) 27 set(COMPILER_RT_EXEC_OUTPUT_DIR ${LLVM_RUNTIME_OUTPUT_INTDIR}) 28 set(COMPILER_RT_INSTALL_PATH lib${LLVM_LIBDIR_SUFFIX}/clang/${CLANG_VERSION}) 29 option(COMPILER_RT_INCLUDE_TESTS "Generate and build compiler-rt unit tests." 30 ${LLVM_INCLUDE_TESTS}) 31 option(COMPILER_RT_ENABLE_WERROR "Fail and stop if warning is triggered" 32 ${LLVM_ENABLE_WERROR}) 33 # Use just-built Clang to compile/link tests on all platforms, except for 34 # Windows where we need to use clang-cl instead. 35 if(NOT MSVC) 36 set(COMPILER_RT_TEST_COMPILER ${LLVM_RUNTIME_OUTPUT_INTDIR}/clang) 37 set(COMPILER_RT_TEST_CXX_COMPILER ${LLVM_RUNTIME_OUTPUT_INTDIR}/clang++) 38 else() 39 set(COMPILER_RT_TEST_COMPILER ${LLVM_RUNTIME_OUTPUT_INTDIR}/clang.exe) 40 set(COMPILER_RT_TEST_CXX_COMPILER ${LLVM_RUNTIME_OUTPUT_INTDIR}/clang++.exe) 41 endif() 42else() 43 # Take output dir and install path from the user. 44 set(COMPILER_RT_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR} CACHE PATH 45 "Path where built compiler-rt libraries should be stored.") 46 set(COMPILER_RT_EXEC_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/bin CACHE PATH 47 "Path where built compiler-rt executables should be stored.") 48 set(COMPILER_RT_INSTALL_PATH ${CMAKE_INSTALL_PREFIX} CACHE PATH 49 "Path where built compiler-rt libraries should be installed.") 50 option(COMPILER_RT_INCLUDE_TESTS "Generate and build compiler-rt unit tests." OFF) 51 option(COMPILER_RT_ENABLE_WERROR "Fail and stop if warning is triggered" OFF) 52 # Use a host compiler to compile/link tests. 53 set(COMPILER_RT_TEST_COMPILER ${CMAKE_C_COMPILER} CACHE PATH "Compiler to use for testing") 54 set(COMPILER_RT_TEST_CXX_COMPILER ${CMAKE_CXX_COMPILER} CACHE PATH "C++ Compiler to use for testing") 55endif() 56 57if("${COMPILER_RT_TEST_COMPILER}" MATCHES "clang[+]*$") 58 set(COMPILER_RT_TEST_COMPILER_ID Clang) 59elseif("${COMPILER_RT_TEST_COMPILER}" MATCHES "clang.*.exe$") 60 set(COMPILER_RT_TEST_COMPILER_ID Clang) 61else() 62 set(COMPILER_RT_TEST_COMPILER_ID GNU) 63endif() 64 65string(TOLOWER ${CMAKE_SYSTEM_NAME} COMPILER_RT_OS_DIR) 66set(COMPILER_RT_LIBRARY_OUTPUT_DIR 67 ${COMPILER_RT_OUTPUT_DIR}/lib/${COMPILER_RT_OS_DIR}) 68set(COMPILER_RT_LIBRARY_INSTALL_DIR 69 ${COMPILER_RT_INSTALL_PATH}/lib/${COMPILER_RT_OS_DIR}) 70 71if(APPLE) 72 # On Darwin if /usr/include doesn't exist, the user probably has Xcode but not 73 # the command line tools. If this is the case, we need to find the OS X 74 # sysroot to pass to clang. 75 if(NOT EXISTS /usr/include) 76 execute_process(COMMAND xcodebuild -version -sdk macosx Path 77 OUTPUT_VARIABLE OSX_SYSROOT 78 ERROR_QUIET 79 OUTPUT_STRIP_TRAILING_WHITESPACE) 80 set(OSX_SYSROOT_FLAG "-isysroot${OSX_SYSROOT}") 81 endif() 82 83 option(COMPILER_RT_ENABLE_IOS "Enable building for iOS" Off) 84 option(COMPILER_RT_ENABLE_WATCHOS "Enable building for watchOS - Experimental" Off) 85 option(COMPILER_RT_ENABLE_TVOS "Enable building for tvOS - Experimental" Off) 86endif() 87 88macro(test_targets) 89 # Find and run MSVC (not clang-cl) and get its version. This will tell clang-cl 90 # what version of MSVC to pretend to be so that the STL works. 91 set(MSVC_VERSION_FLAG "") 92 if (MSVC) 93 # Find and run MSVC (not clang-cl) and get its version. This will tell 94 # clang-cl what version of MSVC to pretend to be so that the STL works. 95 execute_process(COMMAND "$ENV{VSINSTALLDIR}/VC/bin/cl.exe" 96 OUTPUT_QUIET 97 ERROR_VARIABLE MSVC_COMPAT_VERSION 98 ) 99 string(REGEX REPLACE "^.*Compiler Version ([0-9.]+) for .*$" "\\1" 100 MSVC_COMPAT_VERSION "${MSVC_COMPAT_VERSION}") 101 if (MSVC_COMPAT_VERSION MATCHES "^[0-9].+$") 102 set(MSVC_VERSION_FLAG "-fms-compatibility-version=${MSVC_COMPAT_VERSION}") 103 # Add this flag into the host build if this is clang-cl. 104 if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") 105 append("${MSVC_VERSION_FLAG}" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) 106 elseif (COMPILER_RT_TEST_COMPILER_ID MATCHES "Clang") 107 # Add this flag to test compiles to suppress clang's auto-detection 108 # logic. 109 append("${MSVC_VERSION_FLAG}" COMPILER_RT_TEST_COMPILER_CFLAGS) 110 endif() 111 endif() 112 endif() 113 114 # Generate the COMPILER_RT_SUPPORTED_ARCH list. 115 if(ANDROID) 116 # Examine compiler output to determine target architecture. 117 detect_target_arch() 118 set(COMPILER_RT_OS_SUFFIX "-android") 119 elseif(NOT APPLE) # Supported archs for Apple platforms are generated later 120 if("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "i[2-6]86|x86|amd64") 121 if(NOT MSVC) 122 test_target_arch(x86_64 "" "-m64") 123 # FIXME: We build runtimes for both i686 and i386, as "clang -m32" may 124 # target different variant than "$CMAKE_C_COMPILER -m32". This part should 125 # be gone after we resolve PR14109. 126 test_target_arch(i686 __i686__ "-m32") 127 test_target_arch(i386 __i386__ "-m32") 128 else() 129 if (CMAKE_SIZEOF_VOID_P EQUAL 4) 130 test_target_arch(i386 "" "") 131 else() 132 test_target_arch(x86_64 "" "") 133 endif() 134 endif() 135 elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "powerpc") 136 TEST_BIG_ENDIAN(HOST_IS_BIG_ENDIAN) 137 if(HOST_IS_BIG_ENDIAN) 138 test_target_arch(powerpc64 "" "-m64") 139 else() 140 test_target_arch(powerpc64le "" "-m64") 141 endif() 142 elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "s390x") 143 test_target_arch(s390x "" "") 144 elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "mipsel|mips64el") 145 # Gcc doesn't accept -m32/-m64 so we do the next best thing and use 146 # -mips32r2/-mips64r2. We don't use -mips1/-mips3 because we want to match 147 # clang's default CPU's. In the 64-bit case, we must also specify the ABI 148 # since the default ABI differs between gcc and clang. 149 # FIXME: Ideally, we would build the N32 library too. 150 test_target_arch(mipsel "" "-mips32r2" "--target=mipsel-linux-gnu") 151 test_target_arch(mips64el "" "-mips64r2" "--target=mips64el-linux-gnu" "-mabi=n64") 152 elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "mips") 153 test_target_arch(mips "" "-mips32r2" "--target=mips-linux-gnu") 154 test_target_arch(mips64 "" "-mips64r2" "--target=mips64-linux-gnu" "-mabi=n64") 155 elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "arm") 156 test_target_arch(arm "" "-march=armv7-a" "-mfloat-abi=soft") 157 test_target_arch(armhf "" "-march=armv7-a" "-mfloat-abi=hard") 158 elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "aarch32") 159 test_target_arch(aarch32 "" "-march=armv8-a") 160 elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "aarch64") 161 test_target_arch(aarch64 "" "-march=armv8-a") 162 elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "wasm32") 163 test_target_arch(wasm32 "" "--target=wasm32-unknown-unknown") 164 elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "wasm64") 165 test_target_arch(wasm64 "" "--target=wasm64-unknown-unknown") 166 endif() 167 set(COMPILER_RT_OS_SUFFIX "") 168 endif() 169endmacro() 170