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# {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 "^(STATIC|SHARED)$") 148 message(FATAL_ERROR "type argument must be 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 "STATIC") 208 set(libname "${name}-${arch}") 209 set_output_name(output_name_${libname} ${name} ${arch}) 210 else() 211 set(libname "${name}-dynamic-${arch}") 212 set(extra_cflags_${libname} ${TARGET_${arch}_CFLAGS} ${LIB_CFLAGS}) 213 set(extra_link_flags_${libname} ${TARGET_${arch}_LINK_FLAGS} ${LIB_LINK_FLAGS}) 214 if(WIN32) 215 set_output_name(output_name_${libname} ${name}_dynamic ${arch}) 216 else() 217 set_output_name(output_name_${libname} ${name} ${arch}) 218 endif() 219 endif() 220 set(sources_${libname} ${LIB_SOURCES}) 221 format_object_libs(sources_${libname} ${arch} ${LIB_OBJECT_LIBS}) 222 set(libnames ${libnames} ${libname}) 223 set(extra_cflags_${libname} ${TARGET_${arch}_CFLAGS} ${NO_LTO_FLAGS} ${LIB_CFLAGS}) 224 get_compiler_rt_output_dir(${arch} output_dir_${libname}) 225 get_compiler_rt_install_dir(${arch} install_dir_${libname}) 226 endforeach() 227 endif() 228 229 if(NOT libnames) 230 return() 231 endif() 232 233 if(LIB_PARENT_TARGET) 234 # If the parent targets aren't created we should create them 235 if(NOT TARGET ${LIB_PARENT_TARGET}) 236 add_custom_target(${LIB_PARENT_TARGET}) 237 set_target_properties(${LIB_PARENT_TARGET} PROPERTIES 238 FOLDER "Compiler-RT Misc") 239 endif() 240 if(NOT TARGET install-${LIB_PARENT_TARGET}) 241 # The parent install target specifies the parent component to scrape up 242 # anything not installed by the individual install targets, and to handle 243 # installation when running the multi-configuration generators. 244 add_custom_target(install-${LIB_PARENT_TARGET} 245 DEPENDS ${LIB_PARENT_TARGET} 246 COMMAND "${CMAKE_COMMAND}" 247 -DCMAKE_INSTALL_COMPONENT=${LIB_PARENT_TARGET} 248 -P "${CMAKE_BINARY_DIR}/cmake_install.cmake") 249 add_custom_target(install-${LIB_PARENT_TARGET}-stripped 250 DEPENDS ${LIB_PARENT_TARGET} 251 COMMAND "${CMAKE_COMMAND}" 252 -DCMAKE_INSTALL_COMPONENT=${LIB_PARENT_TARGET} 253 -DCMAKE_INSTALL_DO_STRIP=1 254 -P "${CMAKE_BINARY_DIR}/cmake_install.cmake") 255 set_target_properties(install-${LIB_PARENT_TARGET} PROPERTIES 256 FOLDER "Compiler-RT Misc") 257 set_target_properties(install-${LIB_PARENT_TARGET}-stripped PROPERTIES 258 FOLDER "Compiler-RT Misc") 259 add_dependencies(install-compiler-rt install-${LIB_PARENT_TARGET}) 260 add_dependencies(install-compiler-rt-stripped install-${LIB_PARENT_TARGET}-stripped) 261 endif() 262 endif() 263 264 foreach(libname ${libnames}) 265 # If you are using a multi-configuration generator we don't generate 266 # per-library install rules, so we fall back to the parent target COMPONENT 267 if(CMAKE_CONFIGURATION_TYPES AND LIB_PARENT_TARGET) 268 set(COMPONENT_OPTION COMPONENT ${LIB_PARENT_TARGET}) 269 else() 270 set(COMPONENT_OPTION COMPONENT ${libname}) 271 endif() 272 273 add_library(${libname} ${type} ${sources_${libname}}) 274 set_target_compile_flags(${libname} ${extra_cflags_${libname}}) 275 set_target_link_flags(${libname} ${extra_link_flags_${libname}}) 276 set_property(TARGET ${libname} APPEND PROPERTY 277 COMPILE_DEFINITIONS ${LIB_DEFS}) 278 set_target_output_directories(${libname} ${output_dir_${libname}}) 279 set_target_properties(${libname} PROPERTIES 280 OUTPUT_NAME ${output_name_${libname}}) 281 set_target_properties(${libname} PROPERTIES FOLDER "Compiler-RT Runtime") 282 if(LIB_LINK_LIBS) 283 target_link_libraries(${libname} ${LIB_LINK_LIBS}) 284 endif() 285 if(${type} STREQUAL "SHARED") 286 if(COMMAND llvm_setup_rpath) 287 llvm_setup_rpath(${libname}) 288 endif() 289 if(WIN32 AND NOT CYGWIN AND NOT MINGW) 290 set_target_properties(${libname} PROPERTIES IMPORT_PREFIX "") 291 set_target_properties(${libname} PROPERTIES IMPORT_SUFFIX ".lib") 292 endif() 293 if(APPLE) 294 # Ad-hoc sign the dylibs 295 add_custom_command(TARGET ${libname} 296 POST_BUILD 297 COMMAND codesign --sign - $<TARGET_FILE:${libname}> 298 WORKING_DIRECTORY ${COMPILER_RT_LIBRARY_OUTPUT_DIR} 299 ) 300 endif() 301 endif() 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 310 # We only want to generate per-library install targets if you aren't using 311 # an IDE because the extra targets get cluttered in IDEs. 312 if(NOT CMAKE_CONFIGURATION_TYPES) 313 add_custom_target(install-${libname} 314 DEPENDS ${libname} 315 COMMAND "${CMAKE_COMMAND}" 316 -DCMAKE_INSTALL_COMPONENT=${libname} 317 -P "${CMAKE_BINARY_DIR}/cmake_install.cmake") 318 add_custom_target(install-${libname}-stripped 319 DEPENDS ${libname} 320 COMMAND "${CMAKE_COMMAND}" 321 -DCMAKE_INSTALL_COMPONENT=${libname} 322 -DCMAKE_INSTALL_DO_STRIP=1 323 -P "${CMAKE_BINARY_DIR}/cmake_install.cmake") 324 # If you have a parent target specified, we bind the new install target 325 # to the parent install target. 326 if(LIB_PARENT_TARGET) 327 add_dependencies(install-${LIB_PARENT_TARGET} install-${libname}) 328 add_dependencies(install-${LIB_PARENT_TARGET}-stripped install-${libname}-stripped) 329 endif() 330 endif() 331 if(APPLE) 332 set_target_properties(${libname} PROPERTIES 333 OSX_ARCHITECTURES "${LIB_ARCHS_${libname}}") 334 endif() 335 336 if(type STREQUAL "SHARED") 337 rt_externalize_debuginfo(${libname}) 338 endif() 339 endforeach() 340 if(LIB_PARENT_TARGET) 341 add_dependencies(${LIB_PARENT_TARGET} ${libnames}) 342 endif() 343endfunction() 344 345# when cross compiling, COMPILER_RT_TEST_COMPILER_CFLAGS help 346# in compilation and linking of unittests. 347string(REPLACE " " ";" COMPILER_RT_UNITTEST_CFLAGS "${COMPILER_RT_TEST_COMPILER_CFLAGS}") 348set(COMPILER_RT_UNITTEST_LINK_FLAGS ${COMPILER_RT_UNITTEST_CFLAGS}) 349 350# Unittests support. 351set(COMPILER_RT_GTEST_PATH ${LLVM_MAIN_SRC_DIR}/utils/unittest/googletest) 352set(COMPILER_RT_GTEST_SOURCE ${COMPILER_RT_GTEST_PATH}/src/gtest-all.cc) 353set(COMPILER_RT_GTEST_CFLAGS 354 -DGTEST_NO_LLVM_RAW_OSTREAM=1 355 -DGTEST_HAS_RTTI=0 356 -I${COMPILER_RT_GTEST_PATH}/include 357 -I${COMPILER_RT_GTEST_PATH} 358) 359 360# Mocking support. 361set(COMPILER_RT_GMOCK_PATH ${LLVM_MAIN_SRC_DIR}/utils/unittest/googlemock) 362set(COMPILER_RT_GMOCK_SOURCE ${COMPILER_RT_GMOCK_PATH}/src/gmock-all.cc) 363set(COMPILER_RT_GMOCK_CFLAGS 364 -DGTEST_NO_LLVM_RAW_OSTREAM=1 365 -DGTEST_HAS_RTTI=0 366 -I${COMPILER_RT_GMOCK_PATH}/include 367 -I${COMPILER_RT_GMOCK_PATH} 368) 369 370append_list_if(COMPILER_RT_DEBUG -DSANITIZER_DEBUG=1 COMPILER_RT_UNITTEST_CFLAGS) 371append_list_if(COMPILER_RT_HAS_WCOVERED_SWITCH_DEFAULT_FLAG -Wno-covered-switch-default COMPILER_RT_UNITTEST_CFLAGS) 372 373if(MSVC) 374 # gtest use a lot of stuff marked as deprecated on Windows. 375 list(APPEND COMPILER_RT_GTEST_CFLAGS -Wno-deprecated-declarations) 376endif() 377 378# Compile and register compiler-rt tests. 379# generate_compiler_rt_tests(<output object files> <test_suite> <test_name> 380# <test architecture> 381# KIND <custom prefix> 382# SUBDIR <subdirectory for testing binary> 383# SOURCES <sources to compile> 384# RUNTIME <tests runtime to link in> 385# CFLAGS <compile-time flags> 386# COMPILE_DEPS <compile-time dependencies> 387# DEPS <dependencies> 388# LINK_FLAGS <flags to use during linking> 389# ) 390function(generate_compiler_rt_tests test_objects test_suite testname arch) 391 cmake_parse_arguments(TEST "" "KIND;RUNTIME;SUBDIR" 392 "SOURCES;COMPILE_DEPS;DEPS;CFLAGS;LINK_FLAGS" ${ARGN}) 393 394 foreach(source ${TEST_SOURCES}) 395 sanitizer_test_compile( 396 "${test_objects}" "${source}" "${arch}" 397 KIND ${TEST_KIND} 398 COMPILE_DEPS ${TEST_COMPILE_DEPS} 399 DEPS ${TEST_DEPS} 400 CFLAGS ${TEST_CFLAGS} 401 ) 402 endforeach() 403 404 set(TEST_DEPS ${${test_objects}}) 405 406 if(NOT "${TEST_RUNTIME}" STREQUAL "") 407 list(APPEND TEST_DEPS ${TEST_RUNTIME}) 408 list(APPEND "${test_objects}" $<TARGET_FILE:${TEST_RUNTIME}>) 409 endif() 410 411 add_compiler_rt_test(${test_suite} "${testname}" "${arch}" 412 SUBDIR ${TEST_SUBDIR} 413 OBJECTS ${${test_objects}} 414 DEPS ${TEST_DEPS} 415 LINK_FLAGS ${TEST_LINK_FLAGS} 416 ) 417 set("${test_objects}" "${${test_objects}}" PARENT_SCOPE) 418endfunction() 419 420# Link objects into a single executable with COMPILER_RT_TEST_COMPILER, 421# using specified link flags. Make executable a part of provided 422# test_suite. 423# add_compiler_rt_test(<test_suite> <test_name> <arch> 424# SUBDIR <subdirectory for binary> 425# OBJECTS <object files> 426# DEPS <deps (e.g. runtime libs)> 427# LINK_FLAGS <link flags>) 428function(add_compiler_rt_test test_suite test_name arch) 429 cmake_parse_arguments(TEST "" "SUBDIR" "OBJECTS;DEPS;LINK_FLAGS" "" ${ARGN}) 430 set(output_dir ${CMAKE_CURRENT_BINARY_DIR}) 431 if(TEST_SUBDIR) 432 set(output_dir "${output_dir}/${TEST_SUBDIR}") 433 endif() 434 set(output_dir "${output_dir}/${CMAKE_CFG_INTDIR}") 435 file(MAKE_DIRECTORY "${output_dir}") 436 set(output_bin "${output_dir}/${test_name}") 437 if(MSVC) 438 set(output_bin "${output_bin}.exe") 439 endif() 440 441 # Use host compiler in a standalone build, and just-built Clang otherwise. 442 if(NOT COMPILER_RT_STANDALONE_BUILD) 443 list(APPEND TEST_DEPS clang) 444 endif() 445 446 get_target_flags_for_arch(${arch} TARGET_LINK_FLAGS) 447 list(APPEND TEST_LINK_FLAGS ${TARGET_LINK_FLAGS}) 448 449 # If we're not on MSVC, include the linker flags from CMAKE but override them 450 # with the provided link flags. This ensures that flags which are required to 451 # link programs at all are included, but the changes needed for the test 452 # trump. With MSVC we can't do that because CMake is set up to run link.exe 453 # when linking, not the compiler. Here, we hack it to use the compiler 454 # because we want to use -fsanitize flags. 455 if(NOT MSVC) 456 set(TEST_LINK_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${TEST_LINK_FLAGS}") 457 separate_arguments(TEST_LINK_FLAGS) 458 endif() 459 add_custom_command( 460 OUTPUT "${output_bin}" 461 COMMAND ${COMPILER_RT_TEST_COMPILER} ${TEST_OBJECTS} -o "${output_bin}" 462 ${TEST_LINK_FLAGS} 463 DEPENDS ${TEST_DEPS} 464 ) 465 add_custom_target(T${test_name} DEPENDS "${output_bin}") 466 set_target_properties(T${test_name} PROPERTIES FOLDER "Compiler-RT Tests") 467 468 # Make the test suite depend on the binary. 469 add_dependencies(${test_suite} T${test_name}) 470endfunction() 471 472macro(add_compiler_rt_resource_file target_name file_name component) 473 set(src_file "${CMAKE_CURRENT_SOURCE_DIR}/${file_name}") 474 set(dst_file "${COMPILER_RT_OUTPUT_DIR}/share/${file_name}") 475 add_custom_command(OUTPUT ${dst_file} 476 DEPENDS ${src_file} 477 COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src_file} ${dst_file} 478 COMMENT "Copying ${file_name}...") 479 add_custom_target(${target_name} DEPENDS ${dst_file}) 480 # Install in Clang resource directory. 481 install(FILES ${file_name} 482 DESTINATION ${COMPILER_RT_INSTALL_PATH}/share 483 COMPONENT ${component}) 484 add_dependencies(${component} ${target_name}) 485 486 set_target_properties(${target_name} PROPERTIES FOLDER "Compiler-RT Misc") 487endmacro() 488 489macro(add_compiler_rt_script name) 490 set(dst ${COMPILER_RT_EXEC_OUTPUT_DIR}/${name}) 491 set(src ${CMAKE_CURRENT_SOURCE_DIR}/${name}) 492 add_custom_command(OUTPUT ${dst} 493 DEPENDS ${src} 494 COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst} 495 COMMENT "Copying ${name}...") 496 add_custom_target(${name} DEPENDS ${dst}) 497 install(FILES ${dst} 498 PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE 499 DESTINATION ${COMPILER_RT_INSTALL_PATH}/bin) 500endmacro(add_compiler_rt_script src name) 501 502# Builds custom version of libc++ and installs it in <prefix>. 503# Can be used to build sanitized versions of libc++ for running unit tests. 504# add_custom_libcxx(<name> <prefix> 505# DEPS <list of build deps> 506# CFLAGS <list of compile flags> 507# USE_TOOLCHAIN) 508macro(add_custom_libcxx name prefix) 509 if(NOT COMPILER_RT_LIBCXX_PATH) 510 message(FATAL_ERROR "libcxx not found!") 511 endif() 512 513 cmake_parse_arguments(LIBCXX "USE_TOOLCHAIN" "" "DEPS;CFLAGS;CMAKE_ARGS" ${ARGN}) 514 515 if(LIBCXX_USE_TOOLCHAIN) 516 set(compiler_args -DCMAKE_C_COMPILER=${COMPILER_RT_TEST_COMPILER} 517 -DCMAKE_CXX_COMPILER=${COMPILER_RT_TEST_CXX_COMPILER}) 518 if(NOT COMPILER_RT_STANDALONE_BUILD) 519 set(toolchain_deps $<TARGET_FILE:clang>) 520 set(force_deps DEPENDS $<TARGET_FILE:clang>) 521 endif() 522 else() 523 set(compiler_args -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} 524 -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}) 525 endif() 526 527 set(STAMP_DIR ${prefix}-stamps/) 528 set(BINARY_DIR ${prefix}-bins/) 529 530 add_custom_target(${name}-clear 531 COMMAND ${CMAKE_COMMAND} -E remove_directory ${BINARY_DIR} 532 COMMAND ${CMAKE_COMMAND} -E remove_directory ${STAMP_DIR} 533 COMMENT "Clobbering ${name} build and stamp directories" 534 USES_TERMINAL 535 ) 536 set_target_properties(${name}-clear PROPERTIES FOLDER "Compiler-RT Misc") 537 538 add_custom_command( 539 OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp 540 DEPENDS ${LIBCXX_DEPS} ${toolchain_deps} 541 COMMAND ${CMAKE_COMMAND} -E touch ${BINARY_DIR}/CMakeCache.txt 542 COMMAND ${CMAKE_COMMAND} -E touch ${STAMP_DIR}/${name}-mkdir 543 COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp 544 COMMENT "Clobbering bootstrap build and stamp directories" 545 ) 546 547 add_custom_target(${name}-clobber 548 DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp) 549 set_target_properties(${name}-clobber PROPERTIES FOLDER "Compiler-RT Misc") 550 551 set(PASSTHROUGH_VARIABLES 552 CMAKE_C_COMPILER_TARGET 553 CMAKE_CXX_COMPILER_TARGET 554 CMAKE_SHARED_LINKER_FLAGS 555 CMAKE_MODULE_LINKER_FLAGS 556 CMAKE_EXE_LINKER_FLAGS 557 CMAKE_INSTALL_PREFIX 558 CMAKE_MAKE_PROGRAM 559 CMAKE_LINKER 560 CMAKE_AR 561 CMAKE_RANLIB 562 CMAKE_NM 563 CMAKE_OBJCOPY 564 CMAKE_OBJDUMP 565 CMAKE_STRIP 566 CMAKE_SYSROOT 567 CMAKE_SYSTEM_NAME) 568 foreach(variable ${PASSTHROUGH_VARIABLES}) 569 get_property(is_value_set CACHE ${variable} PROPERTY VALUE SET) 570 if(${is_value_set}) 571 get_property(value CACHE ${variable} PROPERTY VALUE) 572 list(APPEND CMAKE_PASSTHROUGH_VARIABLES -D${variable}=${value}) 573 endif() 574 endforeach() 575 576 string(REPLACE ";" " " LIBCXX_C_FLAGS "${LIBCXX_CFLAGS}") 577 get_property(C_FLAGS CACHE CMAKE_C_FLAGS PROPERTY VALUE) 578 set(LIBCXX_C_FLAGS "${LIBCXX_C_FLAGS} ${C_FLAGS}") 579 580 string(REPLACE ";" " " LIBCXX_CXX_FLAGS "${LIBCXX_CFLAGS}") 581 get_property(CXX_FLAGS CACHE CMAKE_CXX_FLAGS PROPERTY VALUE) 582 set(LIBCXX_CXX_FLAGS "${LIBCXX_CXX_FLAGS} ${CXX_FLAGS}") 583 584 ExternalProject_Add(${name} 585 DEPENDS ${name}-clobber ${LIBCXX_DEPS} 586 PREFIX ${prefix} 587 SOURCE_DIR ${COMPILER_RT_LIBCXX_PATH} 588 STAMP_DIR ${STAMP_DIR} 589 BINARY_DIR ${BINARY_DIR} 590 CMAKE_ARGS ${CMAKE_PASSTHROUGH_VARIABLES} 591 ${compiler_args} 592 -DCMAKE_C_FLAGS=${LIBCXX_C_FLAGS} 593 -DCMAKE_CXX_FLAGS=${LIBCXX_CXX_FLAGS} 594 -DCMAKE_BUILD_TYPE=Release 595 -DLLVM_PATH=${LLVM_MAIN_SRC_DIR} 596 -DLLVM_BINARY_DIR=${prefix} 597 -DLLVM_LIBRARY_OUTPUT_INTDIR=${prefix}/lib 598 -DLIBCXX_STANDALONE_BUILD=ON 599 ${LIBCXX_CMAKE_ARGS} 600 INSTALL_COMMAND "" 601 STEP_TARGETS configure build 602 BUILD_ALWAYS 1 603 USES_TERMINAL_CONFIGURE 1 604 USES_TERMINAL_BUILD 1 605 USES_TERMINAL_INSTALL 1 606 EXCLUDE_FROM_ALL TRUE 607 ) 608 609 if (CMAKE_GENERATOR MATCHES "Make") 610 set(run_clean "$(MAKE)" "-C" "${BINARY_DIR}" "clean") 611 else() 612 set(run_clean ${CMAKE_COMMAND} --build ${BINARY_DIR} --target clean 613 --config "$<CONFIGURATION>") 614 endif() 615 616 ExternalProject_Add_Step(${name} clean 617 COMMAND ${run_clean} 618 COMMENT "Cleaning ${name}..." 619 DEPENDEES configure 620 ${force_deps} 621 WORKING_DIRECTORY ${BINARY_DIR} 622 EXCLUDE_FROM_MAIN 1 623 USES_TERMINAL 1 624 ) 625 ExternalProject_Add_StepTargets(${name} clean) 626 627 if(LIBCXX_USE_TOOLCHAIN) 628 add_dependencies(${name}-clean ${name}-clobber) 629 set_target_properties(${name}-clean PROPERTIES 630 SOURCES ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp) 631 endif() 632endmacro() 633 634function(rt_externalize_debuginfo name) 635 if(NOT COMPILER_RT_EXTERNALIZE_DEBUGINFO) 636 return() 637 endif() 638 639 if(NOT COMPILER_RT_EXTERNALIZE_DEBUGINFO_SKIP_STRIP) 640 set(strip_command COMMAND xcrun strip -Sl $<TARGET_FILE:${name}>) 641 endif() 642 643 if(APPLE) 644 if(CMAKE_CXX_FLAGS MATCHES "-flto" 645 OR CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE} MATCHES "-flto") 646 647 set(lto_object ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${name}-lto.o) 648 set_property(TARGET ${name} APPEND_STRING PROPERTY 649 LINK_FLAGS " -Wl,-object_path_lto -Wl,${lto_object}") 650 endif() 651 add_custom_command(TARGET ${name} POST_BUILD 652 COMMAND xcrun dsymutil $<TARGET_FILE:${name}> 653 ${strip_command}) 654 else() 655 message(FATAL_ERROR "COMPILER_RT_EXTERNALIZE_DEBUGINFO isn't implemented for non-darwin platforms!") 656 endif() 657endfunction() 658 659 660# Configure lit configuration files, including compiler-rt specific variables. 661function(configure_compiler_rt_lit_site_cfg input output) 662 set_llvm_build_mode() 663 664 get_compiler_rt_output_dir(${COMPILER_RT_DEFAULT_TARGET_ARCH} output_dir) 665 666 string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} COMPILER_RT_RESOLVED_TEST_COMPILER ${COMPILER_RT_TEST_COMPILER}) 667 string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} COMPILER_RT_RESOLVED_LIBRARY_OUTPUT_DIR ${output_dir}) 668 669 configure_lit_site_cfg(${input} ${output}) 670endfunction() 671