brintos

brintos / llvm-project-archived public Read only

0
0
Text · 32.5 KiB · d658b70 Raw
820 lines · plain
1include(ExternalProject)2include(CompilerRTUtils)3include(HandleCompilerRT)4 5function(set_target_output_directories target output_dir)6  # For RUNTIME_OUTPUT_DIRECTORY variable, Multi-configuration generators7  # append a per-configuration subdirectory to the specified directory.8  # To avoid the appended folder, the configuration specific variable must be9  # set 'RUNTIME_OUTPUT_DIRECTORY_${CONF}':10  # RUNTIME_OUTPUT_DIRECTORY_DEBUG, RUNTIME_OUTPUT_DIRECTORY_RELEASE, ...11  if(CMAKE_CONFIGURATION_TYPES)12    foreach(build_mode ${CMAKE_CONFIGURATION_TYPES})13      string(TOUPPER "${build_mode}" CONFIG_SUFFIX)14      set_target_properties("${target}" PROPERTIES15          "ARCHIVE_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${output_dir}16          "LIBRARY_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${output_dir}17          "RUNTIME_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${output_dir})18    endforeach()19  else()20    set_target_properties("${target}" PROPERTIES21        ARCHIVE_OUTPUT_DIRECTORY ${output_dir}22        LIBRARY_OUTPUT_DIRECTORY ${output_dir}23        RUNTIME_OUTPUT_DIRECTORY ${output_dir})24  endif()25endfunction()26 27# Tries to add an "object library" target for a given list of OSs and/or28# architectures with name "<name>.<arch>" for non-Darwin platforms if29# architecture can be targeted, and "<name>.<os>" for Darwin platforms.30# add_compiler_rt_object_libraries(<name>31#                                  OS <os names>32#                                  ARCHS <architectures>33#                                  SOURCES <source files>34#                                  CFLAGS <compile flags>35#                                  DEFS <compile definitions>36#                                  DEPS <dependencies>37#                                  ADDITIONAL_HEADERS <header files>)38function(add_compiler_rt_object_libraries name)39  cmake_parse_arguments(LIB "" "" "OS;ARCHS;SOURCES;CFLAGS;DEFS;DEPS;ADDITIONAL_HEADERS"40    ${ARGN})41  set(libnames)42  if(APPLE)43    foreach(os ${LIB_OS})44      set(libname "${name}.${os}")45      set(libnames ${libnames} ${libname})46      set(extra_cflags_${libname} ${DARWIN_${os}_CFLAGS})47      list_intersect(LIB_ARCHS_${libname} DARWIN_${os}_ARCHS LIB_ARCHS)48    endforeach()49  else()50    foreach(arch ${LIB_ARCHS})51      set(libname "${name}.${arch}")52      set(libnames ${libnames} ${libname})53      set(extra_cflags_${libname} ${TARGET_${arch}_CFLAGS})54      if(NOT CAN_TARGET_${arch})55        message(FATAL_ERROR "Architecture ${arch} can't be targeted")56        return()57      endif()58    endforeach()59  endif()60 61  # Add headers to LIB_SOURCES for IDEs62  compiler_rt_process_sources(LIB_SOURCES63    ${LIB_SOURCES}64    ADDITIONAL_HEADERS65      ${LIB_ADDITIONAL_HEADERS}66  )67 68  foreach(libname ${libnames})69    add_library(${libname} OBJECT ${LIB_SOURCES})70    if(LIB_DEPS)71      add_dependencies(${libname} ${LIB_DEPS})72    endif()73 74    # Strip out -msse3 if this isn't macOS.75    set(target_flags ${LIB_CFLAGS})76    if(APPLE AND NOT "${libname}" MATCHES ".*\.osx.*")77      list(REMOVE_ITEM target_flags "-msse3")78    endif()79 80    # Build the macOS sanitizers with Mac Catalyst support.81    if (APPLE AND82        "${COMPILER_RT_ENABLE_MACCATALYST}" AND83        "${libname}" MATCHES ".*\.osx.*")84      foreach(arch ${LIB_ARCHS_${libname}})85        list(APPEND target_flags86          "SHELL:-target ${arch}-apple-macos${DARWIN_osx_MIN_VER} -darwin-target-variant ${arch}-apple-ios13.1-macabi")87      endforeach()88    endif()89 90    set_target_compile_flags(${libname}91      ${extra_cflags_${libname}} ${target_flags})92    set_property(TARGET ${libname} APPEND PROPERTY93      COMPILE_DEFINITIONS ${LIB_DEFS})94    set_target_properties(${libname} PROPERTIES FOLDER "Compiler-RT/Libraries")95    if(APPLE)96      set_target_properties(${libname} PROPERTIES97        OSX_ARCHITECTURES "${LIB_ARCHS_${libname}}")98    endif()99  endforeach()100endfunction()101 102# Takes a list of object library targets, and a suffix and appends the proper103# TARGET_OBJECTS string to the output variable.104# format_object_libs(<output> <suffix> ...)105macro(format_object_libs output suffix)106  foreach(lib ${ARGN})107    list(APPEND ${output} $<TARGET_OBJECTS:${lib}.${suffix}>)108  endforeach()109endmacro()110 111function(add_compiler_rt_component name)112  add_custom_target(${name})113  set_target_properties(${name} PROPERTIES FOLDER "Compiler-RT/Components")114  if(COMMAND runtime_register_component)115    runtime_register_component(${name})116  endif()117  add_dependencies(compiler-rt ${name})118endfunction()119 120macro(set_output_name output name arch)121  if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR)122    set(${output} ${name})123  else()124    if(ANDROID AND ${arch} STREQUAL "i386")125      set(${output} "${name}-i686${COMPILER_RT_OS_SUFFIX}")126    elseif(NOT "${arch}" MATCHES "^arm64" AND "${arch}" MATCHES "^arm")127      if(COMPILER_RT_DEFAULT_TARGET_ONLY)128        set(triple "${COMPILER_RT_DEFAULT_TARGET_TRIPLE}")129      else()130        set(triple "${LLVM_TARGET_TRIPLE}")131      endif()132      # Except for baremetal, when using arch-suffixed runtime library names,133      # clang only looks for libraries named "arm" or "armhf", see134      # getArchNameForCompilerRTLib in clang. Therefore, try to inspect both135      # the arch name and the triple if it seems like we're building an armhf136      # target.137      if (COMPILER_RT_BAREMETAL_BUILD)138        set(${output} "${name}-${arch}${COMPILER_RT_OS_SUFFIX}")139      elseif ("${arch}" MATCHES "hf$" OR "${triple}" MATCHES "hf$")140        set(${output} "${name}-armhf${COMPILER_RT_OS_SUFFIX}")141      else()142        set(${output} "${name}-arm${COMPILER_RT_OS_SUFFIX}")143      endif()144    else()145      set(${output} "${name}-${arch}${COMPILER_RT_OS_SUFFIX}")146    endif()147  endif()148endmacro()149 150# Adds static or shared runtime for a list of architectures and operating151# systems and puts it in the proper directory in the build and install trees.152# add_compiler_rt_runtime(<name>153#                         {OBJECT|STATIC|SHARED|MODULE}154#                         ARCHS <architectures>155#                         OS <os list>156#                         SOURCES <source files>157#                         CFLAGS <compile flags>158#                         LINK_FLAGS <linker flags>159#                         DEFS <compile definitions>160#                         DEPS <dependencies>161#                         LINK_LIBS <linked libraries> (only for shared library)162#                         OBJECT_LIBS <object libraries to use as sources>163#                         PARENT_TARGET <convenience parent target>164#                         ADDITIONAL_HEADERS <header files>165#                         C_STANDARD <version>166#                         CXX_STANDARD <version>)167function(add_compiler_rt_runtime name type)168  if(NOT type MATCHES "^(OBJECT|STATIC|SHARED|MODULE)$")169    message(FATAL_ERROR170            "type argument must be OBJECT, STATIC, SHARED or MODULE")171    return()172  endif()173  cmake_parse_arguments(LIB174    ""175    "PARENT_TARGET;C_STANDARD;CXX_STANDARD"176    "OS;ARCHS;SOURCES;CFLAGS;LINK_FLAGS;DEFS;DEPS;LINK_LIBS;OBJECT_LIBS;ADDITIONAL_HEADERS"177    ${ARGN})178  set(libnames)179  # Until we support this some other way, build compiler-rt runtime without LTO180  # to allow non-LTO projects to link with it. GPU targets can currently only be181  # distributed as LLVM-IR and ignore this.182  if(COMPILER_RT_HAS_FNO_LTO_FLAG AND NOT COMPILER_RT_GPU_BUILD)183    set(NO_LTO_FLAGS "-fno-lto")184  else()185    set(NO_LTO_FLAGS "")186  endif()187 188  # By default do not instrument or use profdata for compiler-rt.189  set(NO_PGO_FLAGS "")190  if(NOT COMPILER_RT_ENABLE_PGO)191    if(LLVM_PROFDATA_FILE AND COMPILER_RT_HAS_FNO_PROFILE_INSTR_USE_FLAG)192      list(APPEND NO_PGO_FLAGS "-fno-profile-instr-use")193    endif()194    if(LLVM_BUILD_INSTRUMENTED MATCHES IR AND COMPILER_RT_HAS_FNO_PROFILE_GENERATE_FLAG)195      list(APPEND NO_PGO_FLAGS "-fno-profile-generate")196    elseif((LLVM_BUILD_INSTRUMENTED OR LLVM_BUILD_INSTRUMENTED_COVERAGE) AND COMPILER_RT_HAS_FNO_PROFILE_INSTR_GENERATE_FLAG)197      list(APPEND NO_PGO_FLAGS "-fno-profile-instr-generate")198      if(LLVM_BUILD_INSTRUMENTED_COVERAGE AND COMPILER_RT_HAS_FNO_COVERAGE_MAPPING_FLAG)199        list(APPEND NO_PGO_FLAGS "-fno-coverage-mapping")200      endif()201    endif()202  endif()203 204  list(LENGTH LIB_SOURCES LIB_SOURCES_LENGTH)205  if (${LIB_SOURCES_LENGTH} GREATER 0)206    # Add headers to LIB_SOURCES for IDEs. It doesn't make sense to207    # do this for a runtime library that only consists of OBJECT208    # libraries, so only add the headers when source files are present.209    compiler_rt_process_sources(LIB_SOURCES210      ${LIB_SOURCES}211      ADDITIONAL_HEADERS212        ${LIB_ADDITIONAL_HEADERS}213    )214  endif()215 216  if(APPLE)217    foreach(os ${LIB_OS})218      # Strip out -msse3 if this isn't macOS.219      list(LENGTH LIB_CFLAGS HAS_EXTRA_CFLAGS)220      if(HAS_EXTRA_CFLAGS AND NOT "${os}" MATCHES "^(osx)$")221        list(REMOVE_ITEM LIB_CFLAGS "-msse3")222      endif()223      if(type STREQUAL "STATIC")224        set(libname "${name}_${os}")225      else()226        set(libname "${name}_${os}_dynamic")227        set(extra_link_flags_${libname} ${DARWIN_${os}_LINK_FLAGS} ${LIB_LINK_FLAGS})228      endif()229      list_intersect(LIB_ARCHS_${libname} DARWIN_${os}_ARCHS LIB_ARCHS)230      if(LIB_ARCHS_${libname})231        list(APPEND libnames ${libname})232        set(extra_cflags_${libname} ${DARWIN_${os}_CFLAGS} ${NO_LTO_FLAGS} ${NO_PGO_FLAGS} ${LIB_CFLAGS})233        set(output_name_${libname} ${libname}${COMPILER_RT_OS_SUFFIX})234        set(sources_${libname} ${LIB_SOURCES})235        format_object_libs(sources_${libname} ${os} ${LIB_OBJECT_LIBS})236        get_compiler_rt_output_dir(${COMPILER_RT_DEFAULT_TARGET_ARCH} output_dir_${libname})237        get_compiler_rt_install_dir(${COMPILER_RT_DEFAULT_TARGET_ARCH} install_dir_${libname})238      endif()239 240      # Build the macOS sanitizers with Mac Catalyst support.241      if ("${COMPILER_RT_ENABLE_MACCATALYST}" AND242          "${os}" MATCHES "^(osx)$")243        foreach(arch ${LIB_ARCHS_${libname}})244          list(APPEND extra_cflags_${libname}245            "SHELL:-target ${arch}-apple-macos${DARWIN_osx_MIN_VER} -darwin-target-variant ${arch}-apple-ios13.1-macabi")246          list(APPEND extra_link_flags_${libname}247            "SHELL:-target ${arch}-apple-macos${DARWIN_osx_MIN_VER} -darwin-target-variant ${arch}-apple-ios13.1-macabi")248        endforeach()249      endif()250    endforeach()251  else()252    foreach(arch ${LIB_ARCHS})253      if(NOT CAN_TARGET_${arch})254        message(FATAL_ERROR "Architecture ${arch} can't be targeted")255        return()256      endif()257      if(type STREQUAL "OBJECT")258        set(libname "${name}-${arch}")259        set_output_name(output_name_${libname} ${name}${COMPILER_RT_OS_SUFFIX} ${arch})260      elseif(type STREQUAL "STATIC")261        set(libname "${name}-${arch}")262        set_output_name(output_name_${libname} ${name} ${arch})263      else()264        set(libname "${name}-dynamic-${arch}")265        set(extra_cflags_${libname} ${TARGET_${arch}_CFLAGS} ${LIB_CFLAGS})266        set(extra_link_flags_${libname} ${TARGET_${arch}_LINK_FLAGS} ${LIB_LINK_FLAGS})267        if(WIN32)268          set_output_name(output_name_${libname} ${name}_dynamic ${arch})269        else()270          set_output_name(output_name_${libname} ${name} ${arch})271        endif()272      endif()273      if(COMPILER_RT_USE_BUILTINS_LIBRARY AND NOT type STREQUAL "OBJECT" AND274         NOT name STREQUAL "clang_rt.builtins")275        get_compiler_rt_target(${arch} target)276        find_compiler_rt_library(builtins builtins_${libname} TARGET ${target})277        if(builtins_${libname} STREQUAL "NOTFOUND")278          message(FATAL_ERROR "Cannot find builtins library for the target architecture")279        endif()280      endif()281      set(sources_${libname} ${LIB_SOURCES})282      format_object_libs(sources_${libname} ${arch} ${LIB_OBJECT_LIBS})283      set(libnames ${libnames} ${libname})284      set(extra_cflags_${libname} ${TARGET_${arch}_CFLAGS} ${NO_LTO_FLAGS} ${NO_PGO_FLAGS} ${LIB_CFLAGS})285      get_compiler_rt_output_dir(${arch} output_dir_${libname})286      get_compiler_rt_install_dir(${arch} install_dir_${libname})287    endforeach()288  endif()289 290  if(NOT libnames)291    return()292  endif()293 294  if(LIB_PARENT_TARGET)295    # If the parent targets aren't created we should create them296    if(NOT TARGET ${LIB_PARENT_TARGET})297      add_custom_target(${LIB_PARENT_TARGET})298      set_target_properties(${LIB_PARENT_TARGET} PROPERTIES299                            FOLDER "Compiler-RT/Runtimes")300    endif()301  endif()302 303  foreach(libname ${libnames})304    # If you are using a multi-configuration generator we don't generate305    # per-library install rules, so we fall back to the parent target COMPONENT306    if(CMAKE_CONFIGURATION_TYPES AND LIB_PARENT_TARGET)307      set(COMPONENT_OPTION COMPONENT ${LIB_PARENT_TARGET})308    else()309      set(COMPONENT_OPTION COMPONENT ${libname})310    endif()311 312    if(type STREQUAL "SHARED")313      list(APPEND LIB_DEFS COMPILER_RT_SHARED_LIB)314    endif()315 316    if(type STREQUAL "OBJECT")317      if(CMAKE_C_COMPILER_ID MATCHES Clang AND CMAKE_C_COMPILER_TARGET)318        list(APPEND extra_cflags_${libname} "--target=${CMAKE_C_COMPILER_TARGET}")319      endif()320      if(CMAKE_SYSROOT)321        list(APPEND extra_cflags_${libname} "--sysroot=${CMAKE_SYSROOT}")322      endif()323      string(REPLACE ";" " " extra_cflags_${libname} "${extra_cflags_${libname}}")324      string(REGEX MATCHALL "<[A-Za-z0-9_]*>" substitutions325             ${CMAKE_C_COMPILE_OBJECT})326      set(compile_command_${libname} "${CMAKE_C_COMPILE_OBJECT}")327 328      set(output_file_${libname} ${output_name_${libname}}${CMAKE_C_OUTPUT_EXTENSION})329      foreach(substitution ${substitutions})330        if(substitution STREQUAL "<CMAKE_C_COMPILER>")331          string(REPLACE "<CMAKE_C_COMPILER>" "${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1}"332                 compile_command_${libname} ${compile_command_${libname}})333        elseif(substitution STREQUAL "<OBJECT>")334          string(REPLACE "<OBJECT>" "${output_dir_${libname}}/${output_file_${libname}}"335                 compile_command_${libname} ${compile_command_${libname}})336        elseif(substitution STREQUAL "<SOURCE>")337          string(REPLACE "<SOURCE>" "${sources_${libname}}"338                 compile_command_${libname} ${compile_command_${libname}})339        elseif(substitution STREQUAL "<FLAGS>")340          string(REPLACE "<FLAGS>" "${CMAKE_C_FLAGS} ${extra_cflags_${libname}}"341                 compile_command_${libname} ${compile_command_${libname}})342        else()343          string(REPLACE "${substitution}" "" compile_command_${libname}344                 ${compile_command_${libname}})345        endif()346      endforeach()347      separate_arguments(compile_command_${libname})348      add_custom_command(349          OUTPUT ${output_dir_${libname}}/${output_file_${libname}}350          COMMAND ${compile_command_${libname}}351          DEPENDS ${sources_${libname}}352          COMMENT "Building C object ${output_file_${libname}}")353      add_custom_target(${libname} DEPENDS ${output_dir_${libname}}/${output_file_${libname}})354      set_target_properties(${libname} PROPERTIES FOLDER "Compiler-RT/Codegenning")355      install(FILES ${output_dir_${libname}}/${output_file_${libname}}356        DESTINATION ${install_dir_${libname}}357        ${COMPONENT_OPTION})358    else()359      add_library(${libname} ${type} ${sources_${libname}})360      set_target_compile_flags(${libname} ${extra_cflags_${libname}})361      set_target_link_flags(${libname} ${extra_link_flags_${libname}})362      set_property(TARGET ${libname} APPEND PROPERTY363                   COMPILE_DEFINITIONS ${LIB_DEFS})364      if(LIB_C_STANDARD)365        set_property(TARGET ${libname} PROPERTY C_STANDARD ${LIB_C_STANDARD})366      endif()367      if(LIB_CXX_STANDARD)368        set_property(TARGET ${libname} PROPERTY CXX_STANDARD ${LIB_CXX_STANDARD})369      endif()370      set_target_output_directories(${libname} ${output_dir_${libname}})371      install(TARGETS ${libname}372        ARCHIVE DESTINATION ${install_dir_${libname}}373                ${COMPONENT_OPTION}374        LIBRARY DESTINATION ${install_dir_${libname}}375                ${COMPONENT_OPTION}376        RUNTIME DESTINATION ${install_dir_${libname}}377                ${COMPONENT_OPTION})378    endif()379    if(LIB_DEPS)380      add_dependencies(${libname} ${LIB_DEPS})381    endif()382    set_target_properties(${libname} PROPERTIES383        OUTPUT_NAME ${output_name_${libname}}384        FOLDER "Compiler-RT/Runtimes")385    if(LIB_LINK_LIBS)386      target_link_libraries(${libname} PRIVATE ${LIB_LINK_LIBS})387    endif()388    if(builtins_${libname})389      target_link_libraries(${libname} PRIVATE ${builtins_${libname}})390    endif()391    if(${type} STREQUAL "SHARED")392      if(APPLE OR WIN32)393        set_property(TARGET ${libname} PROPERTY BUILD_WITH_INSTALL_RPATH ON)394      endif()395      if(WIN32 AND NOT CYGWIN AND NOT MINGW)396        set_target_properties(${libname} PROPERTIES IMPORT_PREFIX "")397        set_target_properties(${libname} PROPERTIES IMPORT_SUFFIX ".lib")398      endif()399      find_program(CODESIGN codesign)400      if (APPLE AND NOT CMAKE_LINKER MATCHES ".*lld.*" AND CODESIGN)401        # Apple's linker signs the resulting dylib with an ad-hoc code signature in402        # most situations, except:403        # 1. Versions of ld64 prior to ld64-609 in Xcode 12 predate this behavior.404        # 2. Apple's new linker does not when building with `-darwin-target-variant`405        #    to support macOS Catalyst.406        #407        # Explicitly re-signing the dylib works around both of these issues. The408        # signature is marked as `linker-signed` when that is supported so that it409        # behaves as expected when processed by subsequent tooling.410        #411        # Detect whether `codesign` supports `-o linker-signed` by passing it as an412        # argument and looking for `invalid argument "linker-signed"` in its output.413        # FIXME: Remove this once all supported toolchains support `-o linker-signed`.414        execute_process(415          COMMAND sh -c "${CODESIGN} -f -s - -o linker-signed this-does-not-exist 2>&1 | grep -q linker-signed"416          RESULT_VARIABLE CODESIGN_SUPPORTS_LINKER_SIGNED417        )418 419        set(EXTRA_CODESIGN_ARGUMENTS)420        if (CODESIGN_SUPPORTS_LINKER_SIGNED)421          list(APPEND EXTRA_CODESIGN_ARGUMENTS -o linker-signed)422        endif()423 424        add_custom_command(TARGET ${libname}425          POST_BUILD426          COMMAND ${CODESIGN} --sign - ${EXTRA_CODESIGN_ARGUMENTS} $<TARGET_FILE:${libname}>427          WORKING_DIRECTORY ${COMPILER_RT_OUTPUT_LIBRARY_DIR}428          COMMAND_EXPAND_LISTS429        )430      endif()431    endif()432 433    set(parent_target_arg)434    if(LIB_PARENT_TARGET)435      set(parent_target_arg PARENT_TARGET ${LIB_PARENT_TARGET})436    endif()437    add_compiler_rt_install_targets(${libname} ${parent_target_arg})438 439    if(APPLE)440      set_target_properties(${libname} PROPERTIES441      OSX_ARCHITECTURES "${LIB_ARCHS_${libname}}")442    endif()443 444    if(type STREQUAL "SHARED")445      rt_externalize_debuginfo(${libname})446    endif()447  endforeach()448  if(LIB_PARENT_TARGET)449    add_dependencies(${LIB_PARENT_TARGET} ${libnames})450  endif()451endfunction()452 453# Compile and register compiler-rt tests.454# generate_compiler_rt_tests(<output object files> <test_suite> <test_name>455#                           <test architecture>456#                           KIND <custom prefix>457#                           SUBDIR <subdirectory for testing binary>458#                           SOURCES <sources to compile>459#                           RUNTIME <tests runtime to link in>460#                           CFLAGS <compile-time flags>461#                           COMPILE_DEPS <compile-time dependencies>462#                           DEPS <dependencies>463#                           LINK_FLAGS <flags to use during linking>464# )465function(generate_compiler_rt_tests test_objects test_suite testname arch)466  cmake_parse_arguments(TEST "" "KIND;RUNTIME;SUBDIR"467    "SOURCES;COMPILE_DEPS;DEPS;CFLAGS;LINK_FLAGS" ${ARGN})468 469  foreach(source ${TEST_SOURCES})470    sanitizer_test_compile(471      "${test_objects}" "${source}" "${arch}"472      KIND ${TEST_KIND}473      COMPILE_DEPS ${TEST_COMPILE_DEPS}474      DEPS ${TEST_DEPS}475      CFLAGS ${TEST_CFLAGS}476      )477  endforeach()478 479  set(TEST_DEPS ${${test_objects}})480 481  if(NOT "${TEST_RUNTIME}" STREQUAL "")482    list(APPEND TEST_DEPS ${TEST_RUNTIME})483    list(APPEND "${test_objects}" $<TARGET_FILE:${TEST_RUNTIME}>)484  endif()485 486  add_compiler_rt_test(${test_suite} "${testname}" "${arch}"487    SUBDIR ${TEST_SUBDIR}488    OBJECTS ${${test_objects}}489    DEPS ${TEST_DEPS}490    LINK_FLAGS ${TEST_LINK_FLAGS}491    )492  set("${test_objects}" "${${test_objects}}" PARENT_SCOPE)493endfunction()494 495# Link objects into a single executable with COMPILER_RT_TEST_COMPILER,496# using specified link flags. Make executable a part of provided497# test_suite.498# add_compiler_rt_test(<test_suite> <test_name> <arch>499#                      SUBDIR <subdirectory for binary>500#                      OBJECTS <object files>501#                      DEPS <deps (e.g. runtime libs)>502#                      LINK_FLAGS <link flags>)503function(add_compiler_rt_test test_suite test_name arch)504  cmake_parse_arguments(TEST "" "SUBDIR" "OBJECTS;DEPS;LINK_FLAGS" "" ${ARGN})505  set(output_dir ${CMAKE_CURRENT_BINARY_DIR})506  if(TEST_SUBDIR)507    set(output_dir "${output_dir}/${TEST_SUBDIR}")508  endif()509  set(output_dir "${output_dir}/${CMAKE_CFG_INTDIR}")510  file(MAKE_DIRECTORY "${output_dir}")511  set(output_bin "${output_dir}/${test_name}")512  if(WIN32)513    set(output_bin "${output_bin}.exe")514  endif()515 516  # Use host compiler in a standalone build, and just-built Clang otherwise.517  if(NOT COMPILER_RT_STANDALONE_BUILD)518    list(APPEND TEST_DEPS clang)519  endif()520 521  get_target_flags_for_arch(${arch} TARGET_LINK_FLAGS)522  list(APPEND TEST_LINK_FLAGS ${TARGET_LINK_FLAGS})523 524  # If we're not on MSVC, include the linker flags from CMAKE but override them525  # with the provided link flags. This ensures that flags which are required to526  # link programs at all are included, but the changes needed for the test527  # trump. With MSVC we can't do that because CMake is set up to run link.exe528  # when linking, not the compiler. Here, we hack it to use the compiler529  # because we want to use -fsanitize flags.530 531  # Only add CMAKE_EXE_LINKER_FLAGS when in a standalone build.532  # Or else CMAKE_EXE_LINKER_FLAGS contains flags for build compiler of Clang/llvm.533  # This might not be the same as what the COMPILER_RT_TEST_COMPILER supports.534  # eg: the build compiler use lld linker and we build clang with default ld linker535  # then to be tested clang will complain about lld options like --color-diagnostics.536  if(NOT MSVC AND COMPILER_RT_STANDALONE_BUILD)537    set(TEST_LINK_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${TEST_LINK_FLAGS}")538    separate_arguments(TEST_LINK_FLAGS)539  endif()540  if(NOT COMPILER_RT_STANDALONE_BUILD AND COMPILER_RT_HAS_LLD AND "lld" IN_LIST LLVM_ENABLE_PROJECTS)541    # CMAKE_EXE_LINKER_FLAGS may contain -fuse=lld542    # FIXME: -DLLVM_ENABLE_LLD=ON and -DLLVM_ENABLE_PROJECTS without lld case.543    list(APPEND TEST_DEPS lld)544  endif()545  add_custom_command(546    OUTPUT "${output_bin}"547    COMMAND ${COMPILER_RT_TEST_CXX_COMPILER} ${TEST_OBJECTS} -o "${output_bin}"548            ${TEST_LINK_FLAGS}549    DEPENDS ${TEST_DEPS}550    )551  add_custom_target(T${test_name} DEPENDS "${output_bin}")552  set_target_properties(T${test_name} PROPERTIES FOLDER "Compiler-RT/Tests")553 554  # Make the test suite depend on the binary.555  add_dependencies(${test_suite} T${test_name})556endfunction()557 558macro(add_compiler_rt_resource_file target_name file_name component)559  set(src_file "${CMAKE_CURRENT_SOURCE_DIR}/${file_name}")560  set(dst_file "${COMPILER_RT_OUTPUT_DIR}/share/${file_name}")561  add_custom_command(OUTPUT ${dst_file}562    DEPENDS ${src_file}563    COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src_file} ${dst_file}564    COMMENT "Copying ${file_name}...")565  add_custom_target(${target_name} DEPENDS ${dst_file})566  # Install in Clang resource directory.567  install(FILES ${file_name}568    DESTINATION ${COMPILER_RT_INSTALL_DATA_DIR}569    COMPONENT ${component})570  add_dependencies(${component} ${target_name})571 572  set_target_properties(${target_name} PROPERTIES FOLDER "Compiler-RT/Resources")573endmacro()574 575macro(add_compiler_rt_script name)576  set(dst ${COMPILER_RT_EXEC_OUTPUT_DIR}/${name})577  set(src ${CMAKE_CURRENT_SOURCE_DIR}/${name})578  add_custom_command(OUTPUT ${dst}579    DEPENDS ${src}580    COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst}581    COMMENT "Copying ${name}...")582  add_custom_target(${name} DEPENDS ${dst})583  install(FILES ${dst}584    PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE585    DESTINATION ${COMPILER_RT_INSTALL_BINARY_DIR})586endmacro(add_compiler_rt_script src name)587 588 589macro(add_compiler_rt_cfg target_name file_name component arch)590  set(src_file "${CMAKE_CURRENT_SOURCE_DIR}/AIX/${file_name}")591  get_compiler_rt_output_dir(${arch} output_dir)592  set(dst_file "${output_dir}/${file_name}")593  add_custom_command(OUTPUT ${dst_file}594    DEPENDS ${src_file}595    COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src_file} ${dst_file}596    COMMENT "Copying ${file_name}...")597  add_custom_target(${target_name} DEPENDS ${dst_file})598  install(FILES ${file_name}599    DESTINATION ${COMPILER_RT_INSTALL_LIBRARY_DIR}600    COMPONENT ${component})601  add_dependencies(${component} ${target_name})602 603  set_target_properties(${target_name} PROPERTIES FOLDER "Compiler-RT Misc")604endmacro()605 606# Builds custom version of libc++ and installs it in <prefix>.607# Can be used to build sanitized versions of libc++ for running unit tests.608# add_custom_libcxx(<name> <prefix>609#                   DEPS <list of build deps>610#                   CFLAGS <list of compile flags>611#                   USE_TOOLCHAIN)612macro(add_custom_libcxx name prefix)613  if(NOT COMPILER_RT_LIBCXX_PATH)614    message(FATAL_ERROR "libcxx not found!")615  endif()616  if(NOT COMPILER_RT_LIBCXXABI_PATH)617    message(FATAL_ERROR "libcxxabi not found!")618  endif()619 620  cmake_parse_arguments(LIBCXX "USE_TOOLCHAIN" "" "DEPS;CFLAGS;CMAKE_ARGS" ${ARGN})621 622  if(LIBCXX_USE_TOOLCHAIN)623    set(compiler_args -DCMAKE_C_COMPILER=${COMPILER_RT_TEST_COMPILER}624                      -DCMAKE_CXX_COMPILER=${COMPILER_RT_TEST_CXX_COMPILER})625    if(NOT COMPILER_RT_STANDALONE_BUILD AND NOT LLVM_RUNTIMES_BUILD)626      set(toolchain_deps $<TARGET_FILE:clang>)627      set(force_deps DEPENDS $<TARGET_FILE:clang>)628    endif()629  else()630    set(compiler_args -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}631                      -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER})632  endif()633 634  add_custom_target(${name}-clear635    COMMAND ${CMAKE_COMMAND} -E remove_directory ${prefix}636    COMMENT "Clobbering ${name} build directories"637    USES_TERMINAL638    )639  set_target_properties(${name}-clear PROPERTIES FOLDER "Compiler-RT/Metatargets")640 641  add_custom_command(642    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp643    DEPENDS ${LIBCXX_DEPS} ${toolchain_deps}644    COMMAND ${CMAKE_COMMAND} -E touch ${prefix}/CMakeCache.txt645    COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp646    COMMENT "Clobbering bootstrap build directories"647    )648 649  add_custom_target(${name}-clobber650    DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp)651  set_target_properties(${name}-clobber PROPERTIES FOLDER "Compiler-RT/Metatargets")652 653  set(PASSTHROUGH_VARIABLES654    ANDROID655    ANDROID_NATIVE_API_LEVEL656    CMAKE_C_COMPILER_TARGET657    CMAKE_CXX_COMPILER_TARGET658    CMAKE_SHARED_LINKER_FLAGS659    CMAKE_MODULE_LINKER_FLAGS660    CMAKE_EXE_LINKER_FLAGS661    CMAKE_INSTALL_PREFIX662    CMAKE_MAKE_PROGRAM663    CMAKE_LINKER664    CMAKE_AR665    CMAKE_RANLIB666    CMAKE_NM667    CMAKE_OBJCOPY668    CMAKE_OBJDUMP669    CMAKE_STRIP670    CMAKE_READELF671    CMAKE_SYSROOT672    CMAKE_TOOLCHAIN_FILE673    LIBCXX_HAS_MUSL_LIBC674    LIBCXX_HAS_GCC_S_LIB675    LIBCXX_HAS_PTHREAD_LIB676    LIBCXX_HAS_RT_LIB677    LIBCXX_USE_COMPILER_RT678    LIBCXXABI_HAS_PTHREAD_LIB679    PYTHON_EXECUTABLE680    Python3_EXECUTABLE681    Python2_EXECUTABLE682    CMAKE_SYSTEM_NAME)683  foreach(variable ${PASSTHROUGH_VARIABLES})684    get_property(is_value_set CACHE ${variable} PROPERTY VALUE SET)685    if(${is_value_set})686      get_property(value CACHE ${variable} PROPERTY VALUE)687      list(APPEND CMAKE_PASSTHROUGH_VARIABLES -D${variable}=${value})688    endif()689  endforeach()690 691  string(REPLACE ";" " " LIBCXX_C_FLAGS "${LIBCXX_CFLAGS}")692  get_property(C_FLAGS CACHE CMAKE_C_FLAGS PROPERTY VALUE)693  set(LIBCXX_C_FLAGS "${LIBCXX_C_FLAGS} ${C_FLAGS}")694 695  string(REPLACE ";" " " LIBCXX_CXX_FLAGS "${LIBCXX_CFLAGS}")696  get_property(CXX_FLAGS CACHE CMAKE_CXX_FLAGS PROPERTY VALUE)697  set(LIBCXX_CXX_FLAGS "${LIBCXX_CXX_FLAGS} ${CXX_FLAGS}")698 699  if(CMAKE_VERBOSE_MAKEFILE)700    set(verbose -DCMAKE_VERBOSE_MAKEFILE=ON)701  endif()702 703  ExternalProject_Add(${name}704    DEPENDS ${name}-clobber ${LIBCXX_DEPS}705    PREFIX ${prefix}706    SOURCE_DIR ${LLVM_MAIN_SRC_DIR}/../runtimes707    BINARY_DIR ${prefix}/build708    CMAKE_ARGS ${CMAKE_PASSTHROUGH_VARIABLES}709               ${compiler_args}710               ${verbose}711               -DCMAKE_C_FLAGS=${LIBCXX_C_FLAGS}712               -DCMAKE_CXX_FLAGS=${LIBCXX_CXX_FLAGS}713               -DCMAKE_BUILD_TYPE=Release714               -DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>715               -DCMAKE_INSTALL_MESSAGE=LAZY716               -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY717               -DLLVM_ENABLE_RUNTIMES=libcxx|libcxxabi718               -DLIBCXXABI_USE_LLVM_UNWINDER=OFF719               -DLIBCXXABI_ENABLE_SHARED=OFF720               -DLIBCXXABI_HERMETIC_STATIC_LIBRARY=ON721               -DLIBCXXABI_INCLUDE_TESTS=OFF722               -DLIBCXX_CXX_ABI=libcxxabi723               -DLIBCXX_ENABLE_SHARED=OFF724               -DLIBCXX_HERMETIC_STATIC_LIBRARY=ON725               -DLIBCXX_INCLUDE_BENCHMARKS=OFF726               -DLIBCXX_INCLUDE_TESTS=OFF727               -DLIBCXX_ENABLE_STATIC_ABI_LIBRARY=ON728               -DLLVM_INCLUDE_TESTS=OFF729               -DLLVM_INCLUDE_DOCS=OFF730               ${LIBCXX_CMAKE_ARGS}731    STEP_TARGETS configure build732    BUILD_ALWAYS 1733    USES_TERMINAL_CONFIGURE 1734    USES_TERMINAL_BUILD 1735    USES_TERMINAL_INSTALL 1736    LIST_SEPARATOR |737    EXCLUDE_FROM_ALL TRUE738    )739 740  # Once we depend on CMake 3.26, we can use the INSTALL_BYPRODUCTS argument741  # instead of having to fall back to ExternalProject_Add_Step()742  # Note: We can't use the normal name "install" here since that interferes743  # with the default ExternalProject_Add() logic and causes errors.744  ExternalProject_Add_Step(${name} install-cmake326-workaround745    # Ensure that DESTDIR=... set in the out environment does not affect this746    # target (we always need to install to the build directory).747    COMMAND env DESTDIR= ${CMAKE_COMMAND} --build ${prefix}/build --target install748    COMMENT "Installing ${name}..."749    BYPRODUCTS "${prefix}/lib/libc++.a" "${prefix}/lib/libc++abi.a"750    DEPENDEES build751    EXCLUDE_FROM_MAIN 1752    USES_TERMINAL 1753  )754  ExternalProject_Add_StepTargets(${name} install-cmake326-workaround)755 756  if (CMAKE_GENERATOR MATCHES "Make")757    set(run_clean "$(MAKE)" "-C" "${prefix}" "clean")758  else()759    set(run_clean ${CMAKE_COMMAND} --build ${prefix} --target clean760                                   --config "$<CONFIG>")761  endif()762 763  ExternalProject_Add_Step(${name} clean764    COMMAND ${run_clean}765    COMMENT "Cleaning ${name}..."766    DEPENDEES configure767    ${force_deps}768    WORKING_DIRECTORY ${prefix}769    EXCLUDE_FROM_MAIN 1770    USES_TERMINAL 1771    )772  ExternalProject_Add_StepTargets(${name} clean)773 774  if(LIBCXX_USE_TOOLCHAIN)775    add_dependencies(${name}-clean ${name}-clobber)776    set_target_properties(${name}-clean PROPERTIES777      SOURCES ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp)778  endif()779endmacro()780 781function(rt_externalize_debuginfo name)782  if(NOT COMPILER_RT_EXTERNALIZE_DEBUGINFO)783    return()784  endif()785 786  if(NOT COMPILER_RT_EXTERNALIZE_DEBUGINFO_SKIP_STRIP)787    set(strip_command COMMAND xcrun strip -Sl $<TARGET_FILE:${name}>)788  endif()789 790  if(APPLE)791    if(CMAKE_CXX_FLAGS MATCHES "-flto"792      OR CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE} MATCHES "-flto")793 794      set(lto_object ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${name}-lto.o)795      set_property(TARGET ${name} APPEND_STRING PROPERTY796        LINK_FLAGS " -Wl,-object_path_lto -Wl,${lto_object}")797    endif()798    add_custom_command(TARGET ${name} POST_BUILD799      COMMAND xcrun dsymutil $<TARGET_FILE:${name}>800      ${strip_command})801  else()802    message(FATAL_ERROR "COMPILER_RT_EXTERNALIZE_DEBUGINFO isn't implemented for non-darwin platforms!")803  endif()804endfunction()805 806 807# Configure lit configuration files, including compiler-rt specific variables.808function(configure_compiler_rt_lit_site_cfg input output)809  set_llvm_build_mode()810 811  get_compiler_rt_output_dir(${COMPILER_RT_DEFAULT_TARGET_ARCH} output_dir)812 813  string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} COMPILER_RT_RESOLVED_TEST_COMPILER ${COMPILER_RT_TEST_COMPILER})814  string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} COMPILER_RT_RESOLVED_OUTPUT_DIR ${COMPILER_RT_OUTPUT_DIR})815  string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} COMPILER_RT_RESOLVED_EXEC_OUTPUT_DIR ${COMPILER_RT_EXEC_OUTPUT_DIR})816  string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} COMPILER_RT_RESOLVED_LIBRARY_OUTPUT_DIR ${output_dir})817 818  configure_lit_site_cfg(${input} ${output})819endfunction()820