Home | History | Annotate | Download | only in cmake
      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 
      6 include(CheckIncludeFile)
      7 check_include_file(unwind.h HAVE_UNWIND_H)
      8 
      9 # Top level target used to build all compiler-rt libraries.
     10 add_custom_target(compiler-rt ALL)
     11 set_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.
     15 if (LLVM_LIBRARY_OUTPUT_INTDIR AND LLVM_RUNTIME_OUTPUT_INTDIR AND PACKAGE_VERSION)
     16   set(LLVM_TREE_AVAILABLE On)
     17 endif()
     18 
     19 if (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()
     42 else()
     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")
     55 endif()
     56 
     57 if("${COMPILER_RT_TEST_COMPILER}" MATCHES "clang[+]*$")
     58   set(COMPILER_RT_TEST_COMPILER_ID Clang)
     59 elseif("${COMPILER_RT_TEST_COMPILER}" MATCHES "clang.*.exe$")
     60   set(COMPILER_RT_TEST_COMPILER_ID Clang)
     61 else()
     62   set(COMPILER_RT_TEST_COMPILER_ID GNU)
     63 endif()
     64 
     65 string(TOLOWER ${CMAKE_SYSTEM_NAME} COMPILER_RT_OS_DIR)
     66 set(COMPILER_RT_LIBRARY_OUTPUT_DIR
     67   ${COMPILER_RT_OUTPUT_DIR}/lib/${COMPILER_RT_OS_DIR})
     68 set(COMPILER_RT_LIBRARY_INSTALL_DIR
     69   ${COMPILER_RT_INSTALL_PATH}/lib/${COMPILER_RT_OS_DIR})
     70 
     71 if(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)
     86 endif()
     87 
     88 macro(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()
    169 endmacro()
    170