1include(ExternalProject) 2include(CompilerRTUtils) 3include(HandleCompilerRT) 4 5function(set_target_output_directories target output_dir) 6 # For RUNTIME_OUTPUT_DIRECTORY variable, Multi-configuration generators 7 # append a per-configuration subdirectory to the specified directory. 8 # To avoid the appended folder, the configuration specific variable must be 9 # 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}" PROPERTIES 15 "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}" PROPERTIES 21 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/or 28# architectures with name "<name>.<arch>" for non-Darwin platforms if 29# 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 IDEs 62 compiler_rt_process_sources(LIB_SOURCES 63 ${LIB_SOURCES} 64 ADDITIONAL_HEADERS 65 ${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 AND 82 "${COMPILER_RT_ENABLE_MACCATALYST}" AND 83 "${libname}" MATCHES ".*\.osx.*") 84 foreach(arch ${LIB_ARCHS_${libname}}) 85 list(APPEND target_flags 86 "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 PROPERTY 93 COMPILE_DEFINITIONS ${LIB_DEFS}) 94 set_target_properties(${libname} PROPERTIES FOLDER "Compiler-RT/Libraries") 95 if(APPLE) 96 set_target_properties(${libname} PROPERTIES 97 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 proper 103# 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("${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", see 134 # getArchNameForCompilerRTLib in clang. Therefore, try to inspect both 135 # the arch name and the triple if it seems like we're building an armhf 136 # 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 operating 151# 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# EXTENSIONS <boolean>) 166function(add_compiler_rt_runtime name type) 167 if(NOT type MATCHES "^(OBJECT|STATIC|SHARED|MODULE)$") 168 message(FATAL_ERROR 169 "type argument must be OBJECT, STATIC, SHARED or MODULE") 170 return() 171 endif() 172 cmake_parse_arguments(LIB 173 "" 174 "PARENT_TARGET" 175 "OS;ARCHS;SOURCES;CFLAGS;LINK_FLAGS;DEFS;DEPS;LINK_LIBS;OBJECT_LIBS;ADDITIONAL_HEADERS;EXTENSIONS" 176 ${ARGN}) 177 set(libnames) 178 # Until we support this some other way, build compiler-rt runtime without LTO 179 # to allow non-LTO projects to link with it. GPU targets can currently only be 180 # distributed as LLVM-IR and ignore this. 181 if(COMPILER_RT_HAS_FNO_LTO_FLAG AND NOT COMPILER_RT_GPU_BUILD) 182 set(NO_LTO_FLAGS "-fno-lto") 183 else() 184 set(NO_LTO_FLAGS "") 185 endif() 186 187 # By default do not instrument or use profdata for compiler-rt. 188 set(NO_PGO_FLAGS "") 189 if(NOT COMPILER_RT_ENABLE_PGO) 190 if(LLVM_PROFDATA_FILE AND COMPILER_RT_HAS_FNO_PROFILE_INSTR_USE_FLAG) 191 list(APPEND NO_PGO_FLAGS "-fno-profile-instr-use") 192 endif() 193 if(LLVM_BUILD_INSTRUMENTED MATCHES IR AND COMPILER_RT_HAS_FNO_PROFILE_GENERATE_FLAG) 194 list(APPEND NO_PGO_FLAGS "-fno-profile-generate") 195 elseif((LLVM_BUILD_INSTRUMENTED OR LLVM_BUILD_INSTRUMENTED_COVERAGE) AND COMPILER_RT_HAS_FNO_PROFILE_INSTR_GENERATE_FLAG) 196 list(APPEND NO_PGO_FLAGS "-fno-profile-instr-generate") 197 if(LLVM_BUILD_INSTRUMENTED_COVERAGE AND COMPILER_RT_HAS_FNO_COVERAGE_MAPPING_FLAG) 198 list(APPEND NO_PGO_FLAGS "-fno-coverage-mapping") 199 endif() 200 endif() 201 endif() 202 203 list(LENGTH LIB_SOURCES LIB_SOURCES_LENGTH) 204 if (${LIB_SOURCES_LENGTH} GREATER 0) 205 # Add headers to LIB_SOURCES for IDEs. It doesn't make sense to 206 # do this for a runtime library that only consists of OBJECT 207 # libraries, so only add the headers when source files are present. 208 compiler_rt_process_sources(LIB_SOURCES 209 ${LIB_SOURCES} 210 ADDITIONAL_HEADERS 211 ${LIB_ADDITIONAL_HEADERS} 212 ) 213 endif() 214 215 if(APPLE) 216 foreach(os ${LIB_OS}) 217 # Strip out -msse3 if this isn't macOS. 218 list(LENGTH LIB_CFLAGS HAS_EXTRA_CFLAGS) 219 if(HAS_EXTRA_CFLAGS AND NOT "${os}" MATCHES "^(osx)$") 220 list(REMOVE_ITEM LIB_CFLAGS "-msse3") 221 endif() 222 if(type STREQUAL "STATIC") 223 set(libname "${name}_${os}") 224 else() 225 set(libname "${name}_${os}_dynamic") 226 set(extra_link_flags_${libname} ${DARWIN_${os}_LINK_FLAGS} ${LIB_LINK_FLAGS}) 227 endif() 228 list_intersect(LIB_ARCHS_${libname} DARWIN_${os}_ARCHS LIB_ARCHS) 229 if(LIB_ARCHS_${libname}) 230 list(APPEND libnames ${libname}) 231 set(extra_cflags_${libname} ${DARWIN_${os}_CFLAGS} ${NO_LTO_FLAGS} ${NO_PGO_FLAGS} ${LIB_CFLAGS}) 232 set(output_name_${libname} ${libname}${COMPILER_RT_OS_SUFFIX}) 233 set(sources_${libname} ${LIB_SOURCES}) 234 format_object_libs(sources_${libname} ${os} ${LIB_OBJECT_LIBS}) 235 get_compiler_rt_output_dir(${COMPILER_RT_DEFAULT_TARGET_ARCH} output_dir_${libname}) 236 get_compiler_rt_install_dir(${COMPILER_RT_DEFAULT_TARGET_ARCH} install_dir_${libname}) 237 endif() 238 239 # Build the macOS sanitizers with Mac Catalyst support. 240 if ("${COMPILER_RT_ENABLE_MACCATALYST}" AND 241 "${os}" MATCHES "^(osx)$") 242 foreach(arch ${LIB_ARCHS_${libname}}) 243 list(APPEND extra_cflags_${libname} 244 "SHELL:-target ${arch}-apple-macos${DARWIN_osx_MIN_VER} -darwin-target-variant ${arch}-apple-ios13.1-macabi") 245 list(APPEND extra_link_flags_${libname} 246 "SHELL:-target ${arch}-apple-macos${DARWIN_osx_MIN_VER} -darwin-target-variant ${arch}-apple-ios13.1-macabi") 247 endforeach() 248 endif() 249 endforeach() 250 else() 251 foreach(arch ${LIB_ARCHS}) 252 if(NOT CAN_TARGET_${arch}) 253 message(FATAL_ERROR "Architecture ${arch} can't be targeted") 254 return() 255 endif() 256 if(type STREQUAL "OBJECT") 257 set(libname "${name}-${arch}") 258 set_output_name(output_name_${libname} ${name}${COMPILER_RT_OS_SUFFIX} ${arch}) 259 elseif(type STREQUAL "STATIC") 260 set(libname "${name}-${arch}") 261 set_output_name(output_name_${libname} ${name} ${arch}) 262 else() 263 set(libname "${name}-dynamic-${arch}") 264 set(extra_cflags_${libname} ${TARGET_${arch}_CFLAGS} ${LIB_CFLAGS}) 265 set(extra_link_flags_${libname} ${TARGET_${arch}_LINK_FLAGS} ${LIB_LINK_FLAGS}) 266 if(WIN32) 267 set_output_name(output_name_${libname} ${name}_dynamic ${arch}) 268 else() 269 set_output_name(output_name_${libname} ${name} ${arch}) 270 endif() 271 endif() 272 if(COMPILER_RT_USE_BUILTINS_LIBRARY AND NOT type STREQUAL "OBJECT" AND 273 NOT name STREQUAL "clang_rt.builtins") 274 get_compiler_rt_target(${arch} target) 275 find_compiler_rt_library(builtins builtins_${libname} TARGET ${target}) 276 if(builtins_${libname} STREQUAL "NOTFOUND") 277 message(FATAL_ERROR "Cannot find builtins library for the target architecture") 278 endif() 279 endif() 280 set(sources_${libname} ${LIB_SOURCES}) 281 format_object_libs(sources_${libname} ${arch} ${LIB_OBJECT_LIBS}) 282 set(libnames ${libnames} ${libname}) 283 set(extra_cflags_${libname} ${TARGET_${arch}_CFLAGS} ${NO_LTO_FLAGS} ${NO_PGO_FLAGS} ${LIB_CFLAGS}) 284 get_compiler_rt_output_dir(${arch} output_dir_${libname}) 285 get_compiler_rt_install_dir(${arch} install_dir_${libname}) 286 endforeach() 287 endif() 288 289 if(NOT libnames) 290 return() 291 endif() 292 293 if(LIB_PARENT_TARGET) 294 # If the parent targets aren't created we should create them 295 if(NOT TARGET ${LIB_PARENT_TARGET}) 296 add_custom_target(${LIB_PARENT_TARGET}) 297 set_target_properties(${LIB_PARENT_TARGET} PROPERTIES 298 FOLDER "Compiler-RT/Runtimes") 299 endif() 300 endif() 301 302 foreach(libname ${libnames}) 303 # If you are using a multi-configuration generator we don't generate 304 # per-library install rules, so we fall back to the parent target COMPONENT 305 if(CMAKE_CONFIGURATION_TYPES AND LIB_PARENT_TARGET) 306 set(COMPONENT_OPTION COMPONENT ${LIB_PARENT_TARGET}) 307 else() 308 set(COMPONENT_OPTION COMPONENT ${libname}) 309 endif() 310 311 if(type STREQUAL "SHARED") 312 list(APPEND LIB_DEFS COMPILER_RT_SHARED_LIB) 313 endif() 314 315 if(type STREQUAL "OBJECT") 316 if(CMAKE_C_COMPILER_ID MATCHES Clang AND CMAKE_C_COMPILER_TARGET) 317 list(APPEND extra_cflags_${libname} "--target=${CMAKE_C_COMPILER_TARGET}") 318 endif() 319 if(CMAKE_SYSROOT) 320 list(APPEND extra_cflags_${libname} "--sysroot=${CMAKE_SYSROOT}") 321 endif() 322 string(REPLACE ";" " " extra_cflags_${libname} "${extra_cflags_${libname}}") 323 string(REGEX MATCHALL "<[A-Za-z0-9_]*>" substitutions 324 ${CMAKE_C_COMPILE_OBJECT}) 325 set(compile_command_${libname} "${CMAKE_C_COMPILE_OBJECT}") 326 327 set(output_file_${libname} ${output_name_${libname}}${CMAKE_C_OUTPUT_EXTENSION}) 328 foreach(substitution ${substitutions}) 329 if(substitution STREQUAL "<CMAKE_C_COMPILER>") 330 string(REPLACE "<CMAKE_C_COMPILER>" "${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1}" 331 compile_command_${libname} ${compile_command_${libname}}) 332 elseif(substitution STREQUAL "<OBJECT>") 333 string(REPLACE "<OBJECT>" "${output_dir_${libname}}/${output_file_${libname}}" 334 compile_command_${libname} ${compile_command_${libname}}) 335 elseif(substitution STREQUAL "<SOURCE>") 336 string(REPLACE "<SOURCE>" "${sources_${libname}}" 337 compile_command_${libname} ${compile_command_${libname}}) 338 elseif(substitution STREQUAL "<FLAGS>") 339 string(REPLACE "<FLAGS>" "${CMAKE_C_FLAGS} ${extra_cflags_${libname}}" 340 compile_command_${libname} ${compile_command_${libname}}) 341 else() 342 string(REPLACE "${substitution}" "" compile_command_${libname} 343 ${compile_command_${libname}}) 344 endif() 345 endforeach() 346 separate_arguments(compile_command_${libname}) 347 add_custom_command( 348 OUTPUT ${output_dir_${libname}}/${output_file_${libname}} 349 COMMAND ${compile_command_${libname}} 350 DEPENDS ${sources_${libname}} 351 COMMENT "Building C object ${output_file_${libname}}") 352 add_custom_target(${libname} DEPENDS ${output_dir_${libname}}/${output_file_${libname}}) 353 set_target_properties(${libname} PROPERTIES FOLDER "Compiler-RT/Codegenning") 354 install(FILES ${output_dir_${libname}}/${output_file_${libname}} 355 DESTINATION ${install_dir_${libname}} 356 ${COMPONENT_OPTION}) 357 else() 358 add_library(${libname} ${type} ${sources_${libname}}) 359 set_target_compile_flags(${libname} ${extra_cflags_${libname}}) 360 set_target_link_flags(${libname} ${extra_link_flags_${libname}}) 361 set_property(TARGET ${libname} APPEND PROPERTY 362 COMPILE_DEFINITIONS ${LIB_DEFS}) 363 set_target_output_directories(${libname} ${output_dir_${libname}}) 364 install(TARGETS ${libname} 365 ARCHIVE DESTINATION ${install_dir_${libname}} 366 ${COMPONENT_OPTION} 367 LIBRARY DESTINATION ${install_dir_${libname}} 368 ${COMPONENT_OPTION} 369 RUNTIME DESTINATION ${install_dir_${libname}} 370 ${COMPONENT_OPTION}) 371 endif() 372 if(LIB_DEPS) 373 add_dependencies(${libname} ${LIB_DEPS}) 374 endif() 375 set_target_properties(${libname} PROPERTIES 376 OUTPUT_NAME ${output_name_${libname}} 377 FOLDER "Compiler-RT/Runtimes") 378 if(LIB_LINK_LIBS) 379 target_link_libraries(${libname} PRIVATE ${LIB_LINK_LIBS}) 380 endif() 381 if(builtins_${libname}) 382 target_link_libraries(${libname} PRIVATE ${builtins_${libname}}) 383 endif() 384 if(${type} STREQUAL "SHARED") 385 if(APPLE OR WIN32) 386 set_property(TARGET ${libname} PROPERTY BUILD_WITH_INSTALL_RPATH ON) 387 endif() 388 if(WIN32 AND NOT CYGWIN AND NOT MINGW) 389 set_target_properties(${libname} PROPERTIES IMPORT_PREFIX "") 390 set_target_properties(${libname} PROPERTIES IMPORT_SUFFIX ".lib") 391 endif() 392 find_program(CODESIGN codesign) 393 if (APPLE AND NOT CMAKE_LINKER MATCHES ".*lld.*" AND CODESIGN) 394 # Apple's linker signs the resulting dylib with an ad-hoc code signature in 395 # most situations, except: 396 # 1. Versions of ld64 prior to ld64-609 in Xcode 12 predate this behavior. 397 # 2. Apple's new linker does not when building with `-darwin-target-variant` 398 # to support macOS Catalyst. 399 # 400 # Explicitly re-signing the dylib works around both of these issues. The 401 # signature is marked as `linker-signed` when that is supported so that it 402 # behaves as expected when processed by subsequent tooling. 403 # 404 # Detect whether `codesign` supports `-o linker-signed` by passing it as an 405 # argument and looking for `invalid argument "linker-signed"` in its output. 406 # FIXME: Remove this once all supported toolchains support `-o linker-signed`. 407 execute_process( 408 COMMAND sh -c "${CODESIGN} -f -s - -o linker-signed this-does-not-exist 2>&1 | grep -q linker-signed" 409 RESULT_VARIABLE CODESIGN_SUPPORTS_LINKER_SIGNED 410 ) 411 412 set(EXTRA_CODESIGN_ARGUMENTS) 413 if (CODESIGN_SUPPORTS_LINKER_SIGNED) 414 list(APPEND EXTRA_CODESIGN_ARGUMENTS -o linker-signed) 415 endif() 416 417 add_custom_command(TARGET ${libname} 418 POST_BUILD 419 COMMAND ${CODESIGN} --sign - ${EXTRA_CODESIGN_ARGUMENTS} $<TARGET_FILE:${libname}> 420 WORKING_DIRECTORY ${COMPILER_RT_OUTPUT_LIBRARY_DIR} 421 COMMAND_EXPAND_LISTS 422 ) 423 endif() 424 endif() 425 426 set(parent_target_arg) 427 if(LIB_PARENT_TARGET) 428 set(parent_target_arg PARENT_TARGET ${LIB_PARENT_TARGET}) 429 endif() 430 add_compiler_rt_install_targets(${libname} ${parent_target_arg}) 431 432 if(APPLE) 433 set_target_properties(${libname} PROPERTIES 434 OSX_ARCHITECTURES "${LIB_ARCHS_${libname}}") 435 endif() 436 437 if(type STREQUAL "SHARED") 438 rt_externalize_debuginfo(${libname}) 439 endif() 440 441 if(DEFINED LIB_EXTENSIONS) 442 set_target_properties(${libname} PROPERTIES C_EXTENSIONS ${LIB_EXTENSIONS}) 443 endif() 444 endforeach() 445 if(LIB_PARENT_TARGET) 446 add_dependencies(${LIB_PARENT_TARGET} ${libnames}) 447 endif() 448endfunction() 449 450# Compile and register compiler-rt tests. 451# generate_compiler_rt_tests(<output object files> <test_suite> <test_name> 452# <test architecture> 453# KIND <custom prefix> 454# SUBDIR <subdirectory for testing binary> 455# SOURCES <sources to compile> 456# RUNTIME <tests runtime to link in> 457# CFLAGS <compile-time flags> 458# COMPILE_DEPS <compile-time dependencies> 459# DEPS <dependencies> 460# LINK_FLAGS <flags to use during linking> 461# ) 462function(generate_compiler_rt_tests test_objects test_suite testname arch) 463 cmake_parse_arguments(TEST "" "KIND;RUNTIME;SUBDIR" 464 "SOURCES;COMPILE_DEPS;DEPS;CFLAGS;LINK_FLAGS" ${ARGN}) 465 466 foreach(source ${TEST_SOURCES}) 467 sanitizer_test_compile( 468 "${test_objects}" "${source}" "${arch}" 469 KIND ${TEST_KIND} 470 COMPILE_DEPS ${TEST_COMPILE_DEPS} 471 DEPS ${TEST_DEPS} 472 CFLAGS ${TEST_CFLAGS} 473 ) 474 endforeach() 475 476 set(TEST_DEPS ${${test_objects}}) 477 478 if(NOT "${TEST_RUNTIME}" STREQUAL "") 479 list(APPEND TEST_DEPS ${TEST_RUNTIME}) 480 list(APPEND "${test_objects}" $<TARGET_FILE:${TEST_RUNTIME}>) 481 endif() 482 483 add_compiler_rt_test(${test_suite} "${testname}" "${arch}" 484 SUBDIR ${TEST_SUBDIR} 485 OBJECTS ${${test_objects}} 486 DEPS ${TEST_DEPS} 487 LINK_FLAGS ${TEST_LINK_FLAGS} 488 ) 489 set("${test_objects}" "${${test_objects}}" PARENT_SCOPE) 490endfunction() 491 492# Link objects into a single executable with COMPILER_RT_TEST_COMPILER, 493# using specified link flags. Make executable a part of provided 494# test_suite. 495# add_compiler_rt_test(<test_suite> <test_name> <arch> 496# SUBDIR <subdirectory for binary> 497# OBJECTS <object files> 498# DEPS <deps (e.g. runtime libs)> 499# LINK_FLAGS <link flags>) 500function(add_compiler_rt_test test_suite test_name arch) 501 cmake_parse_arguments(TEST "" "SUBDIR" "OBJECTS;DEPS;LINK_FLAGS" "" ${ARGN}) 502 set(output_dir ${CMAKE_CURRENT_BINARY_DIR}) 503 if(TEST_SUBDIR) 504 set(output_dir "${output_dir}/${TEST_SUBDIR}") 505 endif() 506 set(output_dir "${output_dir}/${CMAKE_CFG_INTDIR}") 507 file(MAKE_DIRECTORY "${output_dir}") 508 set(output_bin "${output_dir}/${test_name}") 509 if(WIN32) 510 set(output_bin "${output_bin}.exe") 511 endif() 512 513 # Use host compiler in a standalone build, and just-built Clang otherwise. 514 if(NOT COMPILER_RT_STANDALONE_BUILD) 515 list(APPEND TEST_DEPS clang) 516 endif() 517 518 get_target_flags_for_arch(${arch} TARGET_LINK_FLAGS) 519 list(APPEND TEST_LINK_FLAGS ${TARGET_LINK_FLAGS}) 520 521 # If we're not on MSVC, include the linker flags from CMAKE but override them 522 # with the provided link flags. This ensures that flags which are required to 523 # link programs at all are included, but the changes needed for the test 524 # trump. With MSVC we can't do that because CMake is set up to run link.exe 525 # when linking, not the compiler. Here, we hack it to use the compiler 526 # because we want to use -fsanitize flags. 527 528 # Only add CMAKE_EXE_LINKER_FLAGS when in a standalone bulid. 529 # Or else CMAKE_EXE_LINKER_FLAGS contains flags for build compiler of Clang/llvm. 530 # This might not be the same as what the COMPILER_RT_TEST_COMPILER supports. 531 # eg: the build compiler use lld linker and we build clang with default ld linker 532 # then to be tested clang will complain about lld options like --color-diagnostics. 533 if(NOT MSVC AND COMPILER_RT_STANDALONE_BUILD) 534 set(TEST_LINK_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${TEST_LINK_FLAGS}") 535 separate_arguments(TEST_LINK_FLAGS) 536 endif() 537 if(NOT COMPILER_RT_STANDALONE_BUILD AND COMPILER_RT_HAS_LLD AND "lld" IN_LIST LLVM_ENABLE_PROJECTS) 538 # CMAKE_EXE_LINKER_FLAGS may contain -fuse=lld 539 # FIXME: -DLLVM_ENABLE_LLD=ON and -DLLVM_ENABLE_PROJECTS without lld case. 540 list(APPEND TEST_DEPS lld) 541 endif() 542 add_custom_command( 543 OUTPUT "${output_bin}" 544 COMMAND ${COMPILER_RT_TEST_CXX_COMPILER} ${TEST_OBJECTS} -o "${output_bin}" 545 ${TEST_LINK_FLAGS} 546 DEPENDS ${TEST_DEPS} 547 ) 548 add_custom_target(T${test_name} DEPENDS "${output_bin}") 549 set_target_properties(T${test_name} PROPERTIES FOLDER "Compiler-RT/Tests") 550 551 # Make the test suite depend on the binary. 552 add_dependencies(${test_suite} T${test_name}) 553endfunction() 554 555macro(add_compiler_rt_resource_file target_name file_name component) 556 set(src_file "${CMAKE_CURRENT_SOURCE_DIR}/${file_name}") 557 set(dst_file "${COMPILER_RT_OUTPUT_DIR}/share/${file_name}") 558 add_custom_command(OUTPUT ${dst_file} 559 DEPENDS ${src_file} 560 COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src_file} ${dst_file} 561 COMMENT "Copying ${file_name}...") 562 add_custom_target(${target_name} DEPENDS ${dst_file}) 563 # Install in Clang resource directory. 564 install(FILES ${file_name} 565 DESTINATION ${COMPILER_RT_INSTALL_DATA_DIR} 566 COMPONENT ${component}) 567 add_dependencies(${component} ${target_name}) 568 569 set_target_properties(${target_name} PROPERTIES FOLDER "Compiler-RT/Resources") 570endmacro() 571 572macro(add_compiler_rt_script name) 573 set(dst ${COMPILER_RT_EXEC_OUTPUT_DIR}/${name}) 574 set(src ${CMAKE_CURRENT_SOURCE_DIR}/${name}) 575 add_custom_command(OUTPUT ${dst} 576 DEPENDS ${src} 577 COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst} 578 COMMENT "Copying ${name}...") 579 add_custom_target(${name} DEPENDS ${dst}) 580 install(FILES ${dst} 581 PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE 582 DESTINATION ${COMPILER_RT_INSTALL_BINARY_DIR}) 583endmacro(add_compiler_rt_script src name) 584 585# Builds custom version of libc++ and installs it in <prefix>. 586# Can be used to build sanitized versions of libc++ for running unit tests. 587# add_custom_libcxx(<name> <prefix> 588# DEPS <list of build deps> 589# CFLAGS <list of compile flags> 590# USE_TOOLCHAIN) 591macro(add_custom_libcxx name prefix) 592 if(NOT COMPILER_RT_LIBCXX_PATH) 593 message(FATAL_ERROR "libcxx not found!") 594 endif() 595 if(NOT COMPILER_RT_LIBCXXABI_PATH) 596 message(FATAL_ERROR "libcxxabi not found!") 597 endif() 598 599 cmake_parse_arguments(LIBCXX "USE_TOOLCHAIN" "" "DEPS;CFLAGS;CMAKE_ARGS" ${ARGN}) 600 601 if(LIBCXX_USE_TOOLCHAIN) 602 set(compiler_args -DCMAKE_C_COMPILER=${COMPILER_RT_TEST_COMPILER} 603 -DCMAKE_CXX_COMPILER=${COMPILER_RT_TEST_CXX_COMPILER}) 604 if(NOT COMPILER_RT_STANDALONE_BUILD AND NOT LLVM_RUNTIMES_BUILD) 605 set(toolchain_deps $<TARGET_FILE:clang>) 606 set(force_deps DEPENDS $<TARGET_FILE:clang>) 607 endif() 608 else() 609 set(compiler_args -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} 610 -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}) 611 endif() 612 613 add_custom_target(${name}-clear 614 COMMAND ${CMAKE_COMMAND} -E remove_directory ${prefix} 615 COMMENT "Clobbering ${name} build directories" 616 USES_TERMINAL 617 ) 618 set_target_properties(${name}-clear PROPERTIES FOLDER "Compiler-RT/Metatargets") 619 620 add_custom_command( 621 OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp 622 DEPENDS ${LIBCXX_DEPS} ${toolchain_deps} 623 COMMAND ${CMAKE_COMMAND} -E touch ${prefix}/CMakeCache.txt 624 COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp 625 COMMENT "Clobbering bootstrap build directories" 626 ) 627 628 add_custom_target(${name}-clobber 629 DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp) 630 set_target_properties(${name}-clobber PROPERTIES FOLDER "Compiler-RT/Metatargets") 631 632 set(PASSTHROUGH_VARIABLES 633 ANDROID 634 ANDROID_NATIVE_API_LEVEL 635 CMAKE_C_COMPILER_TARGET 636 CMAKE_CXX_COMPILER_TARGET 637 CMAKE_SHARED_LINKER_FLAGS 638 CMAKE_MODULE_LINKER_FLAGS 639 CMAKE_EXE_LINKER_FLAGS 640 CMAKE_INSTALL_PREFIX 641 CMAKE_MAKE_PROGRAM 642 CMAKE_LINKER 643 CMAKE_AR 644 CMAKE_RANLIB 645 CMAKE_NM 646 CMAKE_OBJCOPY 647 CMAKE_OBJDUMP 648 CMAKE_STRIP 649 CMAKE_READELF 650 CMAKE_SYSROOT 651 CMAKE_TOOLCHAIN_FILE 652 LIBCXX_HAS_MUSL_LIBC 653 LIBCXX_HAS_GCC_S_LIB 654 LIBCXX_HAS_PTHREAD_LIB 655 LIBCXX_HAS_RT_LIB 656 LIBCXX_USE_COMPILER_RT 657 LIBCXXABI_HAS_PTHREAD_LIB 658 PYTHON_EXECUTABLE 659 Python3_EXECUTABLE 660 Python2_EXECUTABLE 661 CMAKE_SYSTEM_NAME) 662 foreach(variable ${PASSTHROUGH_VARIABLES}) 663 get_property(is_value_set CACHE ${variable} PROPERTY VALUE SET) 664 if(${is_value_set}) 665 get_property(value CACHE ${variable} PROPERTY VALUE) 666 list(APPEND CMAKE_PASSTHROUGH_VARIABLES -D${variable}=${value}) 667 endif() 668 endforeach() 669 670 string(REPLACE ";" " " LIBCXX_C_FLAGS "${LIBCXX_CFLAGS}") 671 get_property(C_FLAGS CACHE CMAKE_C_FLAGS PROPERTY VALUE) 672 set(LIBCXX_C_FLAGS "${LIBCXX_C_FLAGS} ${C_FLAGS}") 673 674 string(REPLACE ";" " " LIBCXX_CXX_FLAGS "${LIBCXX_CFLAGS}") 675 get_property(CXX_FLAGS CACHE CMAKE_CXX_FLAGS PROPERTY VALUE) 676 set(LIBCXX_CXX_FLAGS "${LIBCXX_CXX_FLAGS} ${CXX_FLAGS}") 677 678 if(CMAKE_VERBOSE_MAKEFILE) 679 set(verbose -DCMAKE_VERBOSE_MAKEFILE=ON) 680 endif() 681 682 ExternalProject_Add(${name} 683 DEPENDS ${name}-clobber ${LIBCXX_DEPS} 684 PREFIX ${prefix} 685 SOURCE_DIR ${LLVM_MAIN_SRC_DIR}/../runtimes 686 BINARY_DIR ${prefix}/build 687 CMAKE_ARGS ${CMAKE_PASSTHROUGH_VARIABLES} 688 ${compiler_args} 689 ${verbose} 690 -DCMAKE_C_FLAGS=${LIBCXX_C_FLAGS} 691 -DCMAKE_CXX_FLAGS=${LIBCXX_CXX_FLAGS} 692 -DCMAKE_BUILD_TYPE=Release 693 -DCMAKE_INSTALL_PREFIX=<INSTALL_DIR> 694 -DCMAKE_INSTALL_MESSAGE=LAZY 695 -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY 696 -DLLVM_ENABLE_RUNTIMES=libcxx|libcxxabi 697 -DLIBCXXABI_USE_LLVM_UNWINDER=OFF 698 -DLIBCXXABI_ENABLE_SHARED=OFF 699 -DLIBCXXABI_HERMETIC_STATIC_LIBRARY=ON 700 -DLIBCXXABI_INCLUDE_TESTS=OFF 701 -DLIBCXX_CXX_ABI=libcxxabi 702 -DLIBCXX_ENABLE_SHARED=OFF 703 -DLIBCXX_HERMETIC_STATIC_LIBRARY=ON 704 -DLIBCXX_INCLUDE_BENCHMARKS=OFF 705 -DLIBCXX_INCLUDE_TESTS=OFF 706 -DLIBCXX_ENABLE_STATIC_ABI_LIBRARY=ON 707 -DLLVM_INCLUDE_TESTS=OFF 708 -DLLVM_INCLUDE_DOCS=OFF 709 ${LIBCXX_CMAKE_ARGS} 710 STEP_TARGETS configure build 711 BUILD_ALWAYS 1 712 USES_TERMINAL_CONFIGURE 1 713 USES_TERMINAL_BUILD 1 714 USES_TERMINAL_INSTALL 1 715 LIST_SEPARATOR | 716 EXCLUDE_FROM_ALL TRUE 717 ) 718 719 # Once we depend on CMake 3.26, we can use the INSTALL_BYPRODUCTS argument 720 # instead of having to fall back to ExternalProject_Add_Step() 721 # Note: We can't use the normal name "install" here since that interferes 722 # with the default ExternalProject_Add() logic and causes errors. 723 ExternalProject_Add_Step(${name} install-cmake326-workaround 724 # Ensure that DESTDIR=... set in the out environment does not affect this 725 # target (we always need to install to the build directory). 726 COMMAND env DESTDIR= ${CMAKE_COMMAND} --build ${prefix}/build --target install 727 COMMENT "Installing ${name}..." 728 BYPRODUCTS "${prefix}/lib/libc++.a" "${prefix}/lib/libc++abi.a" 729 DEPENDEES build 730 EXCLUDE_FROM_MAIN 1 731 USES_TERMINAL 1 732 ) 733 ExternalProject_Add_StepTargets(${name} install-cmake326-workaround) 734 735 if (CMAKE_GENERATOR MATCHES "Make") 736 set(run_clean "$(MAKE)" "-C" "${prefix}" "clean") 737 else() 738 set(run_clean ${CMAKE_COMMAND} --build ${prefix} --target clean 739 --config "$<CONFIG>") 740 endif() 741 742 ExternalProject_Add_Step(${name} clean 743 COMMAND ${run_clean} 744 COMMENT "Cleaning ${name}..." 745 DEPENDEES configure 746 ${force_deps} 747 WORKING_DIRECTORY ${prefix} 748 EXCLUDE_FROM_MAIN 1 749 USES_TERMINAL 1 750 ) 751 ExternalProject_Add_StepTargets(${name} clean) 752 753 if(LIBCXX_USE_TOOLCHAIN) 754 add_dependencies(${name}-clean ${name}-clobber) 755 set_target_properties(${name}-clean PROPERTIES 756 SOURCES ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp) 757 endif() 758endmacro() 759 760function(rt_externalize_debuginfo name) 761 if(NOT COMPILER_RT_EXTERNALIZE_DEBUGINFO) 762 return() 763 endif() 764 765 if(NOT COMPILER_RT_EXTERNALIZE_DEBUGINFO_SKIP_STRIP) 766 set(strip_command COMMAND xcrun strip -Sl $<TARGET_FILE:${name}>) 767 endif() 768 769 if(APPLE) 770 if(CMAKE_CXX_FLAGS MATCHES "-flto" 771 OR CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE} MATCHES "-flto") 772 773 set(lto_object ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${name}-lto.o) 774 set_property(TARGET ${name} APPEND_STRING PROPERTY 775 LINK_FLAGS " -Wl,-object_path_lto -Wl,${lto_object}") 776 endif() 777 add_custom_command(TARGET ${name} POST_BUILD 778 COMMAND xcrun dsymutil $<TARGET_FILE:${name}> 779 ${strip_command}) 780 else() 781 message(FATAL_ERROR "COMPILER_RT_EXTERNALIZE_DEBUGINFO isn't implemented for non-darwin platforms!") 782 endif() 783endfunction() 784 785 786# Configure lit configuration files, including compiler-rt specific variables. 787function(configure_compiler_rt_lit_site_cfg input output) 788 set_llvm_build_mode() 789 790 get_compiler_rt_output_dir(${COMPILER_RT_DEFAULT_TARGET_ARCH} output_dir) 791 792 string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} COMPILER_RT_RESOLVED_TEST_COMPILER ${COMPILER_RT_TEST_COMPILER}) 793 string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} COMPILER_RT_RESOLVED_OUTPUT_DIR ${COMPILER_RT_OUTPUT_DIR}) 794 string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} COMPILER_RT_RESOLVED_EXEC_OUTPUT_DIR ${COMPILER_RT_EXEC_OUTPUT_DIR}) 795 string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} COMPILER_RT_RESOLVED_LIBRARY_OUTPUT_DIR ${output_dir}) 796 797 configure_lit_site_cfg(${input} ${output}) 798endfunction() 799