13cab2bb3Spatrickinclude(CMakePushCheckState) 23cab2bb3Spatrickinclude(CheckSymbolExists) 33cab2bb3Spatrick 43cab2bb3Spatrick# Because compiler-rt spends a lot of time setting up custom compile flags, 53cab2bb3Spatrick# define a handy helper function for it. The compile flags setting in CMake 63cab2bb3Spatrick# has serious issues that make its syntax challenging at best. 73cab2bb3Spatrickfunction(set_target_compile_flags target) 8*810390e3Srobert set_property(TARGET ${target} PROPERTY COMPILE_OPTIONS ${ARGN}) 93cab2bb3Spatrickendfunction() 103cab2bb3Spatrick 113cab2bb3Spatrickfunction(set_target_link_flags target) 12*810390e3Srobert set_property(TARGET ${target} PROPERTY LINK_OPTIONS ${ARGN}) 133cab2bb3Spatrickendfunction() 143cab2bb3Spatrick 153cab2bb3Spatrick# Set the variable var_PYBOOL to True if var holds a true-ish string, 163cab2bb3Spatrick# otherwise set it to False. 173cab2bb3Spatrickmacro(pythonize_bool var) 183cab2bb3Spatrick if (${var}) 193cab2bb3Spatrick set(${var}_PYBOOL True) 203cab2bb3Spatrick else() 213cab2bb3Spatrick set(${var}_PYBOOL False) 223cab2bb3Spatrick endif() 233cab2bb3Spatrickendmacro() 243cab2bb3Spatrick 253cab2bb3Spatrick# Appends value to all lists in ARGN, if the condition is true. 263cab2bb3Spatrickmacro(append_list_if condition value) 273cab2bb3Spatrick if(${condition}) 283cab2bb3Spatrick foreach(list ${ARGN}) 293cab2bb3Spatrick list(APPEND ${list} ${value}) 303cab2bb3Spatrick endforeach() 313cab2bb3Spatrick endif() 323cab2bb3Spatrickendmacro() 333cab2bb3Spatrick 343cab2bb3Spatrick# Appends value to all strings in ARGN, if the condition is true. 353cab2bb3Spatrickmacro(append_string_if condition value) 363cab2bb3Spatrick if(${condition}) 373cab2bb3Spatrick foreach(str ${ARGN}) 383cab2bb3Spatrick set(${str} "${${str}} ${value}") 393cab2bb3Spatrick endforeach() 403cab2bb3Spatrick endif() 413cab2bb3Spatrickendmacro() 423cab2bb3Spatrick 433cab2bb3Spatrickmacro(append_rtti_flag polarity list) 443cab2bb3Spatrick if(${polarity}) 453cab2bb3Spatrick append_list_if(COMPILER_RT_HAS_FRTTI_FLAG -frtti ${list}) 463cab2bb3Spatrick append_list_if(COMPILER_RT_HAS_GR_FLAG /GR ${list}) 473cab2bb3Spatrick else() 483cab2bb3Spatrick append_list_if(COMPILER_RT_HAS_FNO_RTTI_FLAG -fno-rtti ${list}) 493cab2bb3Spatrick append_list_if(COMPILER_RT_HAS_GR_FLAG /GR- ${list}) 503cab2bb3Spatrick endif() 513cab2bb3Spatrickendmacro() 523cab2bb3Spatrick 533cab2bb3Spatrickmacro(list_intersect output input1 input2) 543cab2bb3Spatrick set(${output}) 553cab2bb3Spatrick foreach(it ${${input1}}) 563cab2bb3Spatrick list(FIND ${input2} ${it} index) 573cab2bb3Spatrick if( NOT (index EQUAL -1)) 583cab2bb3Spatrick list(APPEND ${output} ${it}) 593cab2bb3Spatrick endif() 603cab2bb3Spatrick endforeach() 613cab2bb3Spatrickendmacro() 623cab2bb3Spatrick 633cab2bb3Spatrickfunction(list_replace input_list old new) 643cab2bb3Spatrick set(replaced_list) 653cab2bb3Spatrick foreach(item ${${input_list}}) 663cab2bb3Spatrick if(${item} STREQUAL ${old}) 673cab2bb3Spatrick list(APPEND replaced_list ${new}) 683cab2bb3Spatrick else() 693cab2bb3Spatrick list(APPEND replaced_list ${item}) 703cab2bb3Spatrick endif() 713cab2bb3Spatrick endforeach() 723cab2bb3Spatrick set(${input_list} "${replaced_list}" PARENT_SCOPE) 733cab2bb3Spatrickendfunction() 743cab2bb3Spatrick 753cab2bb3Spatrick# Takes ${ARGN} and puts only supported architectures in @out_var list. 763cab2bb3Spatrickfunction(filter_available_targets out_var) 773cab2bb3Spatrick set(archs ${${out_var}}) 783cab2bb3Spatrick foreach(arch ${ARGN}) 793cab2bb3Spatrick list(FIND COMPILER_RT_SUPPORTED_ARCH ${arch} ARCH_INDEX) 803cab2bb3Spatrick if(NOT (ARCH_INDEX EQUAL -1) AND CAN_TARGET_${arch}) 813cab2bb3Spatrick list(APPEND archs ${arch}) 823cab2bb3Spatrick endif() 833cab2bb3Spatrick endforeach() 843cab2bb3Spatrick set(${out_var} ${archs} PARENT_SCOPE) 853cab2bb3Spatrickendfunction() 863cab2bb3Spatrick 873cab2bb3Spatrick# Add $arch as supported with no additional flags. 883cab2bb3Spatrickmacro(add_default_target_arch arch) 893cab2bb3Spatrick set(TARGET_${arch}_CFLAGS "") 903cab2bb3Spatrick set(CAN_TARGET_${arch} 1) 913cab2bb3Spatrick list(APPEND COMPILER_RT_SUPPORTED_ARCH ${arch}) 923cab2bb3Spatrickendmacro() 933cab2bb3Spatrick 943cab2bb3Spatrickfunction(check_compile_definition def argstring out_var) 953cab2bb3Spatrick if("${def}" STREQUAL "") 963cab2bb3Spatrick set(${out_var} TRUE PARENT_SCOPE) 973cab2bb3Spatrick return() 983cab2bb3Spatrick endif() 993cab2bb3Spatrick cmake_push_check_state() 1003cab2bb3Spatrick set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${argstring}") 1013cab2bb3Spatrick check_symbol_exists(${def} "" ${out_var}) 1023cab2bb3Spatrick cmake_pop_check_state() 1033cab2bb3Spatrickendfunction() 1043cab2bb3Spatrick 1053cab2bb3Spatrick# test_target_arch(<arch> <def> <target flags...>) 1063cab2bb3Spatrick# Checks if architecture is supported: runs host compiler with provided 1073cab2bb3Spatrick# flags to verify that: 1083cab2bb3Spatrick# 1) <def> is defined (if non-empty) 1093cab2bb3Spatrick# 2) simple file can be successfully built. 1103cab2bb3Spatrick# If successful, saves target flags for this architecture. 1113cab2bb3Spatrickmacro(test_target_arch arch def) 1123cab2bb3Spatrick set(TARGET_${arch}_CFLAGS ${ARGN}) 1133cab2bb3Spatrick set(TARGET_${arch}_LINK_FLAGS ${ARGN}) 1143cab2bb3Spatrick set(argstring "") 1153cab2bb3Spatrick foreach(arg ${ARGN}) 1163cab2bb3Spatrick set(argstring "${argstring} ${arg}") 1173cab2bb3Spatrick endforeach() 1183cab2bb3Spatrick check_compile_definition("${def}" "${argstring}" HAS_${arch}_DEF) 1193cab2bb3Spatrick if(NOT DEFINED CAN_TARGET_${arch}) 1203cab2bb3Spatrick if(NOT HAS_${arch}_DEF) 1213cab2bb3Spatrick set(CAN_TARGET_${arch} FALSE) 1223cab2bb3Spatrick elseif(TEST_COMPILE_ONLY) 123*810390e3Srobert try_compile_only(CAN_TARGET_${arch} 124*810390e3Srobert SOURCE "#include <limits.h>\nint foo(int x, int y) { return x + y; }\n" 125*810390e3Srobert FLAGS ${TARGET_${arch}_CFLAGS}) 1263cab2bb3Spatrick else() 1273cab2bb3Spatrick set(FLAG_NO_EXCEPTIONS "") 1283cab2bb3Spatrick if(COMPILER_RT_HAS_FNO_EXCEPTIONS_FLAG) 1293cab2bb3Spatrick set(FLAG_NO_EXCEPTIONS " -fno-exceptions ") 1303cab2bb3Spatrick endif() 1313cab2bb3Spatrick set(SAVED_CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS}) 1323cab2bb3Spatrick set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${argstring}") 1333cab2bb3Spatrick try_compile(CAN_TARGET_${arch} ${CMAKE_BINARY_DIR} ${SIMPLE_SOURCE} 1343cab2bb3Spatrick COMPILE_DEFINITIONS "${TARGET_${arch}_CFLAGS} ${FLAG_NO_EXCEPTIONS}" 1353cab2bb3Spatrick OUTPUT_VARIABLE TARGET_${arch}_OUTPUT) 1363cab2bb3Spatrick set(CMAKE_EXE_LINKER_FLAGS ${SAVED_CMAKE_EXE_LINKER_FLAGS}) 1373cab2bb3Spatrick endif() 1383cab2bb3Spatrick endif() 1393cab2bb3Spatrick if(${CAN_TARGET_${arch}}) 1403cab2bb3Spatrick list(APPEND COMPILER_RT_SUPPORTED_ARCH ${arch}) 1413cab2bb3Spatrick elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" STREQUAL "${arch}" AND 1423cab2bb3Spatrick COMPILER_RT_HAS_EXPLICIT_DEFAULT_TARGET_TRIPLE) 1433cab2bb3Spatrick # Bail out if we cannot target the architecture we plan to test. 1443cab2bb3Spatrick message(FATAL_ERROR "Cannot compile for ${arch}:\n${TARGET_${arch}_OUTPUT}") 1453cab2bb3Spatrick endif() 1463cab2bb3Spatrickendmacro() 1473cab2bb3Spatrick 1483cab2bb3Spatrickmacro(detect_target_arch) 1493cab2bb3Spatrick check_symbol_exists(__arm__ "" __ARM) 150*810390e3Srobert check_symbol_exists(__AVR__ "" __AVR) 1513cab2bb3Spatrick check_symbol_exists(__aarch64__ "" __AARCH64) 1523cab2bb3Spatrick check_symbol_exists(__x86_64__ "" __X86_64) 1533cab2bb3Spatrick check_symbol_exists(__i386__ "" __I386) 154*810390e3Srobert check_symbol_exists(__loongarch__ "" __LOONGARCH) 1553cab2bb3Spatrick check_symbol_exists(__mips__ "" __MIPS) 1563cab2bb3Spatrick check_symbol_exists(__mips64__ "" __MIPS64) 157d89ec533Spatrick check_symbol_exists(__powerpc__ "" __PPC) 1583cab2bb3Spatrick check_symbol_exists(__powerpc64__ "" __PPC64) 1593cab2bb3Spatrick check_symbol_exists(__powerpc64le__ "" __PPC64LE) 1603cab2bb3Spatrick check_symbol_exists(__riscv "" __RISCV) 1613cab2bb3Spatrick check_symbol_exists(__s390x__ "" __S390X) 1623cab2bb3Spatrick check_symbol_exists(__sparc "" __SPARC) 1633cab2bb3Spatrick check_symbol_exists(__sparcv9 "" __SPARCV9) 1643cab2bb3Spatrick check_symbol_exists(__wasm32__ "" __WEBASSEMBLY32) 1653cab2bb3Spatrick check_symbol_exists(__wasm64__ "" __WEBASSEMBLY64) 1661f9cb04fSpatrick check_symbol_exists(__ve__ "" __VE) 1673cab2bb3Spatrick if(__ARM) 1683cab2bb3Spatrick add_default_target_arch(arm) 169*810390e3Srobert elseif(__AVR) 170*810390e3Srobert add_default_target_arch(avr) 1713cab2bb3Spatrick elseif(__AARCH64) 1723cab2bb3Spatrick add_default_target_arch(aarch64) 1733cab2bb3Spatrick elseif(__X86_64) 174d89ec533Spatrick if(CMAKE_SIZEOF_VOID_P EQUAL "4") 175d89ec533Spatrick add_default_target_arch(x32) 176d89ec533Spatrick elseif(CMAKE_SIZEOF_VOID_P EQUAL "8") 1773cab2bb3Spatrick add_default_target_arch(x86_64) 178d89ec533Spatrick else() 179d89ec533Spatrick message(FATAL_ERROR "Unsupported pointer size for X86_64") 180d89ec533Spatrick endif() 1813cab2bb3Spatrick elseif(__I386) 1823cab2bb3Spatrick add_default_target_arch(i386) 183*810390e3Srobert elseif(__LOONGARCH) 184*810390e3Srobert if(CMAKE_SIZEOF_VOID_P EQUAL "4") 185*810390e3Srobert add_default_target_arch(loongarch32) 186*810390e3Srobert elseif(CMAKE_SIZEOF_VOID_P EQUAL "8") 187*810390e3Srobert add_default_target_arch(loongarch64) 188*810390e3Srobert else() 189*810390e3Srobert message(FATAL_ERROR "Unsupported pointer size for LoongArch") 190*810390e3Srobert endif() 1913cab2bb3Spatrick elseif(__MIPS64) # must be checked before __MIPS 1923cab2bb3Spatrick add_default_target_arch(mips64) 1933cab2bb3Spatrick elseif(__MIPS) 1943cab2bb3Spatrick add_default_target_arch(mips) 195d89ec533Spatrick elseif(__PPC64) # must be checked before __PPC 1963cab2bb3Spatrick add_default_target_arch(powerpc64) 1973cab2bb3Spatrick elseif(__PPC64LE) 1983cab2bb3Spatrick add_default_target_arch(powerpc64le) 199d89ec533Spatrick elseif(__PPC) 200d89ec533Spatrick add_default_target_arch(powerpc) 2013cab2bb3Spatrick elseif(__RISCV) 2023cab2bb3Spatrick if(CMAKE_SIZEOF_VOID_P EQUAL "4") 2033cab2bb3Spatrick add_default_target_arch(riscv32) 2043cab2bb3Spatrick elseif(CMAKE_SIZEOF_VOID_P EQUAL "8") 2053cab2bb3Spatrick add_default_target_arch(riscv64) 2063cab2bb3Spatrick else() 2073cab2bb3Spatrick message(FATAL_ERROR "Unsupport XLEN for RISC-V") 2083cab2bb3Spatrick endif() 2093cab2bb3Spatrick elseif(__S390X) 2103cab2bb3Spatrick add_default_target_arch(s390x) 2113cab2bb3Spatrick elseif(__SPARCV9) 2123cab2bb3Spatrick add_default_target_arch(sparcv9) 2133cab2bb3Spatrick elseif(__SPARC) 2143cab2bb3Spatrick add_default_target_arch(sparc) 2153cab2bb3Spatrick elseif(__WEBASSEMBLY32) 2163cab2bb3Spatrick add_default_target_arch(wasm32) 2173cab2bb3Spatrick elseif(__WEBASSEMBLY64) 2183cab2bb3Spatrick add_default_target_arch(wasm64) 2191f9cb04fSpatrick elseif(__VE) 2201f9cb04fSpatrick add_default_target_arch(ve) 2213cab2bb3Spatrick endif() 2223cab2bb3Spatrickendmacro() 2233cab2bb3Spatrick 224d89ec533Spatrickfunction(get_compiler_rt_root_source_dir ROOT_DIR_VAR) 225d89ec533Spatrick # Compute the path to the root of the Compiler-RT source tree 226d89ec533Spatrick # regardless of how the project was configured. 227d89ec533Spatrick # 228d89ec533Spatrick # This function is useful because using `${CMAKE_SOURCE_DIR}` 229d89ec533Spatrick # is error prone due to the numerous ways Compiler-RT can be 230d89ec533Spatrick # configured. 231d89ec533Spatrick # 232d89ec533Spatrick # `ROOT_DIR_VAR` - the name of the variable to write the result to. 233d89ec533Spatrick # 234d89ec533Spatrick # TODO(dliew): When CMake min version is 3.17 or newer use 235d89ec533Spatrick # `CMAKE_CURRENT_FUNCTION_LIST_DIR` instead. 236d89ec533Spatrick if ("${ROOT_DIR_VAR}" STREQUAL "") 237d89ec533Spatrick message(FATAL_ERROR "ROOT_DIR_VAR cannot be empty") 238d89ec533Spatrick endif() 239d89ec533Spatrick 240d89ec533Spatrick # Compiler-rt supports different source root paths. 241d89ec533Spatrick # Handle each case here. 242d89ec533Spatrick set(PATH_TO_COMPILER_RT_SOURCE_ROOT "") 243d89ec533Spatrick if (DEFINED CompilerRTBuiltins_SOURCE_DIR) 244d89ec533Spatrick # Compiler-RT Builtins standalone build. 245d89ec533Spatrick # `llvm-project/compiler-rt/lib/builtins` 246d89ec533Spatrick set(PATH_TO_COMPILER_RT_SOURCE_ROOT "${CompilerRTBuiltins_SOURCE_DIR}/../../") 247*810390e3Srobert elseif (DEFINED CompilerRTCRT_SOURCE_DIR) 248*810390e3Srobert # Compiler-RT CRT standalone build. 249*810390e3Srobert # `llvm-project/compiler-rt/lib/crt` 250*810390e3Srobert set(PATH_TO_COMPILER_RT_SOURCE_ROOT "${CompilerRTCRT_SOURCE_DIR}/../../") 251d89ec533Spatrick elseif(DEFINED CompilerRT_SOURCE_DIR) 252d89ec533Spatrick # Compiler-RT standalone build. 253d89ec533Spatrick # `llvm-project/compiler-rt` 254d89ec533Spatrick set(PATH_TO_COMPILER_RT_SOURCE_ROOT "${CompilerRT_SOURCE_DIR}") 255d89ec533Spatrick elseif (EXISTS "${CMAKE_SOURCE_DIR}/../compiler-rt") 256d89ec533Spatrick # In tree build with LLVM as the root project. 257d89ec533Spatrick # See `llvm-project/projects/`. 258d89ec533Spatrick # Assumes monorepo layout. 259d89ec533Spatrick set(PATH_TO_COMPILER_RT_SOURCE_ROOT "${CMAKE_SOURCE_DIR}/../compiler-rt") 260d89ec533Spatrick else() 261d89ec533Spatrick message(FATAL_ERROR "Unhandled Compiler-RT source root configuration.") 262d89ec533Spatrick endif() 263d89ec533Spatrick 264d89ec533Spatrick get_filename_component(ROOT_DIR "${PATH_TO_COMPILER_RT_SOURCE_ROOT}" ABSOLUTE) 265d89ec533Spatrick if (NOT EXISTS "${ROOT_DIR}") 266d89ec533Spatrick message(FATAL_ERROR "Path \"${ROOT_DIR}\" doesn't exist") 267d89ec533Spatrick endif() 268d89ec533Spatrick 269d89ec533Spatrick # Sanity check: Make sure we can locate the current source file via the 270d89ec533Spatrick # computed path. 271d89ec533Spatrick set(PATH_TO_CURRENT_FILE "${ROOT_DIR}/cmake/Modules/CompilerRTUtils.cmake") 272d89ec533Spatrick if (NOT EXISTS "${PATH_TO_CURRENT_FILE}") 273d89ec533Spatrick message(FATAL_ERROR "Could not find \"${PATH_TO_CURRENT_FILE}\"") 274d89ec533Spatrick endif() 275d89ec533Spatrick 276d89ec533Spatrick set("${ROOT_DIR_VAR}" "${ROOT_DIR}" PARENT_SCOPE) 277d89ec533Spatrickendfunction() 278d89ec533Spatrick 2793cab2bb3Spatrickmacro(load_llvm_config) 280*810390e3Srobert if (LLVM_CONFIG_PATH AND NOT LLVM_CMAKE_DIR) 281*810390e3Srobert message(WARNING 282*810390e3Srobert "LLVM_CONFIG_PATH is deprecated, please use LLVM_CMAKE_DIR instead") 283*810390e3Srobert # Compute the path to the LLVM install prefix and pass it as LLVM_CMAKE_DIR, 284*810390e3Srobert # CMake will locate the appropriate lib*/cmake subdirectory from there. 285*810390e3Srobert # For example. for -DLLVM_CONFIG_PATH=/usr/lib/llvm/16/bin/llvm-config 286*810390e3Srobert # this will yield LLVM_CMAKE_DIR=/usr/lib/llvm/16. 287*810390e3Srobert get_filename_component(LLVM_CMAKE_DIR "${LLVM_CONFIG_PATH}" DIRECTORY) 288*810390e3Srobert get_filename_component(LLVM_CMAKE_DIR "${LLVM_CMAKE_DIR}" DIRECTORY) 2893cab2bb3Spatrick endif() 290d89ec533Spatrick 291d89ec533Spatrick # Compute path to LLVM sources assuming the monorepo layout. 292d89ec533Spatrick # We don't set `LLVM_MAIN_SRC_DIR` directly to avoid overriding a user provided 293d89ec533Spatrick # CMake cache value. 294d89ec533Spatrick get_compiler_rt_root_source_dir(COMPILER_RT_ROOT_SRC_PATH) 295d89ec533Spatrick get_filename_component(LLVM_MAIN_SRC_DIR_DEFAULT "${COMPILER_RT_ROOT_SRC_PATH}/../llvm" ABSOLUTE) 296d89ec533Spatrick if (NOT EXISTS "${LLVM_MAIN_SRC_DIR_DEFAULT}") 297d89ec533Spatrick # TODO(dliew): Remove this legacy fallback path. 298d89ec533Spatrick message(WARNING 299d89ec533Spatrick "LLVM source tree not found at \"${LLVM_MAIN_SRC_DIR_DEFAULT}\". " 300d89ec533Spatrick "You are not using the monorepo layout. This configuration is DEPRECATED.") 301d89ec533Spatrick endif() 302d89ec533Spatrick 303*810390e3Srobert find_package(LLVM HINTS "${LLVM_CMAKE_DIR}") 304*810390e3Srobert if (NOT LLVM_FOUND) 305*810390e3Srobert message(WARNING "UNSUPPORTED COMPILER-RT CONFIGURATION DETECTED: " 306*810390e3Srobert "LLVM cmake package not found.\n" 307*810390e3Srobert "Reconfigure with -DLLVM_CMAKE_DIR=/path/to/llvm.") 3083cab2bb3Spatrick else() 309*810390e3Srobert list(APPEND CMAKE_MODULE_PATH "${LLVM_DIR}") 310*810390e3Srobert # Turn into CACHE PATHs for overwritting 311*810390e3Srobert set(LLVM_BINARY_DIR "${LLVM_BINARY_DIR}" CACHE PATH "Path to LLVM build tree") 312*810390e3Srobert set(LLVM_LIBRARY_DIR "${LLVM_LIBRARY_DIR}" CACHE PATH "Path to llvm/lib") 313*810390e3Srobert set(LLVM_TOOLS_BINARY_DIR "${LLVM_TOOLS_BINARY_DIR}" CACHE PATH "Path to llvm/bin") 314*810390e3Srobert set(LLVM_INCLUDE_DIR ${LLVM_INCLUDE_DIRS} CACHE PATH "Path to llvm/include and any other header dirs needed") 315*810390e3Srobert 316*810390e3Srobert list(FIND LLVM_AVAILABLE_LIBS LLVMXRay XRAY_INDEX) 3173cab2bb3Spatrick set(COMPILER_RT_HAS_LLVMXRAY TRUE) 318*810390e3Srobert if (XRAY_INDEX EQUAL -1) 319*810390e3Srobert message(WARNING "LLVMXRay not found in LLVM_AVAILABLE_LIBS") 320*810390e3Srobert set(COMPILER_RT_HAS_LLVMXRAY FALSE) 3213cab2bb3Spatrick endif() 3223cab2bb3Spatrick 323*810390e3Srobert list(FIND LLVM_AVAILABLE_LIBS LLVMTestingSupport TESTINGSUPPORT_INDEX) 3243cab2bb3Spatrick set(COMPILER_RT_HAS_LLVMTESTINGSUPPORT TRUE) 325*810390e3Srobert if (TESTINGSUPPORT_INDEX EQUAL -1) 326*810390e3Srobert message(WARNING "LLVMTestingSupport not found in LLVM_AVAILABLE_LIBS") 327*810390e3Srobert set(COMPILER_RT_HAS_LLVMTESTINGSUPPORT FALSE) 3283cab2bb3Spatrick endif() 3293cab2bb3Spatrick endif() 3303cab2bb3Spatrick 3313cab2bb3Spatrick set(LLVM_LIBRARY_OUTPUT_INTDIR 3323cab2bb3Spatrick ${LLVM_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib${LLVM_LIBDIR_SUFFIX}) 333d89ec533Spatrick 334d89ec533Spatrick set(LLVM_MAIN_SRC_DIR "${LLVM_MAIN_SRC_DIR_DEFAULT}" CACHE PATH "Path to LLVM source tree") 335d89ec533Spatrick message(STATUS "LLVM_MAIN_SRC_DIR: \"${LLVM_MAIN_SRC_DIR}\"") 336d89ec533Spatrick if (NOT EXISTS "${LLVM_MAIN_SRC_DIR}") 337d89ec533Spatrick # TODO(dliew): Make this a hard error 338d89ec533Spatrick message(WARNING "LLVM_MAIN_SRC_DIR (${LLVM_MAIN_SRC_DIR}) does not exist. " 339d89ec533Spatrick "You can override the inferred path by adding " 340d89ec533Spatrick "`-DLLVM_MAIN_SRC_DIR=<path_to_llvm_src>` to your CMake invocation " 341d89ec533Spatrick "where `<path_to_llvm_src>` is the path to the `llvm` directory in " 342d89ec533Spatrick "the `llvm-project` repo. " 343d89ec533Spatrick "This will be treated as error in the future.") 344d89ec533Spatrick endif() 345d89ec533Spatrick 346*810390e3Srobert if (NOT LLVM_FOUND) 347d89ec533Spatrick # This configuration tries to configure without the prescence of `LLVMConfig.cmake`. It is 348d89ec533Spatrick # intended for testing purposes (generating the lit test suites) and will likely not support 349d89ec533Spatrick # a build of the runtimes in compiler-rt. 350d89ec533Spatrick include(CompilerRTMockLLVMCMakeConfig) 351d89ec533Spatrick compiler_rt_mock_llvm_cmake_config() 352d89ec533Spatrick endif() 353d89ec533Spatrick 3543cab2bb3Spatrickendmacro() 3553cab2bb3Spatrick 3563cab2bb3Spatrickmacro(construct_compiler_rt_default_triple) 3573cab2bb3Spatrick if(COMPILER_RT_DEFAULT_TARGET_ONLY) 3583cab2bb3Spatrick if(DEFINED COMPILER_RT_DEFAULT_TARGET_TRIPLE) 3593cab2bb3Spatrick message(FATAL_ERROR "COMPILER_RT_DEFAULT_TARGET_TRIPLE isn't supported when building for default target only") 3603cab2bb3Spatrick endif() 3613cab2bb3Spatrick set(COMPILER_RT_DEFAULT_TARGET_TRIPLE ${CMAKE_C_COMPILER_TARGET}) 3623cab2bb3Spatrick else() 363*810390e3Srobert set(COMPILER_RT_DEFAULT_TARGET_TRIPLE ${LLVM_TARGET_TRIPLE} CACHE STRING 3643cab2bb3Spatrick "Default triple for which compiler-rt runtimes will be built.") 3653cab2bb3Spatrick endif() 3663cab2bb3Spatrick 367*810390e3Srobert string(REPLACE "-" ";" LLVM_TARGET_TRIPLE_LIST ${COMPILER_RT_DEFAULT_TARGET_TRIPLE}) 368*810390e3Srobert list(GET LLVM_TARGET_TRIPLE_LIST 0 COMPILER_RT_DEFAULT_TARGET_ARCH) 369d89ec533Spatrick 370d89ec533Spatrick # Map various forms of the architecture names to the canonical forms 371d89ec533Spatrick # (as they are used by clang, see getArchNameForCompilerRTLib). 372d89ec533Spatrick if("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "^i.86$") 373d89ec533Spatrick # Android uses i686, but that's remapped at a later stage. 374d89ec533Spatrick set(COMPILER_RT_DEFAULT_TARGET_ARCH "i386") 375d89ec533Spatrick endif() 376d89ec533Spatrick 3773cab2bb3Spatrick # Determine if test target triple is specified explicitly, and doesn't match the 3783cab2bb3Spatrick # default. 379*810390e3Srobert if(NOT COMPILER_RT_DEFAULT_TARGET_TRIPLE STREQUAL LLVM_TARGET_TRIPLE) 3803cab2bb3Spatrick set(COMPILER_RT_HAS_EXPLICIT_DEFAULT_TARGET_TRIPLE TRUE) 3813cab2bb3Spatrick else() 3823cab2bb3Spatrick set(COMPILER_RT_HAS_EXPLICIT_DEFAULT_TARGET_TRIPLE FALSE) 3833cab2bb3Spatrick endif() 3843cab2bb3Spatrickendmacro() 3853cab2bb3Spatrick 3861f9cb04fSpatrick# Filter out generic versions of routines that are re-implemented in an 3871f9cb04fSpatrick# architecture specific manner. This prevents multiple definitions of the same 3881f9cb04fSpatrick# symbols, making the symbol selection non-deterministic. 3891f9cb04fSpatrick# 3901f9cb04fSpatrick# We follow the convention that a source file that exists in a sub-directory 3911f9cb04fSpatrick# (e.g. `ppc/divtc3.c`) is architecture-specific and that if a generic 3921f9cb04fSpatrick# implementation exists it will be a top-level source file with the same name 3931f9cb04fSpatrick# modulo the file extension (e.g. `divtc3.c`). 3941f9cb04fSpatrickfunction(filter_builtin_sources inout_var name) 3951f9cb04fSpatrick set(intermediate ${${inout_var}}) 3963cab2bb3Spatrick foreach(_file ${intermediate}) 3971f9cb04fSpatrick get_filename_component(_file_dir ${_file} DIRECTORY) 3981f9cb04fSpatrick if (NOT "${_file_dir}" STREQUAL "") 3991f9cb04fSpatrick # Architecture specific file. If a generic version exists, print a notice 4001f9cb04fSpatrick # and ensure that it is removed from the file list. 4013cab2bb3Spatrick get_filename_component(_name ${_file} NAME) 4021f9cb04fSpatrick string(REGEX REPLACE "\\.S$" ".c" _cname "${_name}") 4031f9cb04fSpatrick if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${_cname}") 4041f9cb04fSpatrick message(STATUS "For ${name} builtins preferring ${_file} to ${_cname}") 4053cab2bb3Spatrick list(REMOVE_ITEM intermediate ${_cname}) 4063cab2bb3Spatrick endif() 4071f9cb04fSpatrick endif() 4083cab2bb3Spatrick endforeach() 4091f9cb04fSpatrick set(${inout_var} ${intermediate} PARENT_SCOPE) 4103cab2bb3Spatrickendfunction() 4113cab2bb3Spatrick 4123cab2bb3Spatrickfunction(get_compiler_rt_target arch variable) 4133cab2bb3Spatrick string(FIND ${COMPILER_RT_DEFAULT_TARGET_TRIPLE} "-" dash_index) 4143cab2bb3Spatrick string(SUBSTRING ${COMPILER_RT_DEFAULT_TARGET_TRIPLE} ${dash_index} -1 triple_suffix) 415*810390e3Srobert string(SUBSTRING ${COMPILER_RT_DEFAULT_TARGET_TRIPLE} 0 ${dash_index} triple_cpu) 4163cab2bb3Spatrick if(COMPILER_RT_DEFAULT_TARGET_ONLY) 4173cab2bb3Spatrick # Use exact spelling when building only for the target specified to CMake. 4183cab2bb3Spatrick set(target "${COMPILER_RT_DEFAULT_TARGET_TRIPLE}") 4193cab2bb3Spatrick elseif(ANDROID AND ${arch} STREQUAL "i386") 4201f9cb04fSpatrick set(target "i686${triple_suffix}") 421*810390e3Srobert elseif(${arch} STREQUAL "amd64") 422*810390e3Srobert set(target "x86_64${triple_suffix}") 423*810390e3Srobert elseif(${arch} STREQUAL "sparc64") 424*810390e3Srobert set(target "sparcv9${triple_suffix}") 425*810390e3Srobert elseif("${arch}" MATCHES "mips64|mips64el") 426*810390e3Srobert string(REGEX REPLACE "-gnu.*" "-gnuabi64" triple_suffix_gnu "${triple_suffix}") 427*810390e3Srobert string(REGEX REPLACE "mipsisa32" "mipsisa64" triple_cpu_mips "${triple_cpu}") 428*810390e3Srobert string(REGEX REPLACE "^mips$" "mips64" triple_cpu_mips "${triple_cpu_mips}") 429*810390e3Srobert string(REGEX REPLACE "^mipsel$" "mips64el" triple_cpu_mips "${triple_cpu_mips}") 430*810390e3Srobert set(target "${triple_cpu_mips}${triple_suffix_gnu}") 431*810390e3Srobert elseif("${arch}" MATCHES "mips|mipsel") 432*810390e3Srobert string(REGEX REPLACE "-gnuabi.*" "-gnu" triple_suffix_gnu "${triple_suffix}") 433*810390e3Srobert string(REGEX REPLACE "mipsisa64" "mipsisa32" triple_cpu_mips "${triple_cpu}") 434*810390e3Srobert string(REGEX REPLACE "mips64" "mips" triple_cpu_mips "${triple_cpu_mips}") 435*810390e3Srobert set(target "${triple_cpu_mips}${triple_suffix_gnu}") 436*810390e3Srobert elseif("${arch}" MATCHES "^arm") 437*810390e3Srobert # Arch is arm, armhf, armv6m (anything else would come from using 438*810390e3Srobert # COMPILER_RT_DEFAULT_TARGET_ONLY, which is checked above). 439*810390e3Srobert if (${arch} STREQUAL "armhf") 440*810390e3Srobert # If we are building for hard float but our ABI is soft float. 441*810390e3Srobert if ("${triple_suffix}" MATCHES ".*eabi$") 442*810390e3Srobert # Change "eabi" -> "eabihf" 443*810390e3Srobert set(triple_suffix "${triple_suffix}hf") 444*810390e3Srobert endif() 445*810390e3Srobert # ABI is already set in the triple, don't repeat it in the architecture. 446*810390e3Srobert set(arch "arm") 447*810390e3Srobert else () 448*810390e3Srobert # If we are building for soft float, but the triple's ABI is hard float. 449*810390e3Srobert if ("${triple_suffix}" MATCHES ".*eabihf$") 450*810390e3Srobert # Change "eabihf" -> "eabi" 451*810390e3Srobert string(REGEX REPLACE "hf$" "" triple_suffix "${triple_suffix}") 452*810390e3Srobert endif() 453*810390e3Srobert endif() 454*810390e3Srobert set(target "${arch}${triple_suffix}") 4553cab2bb3Spatrick else() 4563cab2bb3Spatrick set(target "${arch}${triple_suffix}") 4573cab2bb3Spatrick endif() 4583cab2bb3Spatrick set(${variable} ${target} PARENT_SCOPE) 4593cab2bb3Spatrickendfunction() 4603cab2bb3Spatrick 4613cab2bb3Spatrickfunction(get_compiler_rt_install_dir arch install_dir) 4623cab2bb3Spatrick if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE) 4633cab2bb3Spatrick get_compiler_rt_target(${arch} target) 464d89ec533Spatrick set(${install_dir} ${COMPILER_RT_INSTALL_LIBRARY_DIR}/${target} PARENT_SCOPE) 4653cab2bb3Spatrick else() 466d89ec533Spatrick set(${install_dir} ${COMPILER_RT_INSTALL_LIBRARY_DIR} PARENT_SCOPE) 4673cab2bb3Spatrick endif() 4683cab2bb3Spatrickendfunction() 4693cab2bb3Spatrick 4703cab2bb3Spatrickfunction(get_compiler_rt_output_dir arch output_dir) 4713cab2bb3Spatrick if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE) 4723cab2bb3Spatrick get_compiler_rt_target(${arch} target) 473d89ec533Spatrick set(${output_dir} ${COMPILER_RT_OUTPUT_LIBRARY_DIR}/${target} PARENT_SCOPE) 4743cab2bb3Spatrick else() 475d89ec533Spatrick set(${output_dir} ${COMPILER_RT_OUTPUT_LIBRARY_DIR} PARENT_SCOPE) 4763cab2bb3Spatrick endif() 4773cab2bb3Spatrickendfunction() 4783cab2bb3Spatrick 4793cab2bb3Spatrick# compiler_rt_process_sources( 4803cab2bb3Spatrick# <OUTPUT_VAR> 4813cab2bb3Spatrick# <SOURCE_FILE> ... 4823cab2bb3Spatrick# [ADDITIONAL_HEADERS <header> ...] 4833cab2bb3Spatrick# ) 4843cab2bb3Spatrick# 4853cab2bb3Spatrick# Process the provided sources and write the list of new sources 4863cab2bb3Spatrick# into `<OUTPUT_VAR>`. 4873cab2bb3Spatrick# 4883cab2bb3Spatrick# ADDITIONAL_HEADERS - Adds the supplied header to list of sources for IDEs. 4893cab2bb3Spatrick# 4903cab2bb3Spatrick# This function is very similar to `llvm_process_sources()` but exists here 4913cab2bb3Spatrick# because we need to support standalone builds of compiler-rt. 4923cab2bb3Spatrickfunction(compiler_rt_process_sources OUTPUT_VAR) 4933cab2bb3Spatrick cmake_parse_arguments( 4943cab2bb3Spatrick ARG 4953cab2bb3Spatrick "" 4963cab2bb3Spatrick "" 4973cab2bb3Spatrick "ADDITIONAL_HEADERS" 4983cab2bb3Spatrick ${ARGN} 4993cab2bb3Spatrick ) 5003cab2bb3Spatrick set(sources ${ARG_UNPARSED_ARGUMENTS}) 5013cab2bb3Spatrick set(headers "") 5023cab2bb3Spatrick if (XCODE OR MSVC_IDE OR CMAKE_EXTRA_GENERATOR) 5033cab2bb3Spatrick # For IDEs we need to tell CMake about header files. 5043cab2bb3Spatrick # Otherwise they won't show up in UI. 5053cab2bb3Spatrick set(headers ${ARG_ADDITIONAL_HEADERS}) 5063cab2bb3Spatrick list(LENGTH headers headers_length) 5073cab2bb3Spatrick if (${headers_length} GREATER 0) 5083cab2bb3Spatrick set_source_files_properties(${headers} 5093cab2bb3Spatrick PROPERTIES HEADER_FILE_ONLY ON) 5103cab2bb3Spatrick endif() 5113cab2bb3Spatrick endif() 5123cab2bb3Spatrick set("${OUTPUT_VAR}" ${sources} ${headers} PARENT_SCOPE) 5133cab2bb3Spatrickendfunction() 5143cab2bb3Spatrick 5153cab2bb3Spatrick# Create install targets for a library and its parent component (if specified). 5163cab2bb3Spatrickfunction(add_compiler_rt_install_targets name) 5173cab2bb3Spatrick cmake_parse_arguments(ARG "" "PARENT_TARGET" "" ${ARGN}) 5183cab2bb3Spatrick 5193cab2bb3Spatrick if(ARG_PARENT_TARGET AND NOT TARGET install-${ARG_PARENT_TARGET}) 5203cab2bb3Spatrick # The parent install target specifies the parent component to scrape up 5213cab2bb3Spatrick # anything not installed by the individual install targets, and to handle 5223cab2bb3Spatrick # installation when running the multi-configuration generators. 5233cab2bb3Spatrick add_custom_target(install-${ARG_PARENT_TARGET} 5243cab2bb3Spatrick DEPENDS ${ARG_PARENT_TARGET} 5253cab2bb3Spatrick COMMAND "${CMAKE_COMMAND}" 5263cab2bb3Spatrick -DCMAKE_INSTALL_COMPONENT=${ARG_PARENT_TARGET} 5273cab2bb3Spatrick -P "${CMAKE_BINARY_DIR}/cmake_install.cmake") 5283cab2bb3Spatrick add_custom_target(install-${ARG_PARENT_TARGET}-stripped 5293cab2bb3Spatrick DEPENDS ${ARG_PARENT_TARGET} 5303cab2bb3Spatrick COMMAND "${CMAKE_COMMAND}" 5313cab2bb3Spatrick -DCMAKE_INSTALL_COMPONENT=${ARG_PARENT_TARGET} 5323cab2bb3Spatrick -DCMAKE_INSTALL_DO_STRIP=1 5333cab2bb3Spatrick -P "${CMAKE_BINARY_DIR}/cmake_install.cmake") 5343cab2bb3Spatrick set_target_properties(install-${ARG_PARENT_TARGET} PROPERTIES 5353cab2bb3Spatrick FOLDER "Compiler-RT Misc") 5363cab2bb3Spatrick set_target_properties(install-${ARG_PARENT_TARGET}-stripped PROPERTIES 5373cab2bb3Spatrick FOLDER "Compiler-RT Misc") 5383cab2bb3Spatrick add_dependencies(install-compiler-rt install-${ARG_PARENT_TARGET}) 5393cab2bb3Spatrick add_dependencies(install-compiler-rt-stripped install-${ARG_PARENT_TARGET}-stripped) 5403cab2bb3Spatrick endif() 5413cab2bb3Spatrick 5423cab2bb3Spatrick # We only want to generate per-library install targets if you aren't using 5433cab2bb3Spatrick # an IDE because the extra targets get cluttered in IDEs. 5443cab2bb3Spatrick if(NOT CMAKE_CONFIGURATION_TYPES) 5453cab2bb3Spatrick add_custom_target(install-${name} 5463cab2bb3Spatrick DEPENDS ${name} 5473cab2bb3Spatrick COMMAND "${CMAKE_COMMAND}" 5483cab2bb3Spatrick -DCMAKE_INSTALL_COMPONENT=${name} 5493cab2bb3Spatrick -P "${CMAKE_BINARY_DIR}/cmake_install.cmake") 5503cab2bb3Spatrick add_custom_target(install-${name}-stripped 5513cab2bb3Spatrick DEPENDS ${name} 5523cab2bb3Spatrick COMMAND "${CMAKE_COMMAND}" 5533cab2bb3Spatrick -DCMAKE_INSTALL_COMPONENT=${name} 5543cab2bb3Spatrick -DCMAKE_INSTALL_DO_STRIP=1 5553cab2bb3Spatrick -P "${CMAKE_BINARY_DIR}/cmake_install.cmake") 5563cab2bb3Spatrick # If you have a parent target specified, we bind the new install target 5573cab2bb3Spatrick # to the parent install target. 5583cab2bb3Spatrick if(LIB_PARENT_TARGET) 5593cab2bb3Spatrick add_dependencies(install-${LIB_PARENT_TARGET} install-${name}) 5603cab2bb3Spatrick add_dependencies(install-${LIB_PARENT_TARGET}-stripped install-${name}-stripped) 5613cab2bb3Spatrick endif() 5623cab2bb3Spatrick endif() 5633cab2bb3Spatrickendfunction() 564*810390e3Srobert 565*810390e3Srobert# Add warnings to catch potential errors that can lead to security 566*810390e3Srobert# vulnerabilities. 567*810390e3Srobertfunction(add_security_warnings out_flags macosx_sdk_version) 568*810390e3Srobert set(flags "${${out_flags}}") 569*810390e3Srobert 570*810390e3Srobert append_list_if(COMPILER_RT_HAS_ARRAY_BOUNDS_FLAG -Werror=array-bounds flags) 571*810390e3Srobert append_list_if(COMPILER_RT_HAS_UNINITIALIZED_FLAG -Werror=uninitialized flags) 572*810390e3Srobert append_list_if(COMPILER_RT_HAS_SHADOW_FLAG -Werror=shadow flags) 573*810390e3Srobert append_list_if(COMPILER_RT_HAS_EMPTY_BODY_FLAG -Werror=empty-body flags) 574*810390e3Srobert append_list_if(COMPILER_RT_HAS_SIZEOF_POINTER_MEMACCESS_FLAG -Werror=sizeof-pointer-memaccess flags) 575*810390e3Srobert append_list_if(COMPILER_RT_HAS_SIZEOF_ARRAY_ARGUMENT_FLAG -Werror=sizeof-array-argument flags) 576*810390e3Srobert append_list_if(COMPILER_RT_HAS_SUSPICIOUS_MEMACCESS_FLAG -Werror=suspicious-memaccess flags) 577*810390e3Srobert append_list_if(COMPILER_RT_HAS_BUILTIN_MEMCPY_CHK_SIZE_FLAG -Werror=builtin-memcpy-chk-size flags) 578*810390e3Srobert append_list_if(COMPILER_RT_HAS_ARRAY_BOUNDS_POINTER_ARITHMETIC_FLAG -Werror=array-bounds-pointer-arithmetic flags) 579*810390e3Srobert append_list_if(COMPILER_RT_HAS_RETURN_STACK_ADDRESS_FLAG -Werror=return-stack-address flags) 580*810390e3Srobert append_list_if(COMPILER_RT_HAS_SIZEOF_ARRAY_DECAY_FLAG -Werror=sizeof-array-decay flags) 581*810390e3Srobert append_list_if(COMPILER_RT_HAS_FORMAT_INSUFFICIENT_ARGS_FLAG -Werror=format-insufficient-args flags) 582*810390e3Srobert append_list_if(COMPILER_RT_HAS_BUILTIN_FORMAL_SECURITY_FLAG -Werror=format-security flags) 583*810390e3Srobert append_list_if(COMPILER_RT_HAS_SIZEOF_ARRAY_DIV_FLAG -Werror=sizeof-array-div) 584*810390e3Srobert append_list_if(COMPILER_RT_HAS_SIZEOF_POINTER_DIV_FLAG -Werror=sizeof-pointer-div) 585*810390e3Srobert 586*810390e3Srobert # Add -Wformat-nonliteral only if we can avoid adding the definition of 587*810390e3Srobert # eprintf. On Apple platforms, eprintf is needed only on macosx and only if 588*810390e3Srobert # its version is older than 10.7. 589*810390e3Srobert if ("${macosx_sdk_version}" VERSION_GREATER_EQUAL 10.7) 590*810390e3Srobert list(APPEND flags -Werror=format-nonliteral -DDONT_DEFINE_EPRINTF) 591*810390e3Srobert endif() 592*810390e3Srobert 593*810390e3Srobert set(${out_flags} "${flags}" PARENT_SCOPE) 594*810390e3Srobertendfunction() 595