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_SUPPORT=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_SUPPORT=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 if(NOT COMPILER_RT_STANDALONE_BUILD AND COMPILER_RT_HAS_LLD AND "lld" IN_LIST LLVM_ENABLE_PROJECTS) 469 # CMAKE_EXE_LINKER_FLAGS may contain -fuse=lld 470 # FIXME: -DLLVM_ENABLE_LLD=ON and -DLLVM_ENABLE_PROJECTS without lld case. 471 list(APPEND TEST_DEPS lld) 472 endif() 473 add_custom_command( 474 OUTPUT "${output_bin}" 475 COMMAND ${COMPILER_RT_TEST_COMPILER} ${TEST_OBJECTS} -o "${output_bin}" 476 ${TEST_LINK_FLAGS} 477 DEPENDS ${TEST_DEPS} 478 ) 479 add_custom_target(T${test_name} DEPENDS "${output_bin}") 480 set_target_properties(T${test_name} PROPERTIES FOLDER "Compiler-RT Tests") 481 482 # Make the test suite depend on the binary. 483 add_dependencies(${test_suite} T${test_name}) 484endfunction() 485 486macro(add_compiler_rt_resource_file target_name file_name component) 487 set(src_file "${CMAKE_CURRENT_SOURCE_DIR}/${file_name}") 488 set(dst_file "${COMPILER_RT_OUTPUT_DIR}/share/${file_name}") 489 add_custom_command(OUTPUT ${dst_file} 490 DEPENDS ${src_file} 491 COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src_file} ${dst_file} 492 COMMENT "Copying ${file_name}...") 493 add_custom_target(${target_name} DEPENDS ${dst_file}) 494 # Install in Clang resource directory. 495 install(FILES ${file_name} 496 DESTINATION ${COMPILER_RT_INSTALL_PATH}/share 497 COMPONENT ${component}) 498 add_dependencies(${component} ${target_name}) 499 500 set_target_properties(${target_name} PROPERTIES FOLDER "Compiler-RT Misc") 501endmacro() 502 503macro(add_compiler_rt_script name) 504 set(dst ${COMPILER_RT_EXEC_OUTPUT_DIR}/${name}) 505 set(src ${CMAKE_CURRENT_SOURCE_DIR}/${name}) 506 add_custom_command(OUTPUT ${dst} 507 DEPENDS ${src} 508 COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst} 509 COMMENT "Copying ${name}...") 510 add_custom_target(${name} DEPENDS ${dst}) 511 install(FILES ${dst} 512 PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE 513 DESTINATION ${COMPILER_RT_INSTALL_PATH}/bin) 514endmacro(add_compiler_rt_script src name) 515 516# Builds custom version of libc++ and installs it in <prefix>. 517# Can be used to build sanitized versions of libc++ for running unit tests. 518# add_custom_libcxx(<name> <prefix> 519# DEPS <list of build deps> 520# CFLAGS <list of compile flags> 521# USE_TOOLCHAIN) 522macro(add_custom_libcxx name prefix) 523 if(NOT COMPILER_RT_LIBCXX_PATH) 524 message(FATAL_ERROR "libcxx not found!") 525 endif() 526 if(NOT COMPILER_RT_LIBCXXABI_PATH) 527 message(FATAL_ERROR "libcxxabi not found!") 528 endif() 529 530 cmake_parse_arguments(LIBCXX "USE_TOOLCHAIN" "" "DEPS;CFLAGS;CMAKE_ARGS" ${ARGN}) 531 532 if(LIBCXX_USE_TOOLCHAIN) 533 set(compiler_args -DCMAKE_C_COMPILER=${COMPILER_RT_TEST_COMPILER} 534 -DCMAKE_CXX_COMPILER=${COMPILER_RT_TEST_CXX_COMPILER}) 535 if(NOT COMPILER_RT_STANDALONE_BUILD AND NOT RUNTIMES_BUILD) 536 set(toolchain_deps $<TARGET_FILE:clang>) 537 set(force_deps DEPENDS $<TARGET_FILE:clang>) 538 endif() 539 else() 540 set(compiler_args -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} 541 -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}) 542 endif() 543 544 set(STAMP_DIR ${prefix}-stamps/) 545 set(BINARY_DIR ${prefix}-bins/) 546 547 add_custom_target(${name}-clear 548 COMMAND ${CMAKE_COMMAND} -E remove_directory ${BINARY_DIR} 549 COMMAND ${CMAKE_COMMAND} -E remove_directory ${STAMP_DIR} 550 COMMENT "Clobbering ${name} build and stamp directories" 551 USES_TERMINAL 552 ) 553 set_target_properties(${name}-clear PROPERTIES FOLDER "Compiler-RT Misc") 554 555 add_custom_command( 556 OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp 557 DEPENDS ${LIBCXX_DEPS} ${toolchain_deps} 558 COMMAND ${CMAKE_COMMAND} -E touch ${BINARY_DIR}/CMakeCache.txt 559 COMMAND ${CMAKE_COMMAND} -E touch ${STAMP_DIR}/${name}-mkdir 560 COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp 561 COMMENT "Clobbering bootstrap build and stamp directories" 562 ) 563 564 add_custom_target(${name}-clobber 565 DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp) 566 set_target_properties(${name}-clobber PROPERTIES FOLDER "Compiler-RT Misc") 567 568 set(PASSTHROUGH_VARIABLES 569 CMAKE_C_COMPILER_TARGET 570 CMAKE_CXX_COMPILER_TARGET 571 CMAKE_SHARED_LINKER_FLAGS 572 CMAKE_MODULE_LINKER_FLAGS 573 CMAKE_EXE_LINKER_FLAGS 574 CMAKE_INSTALL_PREFIX 575 CMAKE_MAKE_PROGRAM 576 CMAKE_LINKER 577 CMAKE_AR 578 CMAKE_RANLIB 579 CMAKE_NM 580 CMAKE_OBJCOPY 581 CMAKE_OBJDUMP 582 CMAKE_STRIP 583 CMAKE_SYSROOT 584 CMAKE_SYSTEM_NAME) 585 foreach(variable ${PASSTHROUGH_VARIABLES}) 586 get_property(is_value_set CACHE ${variable} PROPERTY VALUE SET) 587 if(${is_value_set}) 588 get_property(value CACHE ${variable} PROPERTY VALUE) 589 list(APPEND CMAKE_PASSTHROUGH_VARIABLES -D${variable}=${value}) 590 endif() 591 endforeach() 592 593 string(REPLACE ";" " " LIBCXX_C_FLAGS "${LIBCXX_CFLAGS}") 594 get_property(C_FLAGS CACHE CMAKE_C_FLAGS PROPERTY VALUE) 595 set(LIBCXX_C_FLAGS "${LIBCXX_C_FLAGS} ${C_FLAGS}") 596 597 string(REPLACE ";" " " LIBCXX_CXX_FLAGS "${LIBCXX_CFLAGS}") 598 get_property(CXX_FLAGS CACHE CMAKE_CXX_FLAGS PROPERTY VALUE) 599 set(LIBCXX_CXX_FLAGS "${LIBCXX_CXX_FLAGS} ${CXX_FLAGS}") 600 601 ExternalProject_Add(${name} 602 DEPENDS ${name}-clobber ${LIBCXX_DEPS} 603 PREFIX ${prefix} 604 SOURCE_DIR ${COMPILER_RT_SOURCE_DIR}/cmake/Modules/CustomLibcxx 605 STAMP_DIR ${STAMP_DIR} 606 BINARY_DIR ${BINARY_DIR} 607 CMAKE_ARGS ${CMAKE_PASSTHROUGH_VARIABLES} 608 ${compiler_args} 609 -DCMAKE_C_FLAGS=${LIBCXX_C_FLAGS} 610 -DCMAKE_CXX_FLAGS=${LIBCXX_CXX_FLAGS} 611 -DCMAKE_BUILD_TYPE=Release 612 -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY 613 -DLLVM_PATH=${LLVM_MAIN_SRC_DIR} 614 -DLLVM_BINARY_DIR=${prefix} 615 -DLLVM_LIBRARY_OUTPUT_INTDIR=${prefix}/lib 616 -DCOMPILER_RT_LIBCXX_PATH=${COMPILER_RT_LIBCXX_PATH} 617 -DCOMPILER_RT_LIBCXXABI_PATH=${COMPILER_RT_LIBCXXABI_PATH} 618 ${LIBCXX_CMAKE_ARGS} 619 INSTALL_COMMAND "" 620 STEP_TARGETS configure build 621 BUILD_ALWAYS 1 622 USES_TERMINAL_CONFIGURE 1 623 USES_TERMINAL_BUILD 1 624 USES_TERMINAL_INSTALL 1 625 EXCLUDE_FROM_ALL TRUE 626 BUILD_BYPRODUCTS "${prefix}/lib/libc++.a" "${prefix}/lib/libc++abi.a" 627 ) 628 629 if (CMAKE_GENERATOR MATCHES "Make") 630 set(run_clean "$(MAKE)" "-C" "${BINARY_DIR}" "clean") 631 else() 632 set(run_clean ${CMAKE_COMMAND} --build ${BINARY_DIR} --target clean 633 --config "$<CONFIG>") 634 endif() 635 636 ExternalProject_Add_Step(${name} clean 637 COMMAND ${run_clean} 638 COMMENT "Cleaning ${name}..." 639 DEPENDEES configure 640 ${force_deps} 641 WORKING_DIRECTORY ${BINARY_DIR} 642 EXCLUDE_FROM_MAIN 1 643 USES_TERMINAL 1 644 ) 645 ExternalProject_Add_StepTargets(${name} clean) 646 647 if(LIBCXX_USE_TOOLCHAIN) 648 add_dependencies(${name}-clean ${name}-clobber) 649 set_target_properties(${name}-clean PROPERTIES 650 SOURCES ${CMAKE_CURRENT_BINARY_DIR}/${name}-clobber-stamp) 651 endif() 652endmacro() 653 654function(rt_externalize_debuginfo name) 655 if(NOT COMPILER_RT_EXTERNALIZE_DEBUGINFO) 656 return() 657 endif() 658 659 if(NOT COMPILER_RT_EXTERNALIZE_DEBUGINFO_SKIP_STRIP) 660 set(strip_command COMMAND xcrun strip -Sl $<TARGET_FILE:${name}>) 661 endif() 662 663 if(APPLE) 664 if(CMAKE_CXX_FLAGS MATCHES "-flto" 665 OR CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE} MATCHES "-flto") 666 667 set(lto_object ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${name}-lto.o) 668 set_property(TARGET ${name} APPEND_STRING PROPERTY 669 LINK_FLAGS " -Wl,-object_path_lto -Wl,${lto_object}") 670 endif() 671 add_custom_command(TARGET ${name} POST_BUILD 672 COMMAND xcrun dsymutil $<TARGET_FILE:${name}> 673 ${strip_command}) 674 else() 675 message(FATAL_ERROR "COMPILER_RT_EXTERNALIZE_DEBUGINFO isn't implemented for non-darwin platforms!") 676 endif() 677endfunction() 678 679 680# Configure lit configuration files, including compiler-rt specific variables. 681function(configure_compiler_rt_lit_site_cfg input output) 682 set_llvm_build_mode() 683 684 get_compiler_rt_output_dir(${COMPILER_RT_DEFAULT_TARGET_ARCH} output_dir) 685 686 string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} COMPILER_RT_RESOLVED_TEST_COMPILER ${COMPILER_RT_TEST_COMPILER}) 687 string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} COMPILER_RT_RESOLVED_LIBRARY_OUTPUT_DIR ${output_dir}) 688 689 configure_lit_site_cfg(${input} ${output}) 690endfunction() 691