1include(ExternalProject) 2include(CompilerRTUtils) 3 4function(set_target_output_directories target output_dir) 5 # For RUNTIME_OUTPUT_DIRECTORY variable, Multi-configuration generators 6 # append a per-configuration subdirectory to the specified directory. 7 # To avoid the appended folder, the configuration specific variable must be 8 # set 'RUNTIME_OUTPUT_DIRECTORY_${CONF}': 9 # RUNTIME_OUTPUT_DIRECTORY_DEBUG, RUNTIME_OUTPUT_DIRECTORY_RELEASE, ... 10 if(CMAKE_CONFIGURATION_TYPES) 11 foreach(build_mode ${CMAKE_CONFIGURATION_TYPES}) 12 string(TOUPPER "${build_mode}" CONFIG_SUFFIX) 13 set_target_properties("${target}" PROPERTIES 14 "ARCHIVE_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${output_dir} 15 "LIBRARY_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${output_dir} 16 "RUNTIME_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${output_dir}) 17 endforeach() 18 else() 19 set_target_properties("${target}" PROPERTIES 20 ARCHIVE_OUTPUT_DIRECTORY ${output_dir} 21 LIBRARY_OUTPUT_DIRECTORY ${output_dir} 22 RUNTIME_OUTPUT_DIRECTORY ${output_dir}) 23 endif() 24endfunction() 25 26# Tries to add an "object library" target for a given list of OSs and/or 27# architectures with name "<name>.<arch>" for non-Darwin platforms if 28# architecture can be targeted, and "<name>.<os>" for Darwin platforms. 29# add_compiler_rt_object_libraries(<name> 30# OS <os names> 31# ARCHS <architectures> 32# SOURCES <source files> 33# CFLAGS <compile flags> 34# DEFS <compile definitions> 35# DEPS <dependencies> 36# ADDITIONAL_HEADERS <header files>) 37function(add_compiler_rt_object_libraries name) 38 cmake_parse_arguments(LIB "" "" "OS;ARCHS;SOURCES;CFLAGS;DEFS;DEPS;ADDITIONAL_HEADERS" 39 ${ARGN}) 40 set(libnames) 41 if(APPLE) 42 foreach(os ${LIB_OS}) 43 set(libname "${name}.${os}") 44 set(libnames ${libnames} ${libname}) 45 set(extra_cflags_${libname} ${DARWIN_${os}_CFLAGS}) 46 list_intersect(LIB_ARCHS_${libname} DARWIN_${os}_ARCHS LIB_ARCHS) 47 endforeach() 48 else() 49 foreach(arch ${LIB_ARCHS}) 50 set(libname "${name}.${arch}") 51 set(libnames ${libnames} ${libname}) 52 set(extra_cflags_${libname} ${TARGET_${arch}_CFLAGS}) 53 if(NOT CAN_TARGET_${arch}) 54 message(FATAL_ERROR "Architecture ${arch} can't be targeted") 55 return() 56 endif() 57 endforeach() 58 endif() 59 60 # Add headers to LIB_SOURCES for IDEs 61 compiler_rt_process_sources(LIB_SOURCES 62 ${LIB_SOURCES} 63 ADDITIONAL_HEADERS 64 ${LIB_ADDITIONAL_HEADERS} 65 ) 66 67 foreach(libname ${libnames}) 68 add_library(${libname} OBJECT ${LIB_SOURCES}) 69 if(LIB_DEPS) 70 add_dependencies(${libname} ${LIB_DEPS}) 71 endif() 72 73 # Strip out -msse3 if this isn't macOS. 74 set(target_flags ${LIB_CFLAGS}) 75 if(APPLE AND NOT "${libname}" MATCHES ".*\.osx.*") 76 list(REMOVE_ITEM target_flags "-msse3") 77 endif() 78 79 set_target_compile_flags(${libname} 80 ${extra_cflags_${libname}} ${target_flags}) 81 set_property(TARGET ${libname} APPEND PROPERTY 82 COMPILE_DEFINITIONS ${LIB_DEFS}) 83 set_target_properties(${libname} PROPERTIES FOLDER "Compiler-RT Libraries") 84 if(APPLE) 85 set_target_properties(${libname} PROPERTIES 86 OSX_ARCHITECTURES "${LIB_ARCHS_${libname}}") 87 endif() 88 endforeach() 89endfunction() 90 91# Takes a list of object library targets, and a suffix and appends the proper 92# TARGET_OBJECTS string to the output variable. 93# format_object_libs(<output> <suffix> ...) 94macro(format_object_libs output suffix) 95 foreach(lib ${ARGN}) 96 list(APPEND ${output} $<TARGET_OBJECTS:${lib}.${suffix}>) 97 endforeach() 98endmacro() 99 100function(add_compiler_rt_component name) 101 add_custom_target(${name}) 102 set_target_properties(${name} PROPERTIES FOLDER "Compiler-RT Misc") 103 if(COMMAND runtime_register_component) 104 runtime_register_component(${name}) 105 endif() 106 add_dependencies(compiler-rt ${name}) 107endfunction() 108 109function(add_asm_sources output) 110 set(${output} ${ARGN} PARENT_SCOPE) 111 # Xcode will try to compile asm files as C ('clang -x c'), and that will fail. 112 if (${CMAKE_GENERATOR} STREQUAL "Xcode") 113 enable_language(ASM) 114 else() 115 # Pass ASM file directly to the C++ compiler. 116 set_source_files_properties(${ARGN} PROPERTIES LANGUAGE C) 117 endif() 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 else() 127 set(${output} "${name}-${arch}${COMPILER_RT_OS_SUFFIX}") 128 endif() 129 endif() 130endmacro() 131 132# Adds static or shared runtime for a list of architectures and operating 133# systems and puts it in the proper directory in the build and install trees. 134# add_compiler_rt_runtime(<name> 135# {OBJECT|STATIC|SHARED} 136# ARCHS <architectures> 137# OS <os list> 138# SOURCES <source files> 139# CFLAGS <compile flags> 140# LINK_FLAGS <linker flags> 141# DEFS <compile definitions> 142# LINK_LIBS <linked libraries> (only for shared library) 143# OBJECT_LIBS <object libraries to use as sources> 144# PARENT_TARGET <convenience parent target> 145# ADDITIONAL_HEADERS <header files>) 146function(add_compiler_rt_runtime name type) 147 if(NOT type MATCHES "^(OBJECT|STATIC|SHARED)$") 148 message(FATAL_ERROR "type argument must be OBJECT, STATIC or SHARED") 149 return() 150 endif() 151 cmake_parse_arguments(LIB 152 "" 153 "PARENT_TARGET" 154 "OS;ARCHS;SOURCES;CFLAGS;LINK_FLAGS;DEFS;LINK_LIBS;OBJECT_LIBS;ADDITIONAL_HEADERS" 155 ${ARGN}) 156 set(libnames) 157 # Until we support this some other way, build compiler-rt runtime without LTO 158 # to allow non-LTO projects to link with it. 159 if(COMPILER_RT_HAS_FNO_LTO_FLAG) 160 set(NO_LTO_FLAGS "-fno-lto") 161 else() 162 set(NO_LTO_FLAGS "") 163 endif() 164 165 list(LENGTH LIB_SOURCES LIB_SOURCES_LENGTH) 166 if (${LIB_SOURCES_LENGTH} GREATER 0) 167 # Add headers to LIB_SOURCES for IDEs. It doesn't make sense to 168 # do this for a runtime library that only consists of OBJECT 169 # libraries, so only add the headers when source files are present. 170 compiler_rt_process_sources(LIB_SOURCES 171 ${LIB_SOURCES} 172 ADDITIONAL_HEADERS 173 ${LIB_ADDITIONAL_HEADERS} 174 ) 175 endif() 176 177 if(APPLE) 178 foreach(os ${LIB_OS}) 179 # Strip out -msse3 if this isn't macOS. 180 list(LENGTH LIB_CFLAGS HAS_EXTRA_CFLAGS) 181 if(HAS_EXTRA_CFLAGS AND NOT "${os}" MATCHES "^(osx)$") 182 list(REMOVE_ITEM LIB_CFLAGS "-msse3") 183 endif() 184 if(type STREQUAL "STATIC") 185 set(libname "${name}_${os}") 186 else() 187 set(libname "${name}_${os}_dynamic") 188 set(extra_link_flags_${libname} ${DARWIN_${os}_LINK_FLAGS} ${LIB_LINK_FLAGS}) 189 endif() 190 list_intersect(LIB_ARCHS_${libname} DARWIN_${os}_ARCHS LIB_ARCHS) 191 if(LIB_ARCHS_${libname}) 192 list(APPEND libnames ${libname}) 193 set(extra_cflags_${libname} ${DARWIN_${os}_CFLAGS} ${NO_LTO_FLAGS} ${LIB_CFLAGS}) 194 set(output_name_${libname} ${libname}${COMPILER_RT_OS_SUFFIX}) 195 set(sources_${libname} ${LIB_SOURCES}) 196 format_object_libs(sources_${libname} ${os} ${LIB_OBJECT_LIBS}) 197 get_compiler_rt_output_dir(${COMPILER_RT_DEFAULT_TARGET_ARCH} output_dir_${libname}) 198 get_compiler_rt_install_dir(${COMPILER_RT_DEFAULT_TARGET_ARCH} install_dir_${libname}) 199 endif() 200 endforeach() 201 else() 202 foreach(arch ${LIB_ARCHS}) 203 if(NOT CAN_TARGET_${arch}) 204 message(FATAL_ERROR "Architecture ${arch} can't be targeted") 205 return() 206 endif() 207 if(type STREQUAL "OBJECT") 208 set(libname "${name}-${arch}") 209 set_output_name(output_name_${libname} ${name}${COMPILER_RT_OS_SUFFIX} ${arch}) 210 elseif(type STREQUAL "STATIC") 211 set(libname "${name}-${arch}") 212 set_output_name(output_name_${libname} ${name} ${arch}) 213 else() 214 set(libname "${name}-dynamic-${arch}") 215 set(extra_cflags_${libname} ${TARGET_${arch}_CFLAGS} ${LIB_CFLAGS}) 216 set(extra_link_flags_${libname} ${TARGET_${arch}_LINK_FLAGS} ${LIB_LINK_FLAGS}) 217 if(WIN32) 218 set_output_name(output_name_${libname} ${name}_dynamic ${arch}) 219 else() 220 set_output_name(output_name_${libname} ${name} ${arch}) 221 endif() 222 endif() 223 set(sources_${libname} ${LIB_SOURCES}) 224 format_object_libs(sources_${libname} ${arch} ${LIB_OBJECT_LIBS}) 225 set(libnames ${libnames} ${libname}) 226 set(extra_cflags_${libname} ${TARGET_${arch}_CFLAGS} ${NO_LTO_FLAGS} ${LIB_CFLAGS}) 227 get_compiler_rt_output_dir(${arch} output_dir_${libname}) 228 get_compiler_rt_install_dir(${arch} install_dir_${libname}) 229 endforeach() 230 endif() 231 232 if(NOT libnames) 233 return() 234 endif() 235 236 if(LIB_PARENT_TARGET) 237 # If the parent targets aren't created we should create them 238 if(NOT TARGET ${LIB_PARENT_TARGET}) 239 add_custom_target(${LIB_PARENT_TARGET}) 240 set_target_properties(${LIB_PARENT_TARGET} PROPERTIES 241 FOLDER "Compiler-RT Misc") 242 endif() 243 endif() 244 245 foreach(libname ${libnames}) 246 # If you are using a multi-configuration generator we don't generate 247 # per-library install rules, so we fall back to the parent target COMPONENT 248 if(CMAKE_CONFIGURATION_TYPES AND LIB_PARENT_TARGET) 249 set(COMPONENT_OPTION COMPONENT ${LIB_PARENT_TARGET}) 250 else() 251 set(COMPONENT_OPTION COMPONENT ${libname}) 252 endif() 253 254 if(type STREQUAL "OBJECT") 255 if(CMAKE_C_COMPILER_ID MATCHES Clang AND CMAKE_C_COMPILER_TARGET) 256 list(APPEND extra_cflags_${libname} "--target=${CMAKE_C_COMPILER_TARGET}") 257 endif() 258 if(CMAKE_SYSROOT) 259 list(APPEND extra_cflags_${libname} "--sysroot=${CMAKE_SYSROOT}") 260 endif() 261 string(REPLACE ";" " " extra_cflags_${libname} "${extra_cflags_${libname}}") 262 string(REGEX MATCHALL "<[A-Za-z0-9_]*>" substitutions 263 ${CMAKE_C_COMPILE_OBJECT}) 264 set(compile_command_${libname} "${CMAKE_C_COMPILE_OBJECT}") 265 266 set(output_file_${libname} ${output_name_${libname}}${CMAKE_C_OUTPUT_EXTENSION}) 267 foreach(substitution ${substitutions}) 268 if(substitution STREQUAL "<CMAKE_C_COMPILER>") 269 string(REPLACE "<CMAKE_C_COMPILER>" "${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1}" 270 compile_command_${libname} ${compile_command_${libname}}) 271 elseif(substitution STREQUAL "<OBJECT>") 272 string(REPLACE "<OBJECT>" "${output_dir_${libname}}/${output_file_${libname}}" 273 compile_command_${libname} ${compile_command_${libname}}) 274 elseif(substitution STREQUAL "<SOURCE>") 275 string(REPLACE "<SOURCE>" "${sources_${libname}}" 276 compile_command_${libname} ${compile_command_${libname}}) 277 elseif(substitution STREQUAL "<FLAGS>") 278 string(REPLACE "<FLAGS>" "${CMAKE_C_FLAGS} ${extra_cflags_${libname}}" 279 compile_command_${libname} ${compile_command_${libname}}) 280 else() 281 string(REPLACE "${substitution}" "" compile_command_${libname} 282 ${compile_command_${libname}}) 283 endif() 284 endforeach() 285 separate_arguments(compile_command_${libname}) 286 add_custom_command( 287 OUTPUT ${output_dir_${libname}}/${output_file_${libname}} 288 COMMAND ${compile_command_${libname}} 289 DEPENDS ${sources_${libname}} 290 COMMENT "Building C object ${output_file_${libname}}") 291 add_custom_target(${libname} DEPENDS ${output_dir_${libname}}/${output_file_${libname}}) 292 install(FILES ${output_dir_${libname}}/${output_file_${libname}} 293 DESTINATION ${install_dir_${libname}} 294 ${COMPONENT_OPTION}) 295 else() 296 add_library(${libname} ${type} ${sources_${libname}}) 297 set_target_compile_flags(${libname} ${extra_cflags_${libname}}) 298 set_target_link_flags(${libname} ${extra_link_flags_${libname}}) 299 set_property(TARGET ${libname} APPEND PROPERTY 300 COMPILE_DEFINITIONS ${LIB_DEFS}) 301 set_target_output_directories(${libname} ${output_dir_${libname}}) 302 install(TARGETS ${libname} 303 ARCHIVE DESTINATION ${install_dir_${libname}} 304 ${COMPONENT_OPTION} 305 LIBRARY DESTINATION ${install_dir_${libname}} 306 ${COMPONENT_OPTION} 307 RUNTIME DESTINATION ${install_dir_${libname}} 308 ${COMPONENT_OPTION}) 309 endif() 310 set_target_properties(${libname} PROPERTIES 311 OUTPUT_NAME ${output_name_${libname}}) 312 set_target_properties(${libname} PROPERTIES FOLDER "Compiler-RT Runtime") 313 if(LIB_LINK_LIBS) 314 target_link_libraries(${libname} PRIVATE ${LIB_LINK_LIBS}) 315 endif() 316 if(${type} STREQUAL "SHARED") 317 if(COMMAND llvm_setup_rpath) 318 llvm_setup_rpath(${libname}) 319 endif() 320 if(WIN32 AND NOT CYGWIN AND NOT MINGW) 321 set_target_properties(${libname} PROPERTIES IMPORT_PREFIX "") 322 set_target_properties(${libname} PROPERTIES IMPORT_SUFFIX ".lib") 323 endif() 324 if(APPLE) 325 # Ad-hoc sign the dylibs 326 add_custom_command(TARGET ${libname} 327 POST_BUILD 328 COMMAND codesign --sign - $<TARGET_FILE:${libname}> 329 WORKING_DIRECTORY ${COMPILER_RT_LIBRARY_OUTPUT_DIR} 330 ) 331 endif() 332 endif() 333 334 set(parent_target_arg) 335 if(LIB_PARENT_TARGET) 336 set(parent_target_arg PARENT_TARGET ${LIB_PARENT_TARGET}) 337 endif() 338 add_compiler_rt_install_targets(${libname} ${parent_target_arg}) 339 340 if(APPLE) 341 set_target_properties(${libname} PROPERTIES 342 OSX_ARCHITECTURES "${LIB_ARCHS_${libname}}") 343 endif() 344 345 if(type STREQUAL "SHARED") 346 rt_externalize_debuginfo(${libname}) 347 endif() 348 endforeach() 349 if(LIB_PARENT_TARGET) 350 add_dependencies(${LIB_PARENT_TARGET} ${libnames}) 351 endif() 352endfunction() 353 354# when cross compiling, COMPILER_RT_TEST_COMPILER_CFLAGS help 355# in compilation and linking of unittests. 356string(REPLACE " " ";" COMPILER_RT_UNITTEST_CFLAGS "${COMPILER_RT_TEST_COMPILER_CFLAGS}") 357set(COMPILER_RT_UNITTEST_LINK_FLAGS ${COMPILER_RT_UNITTEST_CFLAGS}) 358 359# Unittests support. 360set(COMPILER_RT_GTEST_PATH ${LLVM_MAIN_SRC_DIR}/utils/unittest/googletest) 361set(COMPILER_RT_GTEST_SOURCE ${COMPILER_RT_GTEST_PATH}/src/gtest-all.cc) 362set(COMPILER_RT_GTEST_CFLAGS 363 -DGTEST_NO_LLVM_RAW_OSTREAM=1 364 -DGTEST_HAS_RTTI=0 365 -I${COMPILER_RT_GTEST_PATH}/include 366 -I${COMPILER_RT_GTEST_PATH} 367) 368 369# Mocking support. 370set(COMPILER_RT_GMOCK_PATH ${LLVM_MAIN_SRC_DIR}/utils/unittest/googlemock) 371set(COMPILER_RT_GMOCK_SOURCE ${COMPILER_RT_GMOCK_PATH}/src/gmock-all.cc) 372set(COMPILER_RT_GMOCK_CFLAGS 373 -DGTEST_NO_LLVM_RAW_OSTREAM=1 374 -DGTEST_HAS_RTTI=0 375 -I${COMPILER_RT_GMOCK_PATH}/include 376 -I${COMPILER_RT_GMOCK_PATH} 377) 378 379append_list_if(COMPILER_RT_DEBUG -DSANITIZER_DEBUG=1 COMPILER_RT_UNITTEST_CFLAGS) 380append_list_if(COMPILER_RT_HAS_WCOVERED_SWITCH_DEFAULT_FLAG -Wno-covered-switch-default COMPILER_RT_UNITTEST_CFLAGS) 381 382if(MSVC) 383 # gtest use a lot of stuff marked as deprecated on Windows. 384 list(APPEND COMPILER_RT_GTEST_CFLAGS -Wno-deprecated-declarations) 385endif() 386 387# Compile and register compiler-rt tests. 388# generate_compiler_rt_tests(<output object files> <test_suite> <test_name> 389# <test architecture> 390# KIND <custom prefix> 391# SUBDIR <subdirectory for testing binary> 392# SOURCES <sources to compile> 393# RUNTIME <tests runtime to link in> 394# CFLAGS <compile-time flags> 395# COMPILE_DEPS <compile-time dependencies> 396# DEPS <dependencies> 397# LINK_FLAGS <flags to use during linking> 398# ) 399function(generate_compiler_rt_tests test_objects test_suite testname arch) 400 cmake_parse_arguments(TEST "" "KIND;RUNTIME;SUBDIR" 401 "SOURCES;COMPILE_DEPS;DEPS;CFLAGS;LINK_FLAGS" ${ARGN}) 402 403 foreach(source ${TEST_SOURCES}) 404 sanitizer_test_compile( 405 "${test_objects}" "${source}" "${arch}" 406 KIND ${TEST_KIND} 407 COMPILE_DEPS ${TEST_COMPILE_DEPS} 408 DEPS ${TEST_DEPS} 409 CFLAGS ${TEST_CFLAGS} 410 ) 411 endforeach() 412 413 set(TEST_DEPS ${${test_objects}}) 414 415 if(NOT "${TEST_RUNTIME}" STREQUAL "") 416 list(APPEND TEST_DEPS ${TEST_RUNTIME}) 417 list(APPEND "${test_objects}" $<TARGET_FILE:${TEST_RUNTIME}>) 418 endif() 419 420 add_compiler_rt_test(${test_suite} "${testname}" "${arch}" 421 SUBDIR ${TEST_SUBDIR} 422 OBJECTS ${${test_objects}} 423 DEPS ${TEST_DEPS} 424 LINK_FLAGS ${TEST_LINK_FLAGS} 425 ) 426 set("${test_objects}" "${${test_objects}}" PARENT_SCOPE) 427endfunction() 428 429# Link objects into a single executable with COMPILER_RT_TEST_COMPILER, 430# using specified link flags. Make executable a part of provided 431# test_suite. 432# add_compiler_rt_test(<test_suite> <test_name> <arch> 433# SUBDIR <subdirectory for binary> 434# OBJECTS <object files> 435# DEPS <deps (e.g. runtime libs)> 436# LINK_FLAGS <link flags>) 437function(add_compiler_rt_test test_suite test_name arch) 438 cmake_parse_arguments(TEST "" "SUBDIR" "OBJECTS;DEPS;LINK_FLAGS" "" ${ARGN}) 439 set(output_dir ${CMAKE_CURRENT_BINARY_DIR}) 440 if(TEST_SUBDIR) 441 set(output_dir "${output_dir}/${TEST_SUBDIR}") 442 endif() 443 set(output_dir "${output_dir}/${CMAKE_CFG_INTDIR}") 444 file(MAKE_DIRECTORY "${output_dir}") 445 set(output_bin "${output_dir}/${test_name}") 446 if(MSVC) 447 set(output_bin "${output_bin}.exe") 448 endif() 449 450 # Use host compiler in a standalone build, and just-built Clang otherwise. 451 if(NOT COMPILER_RT_STANDALONE_BUILD) 452 list(APPEND TEST_DEPS clang) 453 endif() 454 455 get_target_flags_for_arch(${arch} TARGET_LINK_FLAGS) 456 list(APPEND TEST_LINK_FLAGS ${TARGET_LINK_FLAGS}) 457 458 # If we're not on MSVC, include the linker flags from CMAKE but override them 459 # with the provided link flags. This ensures that flags which are required to 460 # link programs at all are included, but the changes needed for the test 461 # trump. With MSVC we can't do that because CMake is set up to run link.exe 462 # when linking, not the compiler. Here, we hack it to use the compiler 463 # because we want to use -fsanitize flags. 464 if(NOT MSVC) 465 set(TEST_LINK_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${TEST_LINK_FLAGS}") 466 separate_arguments(TEST_LINK_FLAGS) 467 endif() 468 add_custom_command( 469 OUTPUT "${output_bin}" 470 COMMAND ${COMPILER_RT_TEST_COMPILER} ${TEST_OBJECTS} -o "${output_bin}" 471 ${TEST_LINK_FLAGS} 472 DEPENDS ${TEST_DEPS} 473 ) 474 add_custom_target(T${test_name} DEPENDS "${output_bin}") 475 set_target_properties(T${test_name} PROPERTIES FOLDER "Compiler-RT Tests") 476 477 # Make the test suite depend on the binary. 478 add_dependencies(${test_suite} T${test_name}) 479endfunction() 480 481macro(add_compiler_rt_resource_file target_name file_name component) 482 set(src_file "${CMAKE_CURRENT_SOURCE_DIR}/${file_name}") 483 set(dst_file "${COMPILER_RT_OUTPUT_DIR}/share/${file_name}") 484 add_custom_command(OUTPUT ${dst_file} 485 DEPENDS ${src_file} 486 COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src_file} ${dst_file} 487 COMMENT "Copying ${file_name}...") 488 add_custom_target(${target_name} DEPENDS ${dst_file}) 489 # Install in Clang resource directory. 490 install(FILES ${file_name} 491 DESTINATION ${COMPILER_RT_INSTALL_PATH}/share 492 COMPONENT ${component}) 493 add_dependencies(${component} ${target_name}) 494 495 set_target_properties(${target_name} PROPERTIES FOLDER "Compiler-RT Misc") 496endmacro() 497 498macro(add_compiler_rt_script name) 499 set(dst ${COMPILER_RT_EXEC_OUTPUT_DIR}/${name}) 500 set(src ${CMAKE_CURRENT_SOURCE_DIR}/${name}) 501 add_custom_command(OUTPUT ${dst} 502 DEPENDS ${src} 503 COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst} 504 COMMENT "Copying ${name}...") 505 add_custom_target(${name} DEPENDS ${dst}) 506 install(FILES ${dst} 507 PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE 508 DESTINATION ${COMPILER_RT_INSTALL_PATH}/bin) 509endmacro(add_compiler_rt_script src name) 510 511# Builds custom version of libc++ and installs it in <prefix>. 512# Can be used to build sanitized versions of libc++ for running unit tests. 513# add_custom_libcxx(<name> <prefix> 514# DEPS <list of build deps> 515# CFLAGS <list of compile flags> 516# USE_TOOLCHAIN) 517macro(add_custom_libcxx name prefix) 518 if(NOT COMPILER_RT_LIBCXX_PATH) 519 message(FATAL_ERROR "libcxx not found!") 520 endif() 521 if(NOT COMPILER_RT_LIBCXXABI_PATH) 522 message(FATAL_ERROR "libcxxabi not found!") 523 endif() 524 525 cmake_parse_arguments(LIBCXX "USE_TOOLCHAIN" "" "DEPS;CFLAGS;CMAKE_ARGS" ${ARGN}) 526 527 if(LIBCXX_USE_TOOLCHAIN) 528 set(compiler_args -DCMAKE_C_COMPILER=${COMPILER_RT_TEST_COMPILER} 529 -DCMAKE_CXX_COMPILER=${COMPILER_RT_TEST_CXX_COMPILER}) 530 if(NOT COMPILER_RT_STANDALONE_BUILD AND NOT RUNTIMES_BUILD) 531 set(toolchain_deps $<TARGET_FILE:clang>) 532 set(force_deps DEPENDS $<TARGET_FILE:clang>) 533 endif() 534 else() 535 set(compiler_args -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} 536 -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}) 537 endif() 538 539 set(STAMP_DIR ${prefix}-stamps/) 540 set(BINARY_DIR ${prefix}-bins/) 541 542 add_custom_target(${name}-clear 543 COMMAND ${CMAKE_COMMAND} -E remove_directory ${BINARY_DIR} 544 COMMAND ${CMAKE_COMMAND} -E remove_directory ${STAMP_DIR} 545 COMMENT "Clobbering ${name} build and stamp directories" 546 USES_TERMINAL 547 ) 548 set_target_properties(${name}-clear PROPERTIES FOLDER "Compiler-RT Misc") 549 550 add_custom_command( 551 OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp 552 DEPENDS ${LIBCXX_DEPS} ${toolchain_deps} 553 COMMAND ${CMAKE_COMMAND} -E touch ${BINARY_DIR}/CMakeCache.txt 554 COMMAND ${CMAKE_COMMAND} -E touch ${STAMP_DIR}/${name}-mkdir 555 COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp 556 COMMENT "Clobbering bootstrap build and stamp directories" 557 ) 558 559 add_custom_target(${name}-clobber 560 DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp) 561 set_target_properties(${name}-clobber PROPERTIES FOLDER "Compiler-RT Misc") 562 563 set(PASSTHROUGH_VARIABLES 564 CMAKE_C_COMPILER_TARGET 565 CMAKE_CXX_COMPILER_TARGET 566 CMAKE_SHARED_LINKER_FLAGS 567 CMAKE_MODULE_LINKER_FLAGS 568 CMAKE_EXE_LINKER_FLAGS 569 CMAKE_INSTALL_PREFIX 570 CMAKE_MAKE_PROGRAM 571 CMAKE_LINKER 572 CMAKE_AR 573 CMAKE_RANLIB 574 CMAKE_NM 575 CMAKE_OBJCOPY 576 CMAKE_OBJDUMP 577 CMAKE_STRIP 578 CMAKE_SYSROOT 579 CMAKE_SYSTEM_NAME) 580 foreach(variable ${PASSTHROUGH_VARIABLES}) 581 get_property(is_value_set CACHE ${variable} PROPERTY VALUE SET) 582 if(${is_value_set}) 583 get_property(value CACHE ${variable} PROPERTY VALUE) 584 list(APPEND CMAKE_PASSTHROUGH_VARIABLES -D${variable}=${value}) 585 endif() 586 endforeach() 587 588 string(REPLACE ";" " " LIBCXX_C_FLAGS "${LIBCXX_CFLAGS}") 589 get_property(C_FLAGS CACHE CMAKE_C_FLAGS PROPERTY VALUE) 590 set(LIBCXX_C_FLAGS "${LIBCXX_C_FLAGS} ${C_FLAGS}") 591 592 string(REPLACE ";" " " LIBCXX_CXX_FLAGS "${LIBCXX_CFLAGS}") 593 get_property(CXX_FLAGS CACHE CMAKE_CXX_FLAGS PROPERTY VALUE) 594 set(LIBCXX_CXX_FLAGS "${LIBCXX_CXX_FLAGS} ${CXX_FLAGS}") 595 596 ExternalProject_Add(${name} 597 DEPENDS ${name}-clobber ${LIBCXX_DEPS} 598 PREFIX ${prefix} 599 SOURCE_DIR ${COMPILER_RT_SOURCE_DIR}/cmake/Modules/CustomLibcxx 600 STAMP_DIR ${STAMP_DIR} 601 BINARY_DIR ${BINARY_DIR} 602 CMAKE_ARGS ${CMAKE_PASSTHROUGH_VARIABLES} 603 ${compiler_args} 604 -DCMAKE_C_FLAGS=${LIBCXX_C_FLAGS} 605 -DCMAKE_CXX_FLAGS=${LIBCXX_CXX_FLAGS} 606 -DCMAKE_BUILD_TYPE=Release 607 -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY 608 -DLLVM_PATH=${LLVM_MAIN_SRC_DIR} 609 -DLLVM_BINARY_DIR=${prefix} 610 -DLLVM_LIBRARY_OUTPUT_INTDIR=${prefix}/lib 611 -DCOMPILER_RT_LIBCXX_PATH=${COMPILER_RT_LIBCXX_PATH} 612 -DCOMPILER_RT_LIBCXXABI_PATH=${COMPILER_RT_LIBCXXABI_PATH} 613 ${LIBCXX_CMAKE_ARGS} 614 INSTALL_COMMAND "" 615 STEP_TARGETS configure build 616 BUILD_ALWAYS 1 617 USES_TERMINAL_CONFIGURE 1 618 USES_TERMINAL_BUILD 1 619 USES_TERMINAL_INSTALL 1 620 EXCLUDE_FROM_ALL TRUE 621 ) 622 623 if (CMAKE_GENERATOR MATCHES "Make") 624 set(run_clean "$(MAKE)" "-C" "${BINARY_DIR}" "clean") 625 else() 626 set(run_clean ${CMAKE_COMMAND} --build ${BINARY_DIR} --target clean 627 --config "$<CONFIG>") 628 endif() 629 630 ExternalProject_Add_Step(${name} clean 631 COMMAND ${run_clean} 632 COMMENT "Cleaning ${name}..." 633 DEPENDEES configure 634 ${force_deps} 635 WORKING_DIRECTORY ${BINARY_DIR} 636 EXCLUDE_FROM_MAIN 1 637 USES_TERMINAL 1 638 ) 639 ExternalProject_Add_StepTargets(${name} clean) 640 641 if(LIBCXX_USE_TOOLCHAIN) 642 add_dependencies(${name}-clean ${name}-clobber) 643 set_target_properties(${name}-clean PROPERTIES 644 SOURCES ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp) 645 endif() 646endmacro() 647 648function(rt_externalize_debuginfo name) 649 if(NOT COMPILER_RT_EXTERNALIZE_DEBUGINFO) 650 return() 651 endif() 652 653 if(NOT COMPILER_RT_EXTERNALIZE_DEBUGINFO_SKIP_STRIP) 654 set(strip_command COMMAND xcrun strip -Sl $<TARGET_FILE:${name}>) 655 endif() 656 657 if(APPLE) 658 if(CMAKE_CXX_FLAGS MATCHES "-flto" 659 OR CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE} MATCHES "-flto") 660 661 set(lto_object ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${name}-lto.o) 662 set_property(TARGET ${name} APPEND_STRING PROPERTY 663 LINK_FLAGS " -Wl,-object_path_lto -Wl,${lto_object}") 664 endif() 665 add_custom_command(TARGET ${name} POST_BUILD 666 COMMAND xcrun dsymutil $<TARGET_FILE:${name}> 667 ${strip_command}) 668 else() 669 message(FATAL_ERROR "COMPILER_RT_EXTERNALIZE_DEBUGINFO isn't implemented for non-darwin platforms!") 670 endif() 671endfunction() 672 673 674# Configure lit configuration files, including compiler-rt specific variables. 675function(configure_compiler_rt_lit_site_cfg input output) 676 set_llvm_build_mode() 677 678 get_compiler_rt_output_dir(${COMPILER_RT_DEFAULT_TARGET_ARCH} output_dir) 679 680 string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} COMPILER_RT_RESOLVED_TEST_COMPILER ${COMPILER_RT_TEST_COMPILER}) 681 string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} COMPILER_RT_RESOLVED_LIBRARY_OUTPUT_DIR ${output_dir}) 682 683 configure_lit_site_cfg(${input} ${output}) 684endfunction() 685