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 ${CMAKE_CXX_FLAGS} ${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 360append_list_if(COMPILER_RT_DEBUG -DSANITIZER_DEBUG=1 COMPILER_RT_UNITTEST_CFLAGS) 361append_list_if(COMPILER_RT_HAS_WCOVERED_SWITCH_DEFAULT_FLAG -Wno-covered-switch-default COMPILER_RT_UNITTEST_CFLAGS) 362 363if(MSVC) 364 # clang doesn't support exceptions on Windows yet. 365 list(APPEND COMPILER_RT_UNITTEST_CFLAGS -D_HAS_EXCEPTIONS=0) 366 367 # We should teach clang to understand "#pragma intrinsic", see PR19898. 368 list(APPEND COMPILER_RT_UNITTEST_CFLAGS -Wno-undefined-inline) 369 370 # Clang doesn't support SEH on Windows yet. 371 list(APPEND COMPILER_RT_GTEST_CFLAGS -DGTEST_HAS_SEH=0) 372 373 # gtest use a lot of stuff marked as deprecated on Windows. 374 list(APPEND COMPILER_RT_GTEST_CFLAGS -Wno-deprecated-declarations) 375endif() 376 377# Compile and register compiler-rt tests. 378# generate_compiler_rt_tests(<output object files> <test_suite> <test_name> 379# <test architecture> 380# KIND <custom prefix> 381# SUBDIR <subdirectory for testing binary> 382# SOURCES <sources to compile> 383# RUNTIME <tests runtime to link in> 384# CFLAGS <compile-time flags> 385# COMPILE_DEPS <compile-time dependencies> 386# DEPS <dependencies> 387# LINK_FLAGS <flags to use during linking> 388# ) 389function(generate_compiler_rt_tests test_objects test_suite testname arch) 390 cmake_parse_arguments(TEST "" "KIND;RUNTIME;SUBDIR" 391 "SOURCES;COMPILE_DEPS;DEPS;CFLAGS;LINK_FLAGS" ${ARGN}) 392 393 foreach(source ${TEST_SOURCES}) 394 sanitizer_test_compile( 395 "${test_objects}" "${source}" "${arch}" 396 KIND ${TEST_KIND} 397 COMPILE_DEPS ${TEST_COMPILE_DEPS} 398 DEPS ${TEST_DEPS} 399 CFLAGS ${TEST_CFLAGS} 400 ) 401 endforeach() 402 403 set(TEST_DEPS ${${test_objects}}) 404 405 if(NOT "${TEST_RUNTIME}" STREQUAL "") 406 list(APPEND TEST_DEPS ${TEST_RUNTIME}) 407 list(APPEND "${test_objects}" $<TARGET_FILE:${TEST_RUNTIME}>) 408 endif() 409 410 add_compiler_rt_test(${test_suite} "${testname}" "${arch}" 411 SUBDIR ${TEST_SUBDIR} 412 OBJECTS ${${test_objects}} 413 DEPS ${TEST_DEPS} 414 LINK_FLAGS ${TEST_LINK_FLAGS} 415 ) 416 set("${test_objects}" "${${test_objects}}" PARENT_SCOPE) 417endfunction() 418 419# Link objects into a single executable with COMPILER_RT_TEST_COMPILER, 420# using specified link flags. Make executable a part of provided 421# test_suite. 422# add_compiler_rt_test(<test_suite> <test_name> <arch> 423# SUBDIR <subdirectory for binary> 424# OBJECTS <object files> 425# DEPS <deps (e.g. runtime libs)> 426# LINK_FLAGS <link flags>) 427function(add_compiler_rt_test test_suite test_name arch) 428 cmake_parse_arguments(TEST "" "SUBDIR" "OBJECTS;DEPS;LINK_FLAGS" "" ${ARGN}) 429 set(output_dir ${CMAKE_CURRENT_BINARY_DIR}) 430 if(TEST_SUBDIR) 431 set(output_dir "${output_dir}/${TEST_SUBDIR}") 432 endif() 433 set(output_dir "${output_dir}/${CMAKE_CFG_INTDIR}") 434 file(MAKE_DIRECTORY "${output_dir}") 435 set(output_bin "${output_dir}/${test_name}") 436 if(MSVC) 437 set(output_bin "${output_bin}.exe") 438 endif() 439 440 # Use host compiler in a standalone build, and just-built Clang otherwise. 441 if(NOT COMPILER_RT_STANDALONE_BUILD) 442 list(APPEND TEST_DEPS clang) 443 endif() 444 445 get_target_flags_for_arch(${arch} TARGET_LINK_FLAGS) 446 list(APPEND TEST_LINK_FLAGS ${TARGET_LINK_FLAGS}) 447 448 # If we're not on MSVC, include the linker flags from CMAKE but override them 449 # with the provided link flags. This ensures that flags which are required to 450 # link programs at all are included, but the changes needed for the test 451 # trump. With MSVC we can't do that because CMake is set up to run link.exe 452 # when linking, not the compiler. Here, we hack it to use the compiler 453 # because we want to use -fsanitize flags. 454 if(NOT MSVC) 455 set(TEST_LINK_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${TEST_LINK_FLAGS}") 456 separate_arguments(TEST_LINK_FLAGS) 457 endif() 458 add_custom_command( 459 OUTPUT "${output_bin}" 460 COMMAND ${COMPILER_RT_TEST_COMPILER} ${TEST_OBJECTS} -o "${output_bin}" 461 ${TEST_LINK_FLAGS} 462 DEPENDS ${TEST_DEPS} 463 ) 464 add_custom_target(T${test_name} DEPENDS "${output_bin}") 465 set_target_properties(T${test_name} PROPERTIES FOLDER "Compiler-RT Tests") 466 467 # Make the test suite depend on the binary. 468 add_dependencies(${test_suite} T${test_name}) 469endfunction() 470 471macro(add_compiler_rt_resource_file target_name file_name component) 472 set(src_file "${CMAKE_CURRENT_SOURCE_DIR}/${file_name}") 473 set(dst_file "${COMPILER_RT_OUTPUT_DIR}/share/${file_name}") 474 add_custom_command(OUTPUT ${dst_file} 475 DEPENDS ${src_file} 476 COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src_file} ${dst_file} 477 COMMENT "Copying ${file_name}...") 478 add_custom_target(${target_name} DEPENDS ${dst_file}) 479 # Install in Clang resource directory. 480 install(FILES ${file_name} 481 DESTINATION ${COMPILER_RT_INSTALL_PATH}/share 482 COMPONENT ${component}) 483 add_dependencies(${component} ${target_name}) 484 485 set_target_properties(${target_name} PROPERTIES FOLDER "Compiler-RT Misc") 486endmacro() 487 488macro(add_compiler_rt_script name) 489 set(dst ${COMPILER_RT_EXEC_OUTPUT_DIR}/${name}) 490 set(src ${CMAKE_CURRENT_SOURCE_DIR}/${name}) 491 add_custom_command(OUTPUT ${dst} 492 DEPENDS ${src} 493 COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst} 494 COMMENT "Copying ${name}...") 495 add_custom_target(${name} DEPENDS ${dst}) 496 install(FILES ${dst} 497 PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE 498 DESTINATION ${COMPILER_RT_INSTALL_PATH}/bin) 499endmacro(add_compiler_rt_script src name) 500 501# Builds custom version of libc++ and installs it in <prefix>. 502# Can be used to build sanitized versions of libc++ for running unit tests. 503# add_custom_libcxx(<name> <prefix> 504# DEPS <list of build deps> 505# CFLAGS <list of compile flags> 506# USE_TOOLCHAIN) 507macro(add_custom_libcxx name prefix) 508 if(NOT COMPILER_RT_LIBCXX_PATH) 509 message(FATAL_ERROR "libcxx not found!") 510 endif() 511 512 cmake_parse_arguments(LIBCXX "USE_TOOLCHAIN" "" "DEPS;CFLAGS;CMAKE_ARGS" ${ARGN}) 513 514 if(LIBCXX_USE_TOOLCHAIN) 515 set(compiler_args -DCMAKE_C_COMPILER=${COMPILER_RT_TEST_COMPILER} 516 -DCMAKE_CXX_COMPILER=${COMPILER_RT_TEST_CXX_COMPILER}) 517 if(NOT COMPILER_RT_STANDALONE_BUILD) 518 set(toolchain_deps $<TARGET_FILE:clang>) 519 set(force_deps DEPENDS $<TARGET_FILE:clang>) 520 endif() 521 else() 522 set(compiler_args -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} 523 -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}) 524 endif() 525 526 set(STAMP_DIR ${prefix}-stamps/) 527 set(BINARY_DIR ${prefix}-bins/) 528 529 add_custom_target(${name}-clear 530 COMMAND ${CMAKE_COMMAND} -E remove_directory ${BINARY_DIR} 531 COMMAND ${CMAKE_COMMAND} -E remove_directory ${STAMP_DIR} 532 COMMENT "Clobbering ${name} build and stamp directories" 533 USES_TERMINAL 534 ) 535 set_target_properties(${name}-clear PROPERTIES FOLDER "Compiler-RT Misc") 536 537 add_custom_command( 538 OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp 539 DEPENDS ${LIBCXX_DEPS} ${toolchain_deps} 540 COMMAND ${CMAKE_COMMAND} -E touch ${BINARY_DIR}/CMakeCache.txt 541 COMMAND ${CMAKE_COMMAND} -E touch ${STAMP_DIR}/${name}-mkdir 542 COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp 543 COMMENT "Clobbering bootstrap build and stamp directories" 544 ) 545 546 add_custom_target(${name}-clobber 547 DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp) 548 set_target_properties(${name}-clobber PROPERTIES FOLDER "Compiler-RT Misc") 549 550 set(PASSTHROUGH_VARIABLES 551 CMAKE_C_COMPILER_TARGET 552 CMAKE_CXX_COMPILER_TARGET 553 CMAKE_INSTALL_PREFIX 554 CMAKE_MAKE_PROGRAM 555 CMAKE_LINKER 556 CMAKE_AR 557 CMAKE_RANLIB 558 CMAKE_NM 559 CMAKE_OBJCOPY 560 CMAKE_OBJDUMP 561 CMAKE_STRIP 562 CMAKE_SYSROOT 563 CMAKE_SYSTEM_NAME) 564 foreach(variable ${PASSTHROUGH_VARIABLES}) 565 if(${variable}) 566 list(APPEND CMAKE_PASSTHROUGH_VARIABLES -D${variable}=${${variable}}) 567 endif() 568 endforeach() 569 570 string(REPLACE ";" " " FLAGS_STRING "${LIBCXX_CFLAGS}") 571 set(LIBCXX_C_FLAGS "${FLAGS_STRING}") 572 set(LIBCXX_CXX_FLAGS "${FLAGS_STRING}") 573 574 ExternalProject_Add(${name} 575 DEPENDS ${name}-clobber ${LIBCXX_DEPS} 576 PREFIX ${prefix} 577 SOURCE_DIR ${COMPILER_RT_LIBCXX_PATH} 578 STAMP_DIR ${STAMP_DIR} 579 BINARY_DIR ${BINARY_DIR} 580 CMAKE_ARGS ${CMAKE_PASSTHROUGH_VARIABLES} 581 ${compiler_args} 582 -DCMAKE_C_FLAGS=${LIBCXX_C_FLAGS} 583 -DCMAKE_CXX_FLAGS=${LIBCXX_CXX_FLAGS} 584 -DCMAKE_BUILD_TYPE=Release 585 -DLLVM_PATH=${LLVM_MAIN_SRC_DIR} 586 -DLLVM_BINARY_DIR=${prefix} 587 -DLLVM_LIBRARY_OUTPUT_INTDIR=${prefix}/lib 588 -DLIBCXX_STANDALONE_BUILD=ON 589 ${LIBCXX_CMAKE_ARGS} 590 INSTALL_COMMAND "" 591 STEP_TARGETS configure build 592 BUILD_ALWAYS 1 593 USES_TERMINAL_CONFIGURE 1 594 USES_TERMINAL_BUILD 1 595 USES_TERMINAL_INSTALL 1 596 EXCLUDE_FROM_ALL TRUE 597 ) 598 599 if (CMAKE_GENERATOR MATCHES "Make") 600 set(run_clean "$(MAKE)" "-C" "${BINARY_DIR}" "clean") 601 else() 602 set(run_clean ${CMAKE_COMMAND} --build ${BINARY_DIR} --target clean 603 --config "$<CONFIGURATION>") 604 endif() 605 606 ExternalProject_Add_Step(${name} clean 607 COMMAND ${run_clean} 608 COMMENT "Cleaning ${name}..." 609 DEPENDEES configure 610 ${force_deps} 611 WORKING_DIRECTORY ${BINARY_DIR} 612 EXCLUDE_FROM_MAIN 1 613 USES_TERMINAL 1 614 ) 615 ExternalProject_Add_StepTargets(${name} clean) 616 617 if(LIBCXX_USE_TOOLCHAIN) 618 add_dependencies(${name}-clean ${name}-clobber) 619 set_target_properties(${name}-clean PROPERTIES 620 SOURCES ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp) 621 endif() 622endmacro() 623 624function(rt_externalize_debuginfo name) 625 if(NOT COMPILER_RT_EXTERNALIZE_DEBUGINFO) 626 return() 627 endif() 628 629 if(NOT COMPILER_RT_EXTERNALIZE_DEBUGINFO_SKIP_STRIP) 630 set(strip_command COMMAND xcrun strip -Sl $<TARGET_FILE:${name}>) 631 endif() 632 633 if(APPLE) 634 if(CMAKE_CXX_FLAGS MATCHES "-flto" 635 OR CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE} MATCHES "-flto") 636 637 set(lto_object ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${name}-lto.o) 638 set_property(TARGET ${name} APPEND_STRING PROPERTY 639 LINK_FLAGS " -Wl,-object_path_lto -Wl,${lto_object}") 640 endif() 641 add_custom_command(TARGET ${name} POST_BUILD 642 COMMAND xcrun dsymutil $<TARGET_FILE:${name}> 643 ${strip_command}) 644 else() 645 message(FATAL_ERROR "COMPILER_RT_EXTERNALIZE_DEBUGINFO isn't implemented for non-darwin platforms!") 646 endif() 647endfunction() 648 649 650# Configure lit configuration files, including compiler-rt specific variables. 651function(configure_compiler_rt_lit_site_cfg input output) 652 set_llvm_build_mode() 653 654 get_compiler_rt_output_dir(${COMPILER_RT_DEFAULT_TARGET_ARCH} output_dir) 655 656 string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} COMPILER_RT_RESOLVED_TEST_COMPILER ${COMPILER_RT_TEST_COMPILER}) 657 string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} COMPILER_RT_RESOLVED_LIBRARY_OUTPUT_DIR ${output_dir}) 658 659 configure_lit_site_cfg(${input} ${output}) 660endfunction() 661