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