1# TODO: This file assumes the Clang toolchain so it'd be better if it lived in 2# Clang, except there already is clang/runtime directory which contains 3# similar although simpler functionality. We should figure out how to merge 4# the two files. 5 6# TODO: Selecting runtimes should be always performed inside the runtimes 7# build, see runtimes/CMakeLists.txt, except that we currently check whether 8# compiler-rt is being built to determine whether to first build builtins 9# or not so we need that information in this file as well. 10set(LLVM_ALL_RUNTIMES "compiler-rt;libc;libcxx;libcxxabi;libunwind;openmp") 11set(LLVM_ENABLE_RUNTIMES "" CACHE STRING 12 "Semicolon-separated list of runtimes to build (${LLVM_ALL_RUNTIMES}), or \"all\".") 13if(LLVM_ENABLE_RUNTIMES STREQUAL "all" ) 14 set(LLVM_ENABLE_RUNTIMES ${LLVM_ALL_RUNTIMES}) 15endif() 16foreach(proj ${LLVM_ENABLE_RUNTIMES}) 17 set(proj_dir "${CMAKE_CURRENT_SOURCE_DIR}/../../${proj}") 18 if(IS_DIRECTORY ${proj_dir} AND EXISTS ${proj_dir}/CMakeLists.txt) 19 list(APPEND runtimes ${proj_dir}) 20 else() 21 message(FATAL_ERROR "LLVM_ENABLE_RUNTIMES requests ${proj} but directory not found: ${proj_dir}") 22 endif() 23 string(TOUPPER "${proj}" canon_name) 24 STRING(REGEX REPLACE "-" "_" canon_name ${canon_name}) 25 set(LLVM_EXTERNAL_${canon_name}_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../${proj}") 26endforeach() 27 28function(get_compiler_rt_path path) 29 foreach(entry ${runtimes}) 30 get_filename_component(projName ${entry} NAME) 31 if("${projName}" MATCHES "compiler-rt") 32 set(${path} ${entry} PARENT_SCOPE) 33 return() 34 endif() 35 endforeach() 36endfunction() 37 38include(LLVMExternalProjectUtils) 39 40if(NOT LLVM_BUILD_RUNTIMES) 41 set(EXTRA_ARGS EXCLUDE_FROM_ALL) 42endif() 43 44function(check_apple_target triple builtin_or_runtime) 45 set(error "\ 46compiler-rt for Darwin builds for all platforms and architectures using a \ 47single configuration. Specify only a single darwin triple (e.g. x86_64-apple-darwin) \ 48in your targets list (and not a triple for a specific platform such as macos). \ 49You can use variables such as COMPILER_RT_ENABLE_IOS and DARWIN_ios_ARCHS to \ 50control the specific platforms and architectures to build.") 51 52 set(seen_property ${builtin_or_runtime}_darwin_triple_seen) 53 string(REPLACE "-" ";" triple_components ${triple}) 54 foreach(component ${triple_components}) 55 string(TOLOWER "${component}" component_lower) 56 if(component_lower MATCHES "^darwin") 57 get_property(darwin_triple_seen GLOBAL PROPERTY ${seen_property}) 58 if(darwin_triple_seen) 59 message(FATAL_ERROR "${error}") 60 endif() 61 set_property(GLOBAL PROPERTY ${seen_property} YES) 62 if(NOT RUNTIMES_BUILD_ALLOW_DARWIN) 63 message(FATAL_ERROR "\ 64${error} Set RUNTIMES_BUILD_ALLOW_DARWIN to allow a single darwin triple.") 65 endif() 66 elseif(component_lower MATCHES "^ios|^macos|^tvos|^watchos") 67 message(FATAL_ERROR "${error}") 68 endif() 69 endforeach() 70endfunction() 71 72function(builtin_default_target compiler_rt_path) 73 cmake_parse_arguments(ARG "" "" "DEPENDS" ${ARGN}) 74 75 set(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR_default ON) 76 # AIX should fold 32-bit & 64-bit arch libraries into a single archive. 77 if (TARGET_TRIPLE MATCHES "aix") 78 set(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR_default OFF) 79 endif() 80 81 llvm_ExternalProject_Add(builtins 82 ${compiler_rt_path}/lib/builtins 83 DEPENDS ${ARG_DEPENDS} 84 CMAKE_ARGS -DLLVM_LIBRARY_OUTPUT_INTDIR=${LLVM_LIBRARY_DIR} 85 -DLLVM_RUNTIME_OUTPUT_INTDIR=${LLVM_TOOLS_BINARY_DIR} 86 -DLLVM_DEFAULT_TARGET_TRIPLE=${TARGET_TRIPLE} 87 -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=${LLVM_ENABLE_PER_TARGET_RUNTIME_DIR_default} 88 -DCMAKE_C_COMPILER_WORKS=ON 89 -DCMAKE_ASM_COMPILER_WORKS=ON 90 ${BUILTINS_CMAKE_ARGS} 91 PASSTHROUGH_PREFIXES COMPILER_RT 92 USE_TOOLCHAIN 93 TARGET_TRIPLE ${TARGET_TRIPLE} 94 ${EXTRA_ARGS}) 95endfunction() 96 97function(builtin_register_target compiler_rt_path target) 98 cmake_parse_arguments(ARG "" "" "DEPENDS" ${ARGN}) 99 100 check_apple_target(${target} builtin) 101 102 get_cmake_property(variableNames VARIABLES) 103 foreach(variableName ${variableNames}) 104 string(FIND "${variableName}" "BUILTINS_${target}" out) 105 if("${out}" EQUAL 0) 106 string(REPLACE "BUILTINS_${target}_" "" new_name ${variableName}) 107 string(REPLACE ";" "|" new_value "${${variableName}}") 108 list(APPEND ${target}_extra_args "-D${new_name}=${new_value}") 109 endif() 110 endforeach() 111 112 llvm_ExternalProject_Add(builtins-${target} 113 ${compiler_rt_path}/lib/builtins 114 DEPENDS ${ARG_DEPENDS} 115 CMAKE_ARGS -DLLVM_LIBRARY_OUTPUT_INTDIR=${LLVM_LIBRARY_DIR} 116 -DLLVM_RUNTIME_OUTPUT_INTDIR=${LLVM_TOOLS_BINARY_DIR} 117 -DLLVM_DEFAULT_TARGET_TRIPLE=${target} 118 -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON 119 -DCMAKE_C_COMPILER_WORKS=ON 120 -DCMAKE_ASM_COMPILER_WORKS=ON 121 -DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON 122 ${${target}_extra_args} 123 USE_TOOLCHAIN 124 TARGET_TRIPLE ${target} 125 ${EXTRA_ARGS}) 126endfunction() 127 128# If compiler-rt is present we need to build the builtin libraries first. This 129# is required because the other runtimes need the builtin libraries present 130# before the just-built compiler can pass the configuration tests. 131get_compiler_rt_path(compiler_rt_path) 132if(compiler_rt_path) 133 if(NOT LLVM_BUILTIN_TARGETS) 134 builtin_default_target(${compiler_rt_path} 135 DEPENDS clang-resource-headers) 136 else() 137 if("default" IN_LIST LLVM_BUILTIN_TARGETS) 138 builtin_default_target(${compiler_rt_path} 139 DEPENDS clang-resource-headers) 140 list(REMOVE_ITEM LLVM_BUILTIN_TARGETS "default") 141 else() 142 add_custom_target(builtins) 143 add_custom_target(install-builtins) 144 add_custom_target(install-builtins-stripped) 145 endif() 146 147 foreach(target ${LLVM_BUILTIN_TARGETS}) 148 builtin_register_target(${compiler_rt_path} ${target} 149 DEPENDS clang-resource-headers) 150 151 add_dependencies(builtins builtins-${target}) 152 add_dependencies(install-builtins install-builtins-${target}) 153 add_dependencies(install-builtins-stripped install-builtins-${target}-stripped) 154 endforeach() 155 endif() 156 set(deps builtins) 157 # We don't need to depend on the builtins if we're building instrumented 158 # because the next stage will use the same compiler used to build this stage. 159 if(NOT LLVM_BUILD_INSTRUMENTED AND CLANG_ENABLE_BOOTSTRAP) 160 add_dependencies(clang-bootstrap-deps builtins) 161 endif() 162endif() 163 164# We create a list the names of all the runtime projects in all uppercase and 165# with dashes turned to underscores. This gives us the CMake variable prefixes 166# for all variables that will apply to runtimes. 167foreach(entry ${runtimes}) 168 get_filename_component(projName ${entry} NAME) 169 if(projName STREQUAL "libc") 170 # For now, we will use the name "llvmlibc" for the libc project as it is 171 # not a full libc yet. Also, if we leave it as is, the "lib" prefix gets 172 # stripped below and the targets endup having the name "c", "check-c" etc. 173 set(projName "llvmlibc") 174 endif() 175 string(REPLACE "-" "_" canon_name ${projName}) 176 string(TOUPPER ${canon_name} canon_name) 177 list(APPEND prefixes ${canon_name}) 178 if (${canon_name} STREQUAL "OPENMP") 179 list(APPEND prefixes "LIBOMP" "LIBOMPTARGET") 180 endif() 181 # Many compiler-rt options start with SANITIZER_ rather than COMPILER_RT_, 182 # so when compiler-rt is enabled, consider both. 183 if(canon_name STREQUAL "COMPILER_RT") 184 list(APPEND prefixes SANITIZER) 185 endif() 186 187 string(FIND ${projName} "lib" LIB_IDX) 188 if(LIB_IDX EQUAL 0) 189 string(SUBSTRING ${projName} 3 -1 projName) 190 endif() 191 list(APPEND runtime_names ${projName}) 192endforeach() 193 194function(runtime_default_target) 195 cmake_parse_arguments(ARG "" "" "DEPENDS;PREFIXES" ${ARGN}) 196 197 include(${LLVM_BINARY_DIR}/runtimes/Components.cmake OPTIONAL) 198 set(SUB_CHECK_TARGETS ${SUB_CHECK_TARGETS} PARENT_SCOPE) 199 set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${LLVM_BINARY_DIR}/runtimes/Components.cmake) 200 201 foreach(runtime_name ${runtime_names}) 202 list(APPEND extra_targets 203 ${runtime_name} 204 install-${runtime_name} 205 install-${runtime_name}-stripped) 206 if(LLVM_INCLUDE_TESTS) 207 list(APPEND test_targets check-${runtime_name}) 208 endif() 209 endforeach() 210 foreach(component ${LLVM_RUNTIME_DISTRIBUTION_COMPONENTS}) 211 if(NOT ${component} IN_LIST SUB_COMPONENTS) 212 list(APPEND extra_targets ${component} install-${component} install-${component}-stripped) 213 endif() 214 endforeach() 215 216 if(LLVM_INCLUDE_TESTS) 217 list(APPEND test_targets runtimes-test-depends check-runtimes) 218 endif() 219 220 set(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR_default ON) 221 # AIX should fold 32-bit & 64-bit arch libraries into a single archive. 222 if (TARGET_TRIPLE MATCHES "aix") 223 set(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR_default OFF) 224 endif() 225 226 llvm_ExternalProject_Add(runtimes 227 ${CMAKE_CURRENT_SOURCE_DIR}/../../runtimes 228 DEPENDS ${ARG_DEPENDS} 229 # Builtins were built separately above 230 CMAKE_ARGS -DCOMPILER_RT_BUILD_BUILTINS=Off 231 -DLLVM_INCLUDE_TESTS=${LLVM_INCLUDE_TESTS} 232 -DLLVM_DEFAULT_TARGET_TRIPLE=${TARGET_TRIPLE} 233 -DLLVM_ENABLE_PROJECTS_USED=${LLVM_ENABLE_PROJECTS_USED} 234 -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=${LLVM_ENABLE_PER_TARGET_RUNTIME_DIR_default} 235 -DCMAKE_C_COMPILER_WORKS=ON 236 -DCMAKE_CXX_COMPILER_WORKS=ON 237 -DCMAKE_ASM_COMPILER_WORKS=ON 238 ${RUNTIMES_CMAKE_ARGS} 239 PASSTHROUGH_PREFIXES LLVM_ENABLE_RUNTIMES 240 ${ARG_PREFIXES} 241 EXTRA_TARGETS ${extra_targets} 242 ${test_targets} 243 ${SUB_COMPONENTS} 244 ${SUB_CHECK_TARGETS} 245 ${SUB_INSTALL_TARGETS} 246 USE_TOOLCHAIN 247 TARGET_TRIPLE ${TARGET_TRIPLE} 248 ${EXTRA_ARGS}) 249endfunction() 250 251# runtime_register_target(target) 252# Utility function to register external runtime target. 253function(runtime_register_target name target) 254 cmake_parse_arguments(ARG "" "" "DEPENDS;CMAKE_ARGS" ${ARGN}) 255 include(${LLVM_BINARY_DIR}/runtimes/${name}/Components.cmake OPTIONAL) 256 set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${LLVM_BINARY_DIR}/runtimes/${name}/Components.cmake) 257 258 check_apple_target(${target} runtime) 259 260 set(${name}_deps ${ARG_DEPENDS}) 261 if(NOT name STREQUAL target) 262 list(APPEND ${name}_deps runtimes-${target}) 263 endif() 264 265 foreach(runtime_name ${runtime_names}) 266 set(${runtime_name}-${name} ${runtime_name}) 267 set(install-${runtime_name}-${name} install-${runtime_name}) 268 set(install-${runtime_name}-${name}-stripped install-${runtime_name}-stripped) 269 list(APPEND ${name}_extra_targets ${runtime_name}-${name} install-${runtime_name}-${name} install-${runtime_name}-${name}-stripped) 270 if(LLVM_INCLUDE_TESTS) 271 set(check-${runtime_name}-${name} check-${runtime_name} ) 272 list(APPEND ${name}_test_targets check-${runtime_name}-${name}) 273 endif() 274 endforeach() 275 276 foreach(target_name IN LISTS SUB_COMPONENTS SUB_INSTALL_TARGETS) 277 set(${target_name}-${name} ${target_name}) 278 list(APPEND ${name}_extra_targets ${target_name}-${name}) 279 endforeach() 280 281 foreach(component ${LLVM_RUNTIME_DISTRIBUTION_COMPONENTS}) 282 set(${component}-${name} ${component}) 283 set(install-${component}-${name} install-${component}) 284 set(install-${component}-${name}-stripped install-${component}-stripped) 285 list(APPEND ${name}_extra_targets ${component}-${name} install-${component}-${name} install-${component}-${name}-stripped) 286 endforeach() 287 288 if(LLVM_INCLUDE_TESTS) 289 set(runtimes-test-depends-${name} runtimes-test-depends) 290 set(check-runtimes-${name} check-runtimes) 291 list(APPEND ${name}_test_targets runtimes-test-depends-${name} check-runtimes-${name}) 292 foreach(target_name IN LISTS SUB_CHECK_TARGETS) 293 set(${target_name}-${name} ${target_name}) 294 list(APPEND ${name}_test_targets ${target_name}-${name}) 295 list(APPEND test_targets ${target_name}-${name}) 296 endforeach() 297 set(test_targets "${test_targets}" PARENT_SCOPE) 298 endif() 299 300 set(${name}_extra_args ${ARG_CMAKE_ARGS}) 301 get_cmake_property(variableNames VARIABLES) 302 foreach(variableName ${variableNames}) 303 string(FIND "${variableName}" "RUNTIMES_${target}_" out) 304 if("${out}" EQUAL 0) 305 string(REPLACE "RUNTIMES_${target}_" "" new_name ${variableName}) 306 string(REPLACE ";" "|" new_value "${${variableName}}") 307 list(APPEND ${name}_extra_args "-D${new_name}=${new_value}") 308 endif() 309 endforeach() 310 if(NOT "${name}" STREQUAL "${target}") 311 foreach(variableName ${variableNames}) 312 string(FIND "${variableName}" "RUNTIMES_${name}_" out) 313 if("${out}" EQUAL 0) 314 string(REPLACE "RUNTIMES_${name}_" "" new_name ${variableName}) 315 string(REPLACE ";" "|" new_value "${${variableName}}") 316 list(APPEND ${name}_extra_args "-D${new_name}=${new_value}") 317 endif() 318 endforeach() 319 endif() 320 321 if(NOT RUNTIMES_${name}_LLVM_ENABLE_RUNTIMES AND NOT RUNTIMES_${target}_LLVM_ENABLE_RUNTIMES) 322 string(REPLACE ";" "|" LLVM_ENABLE_RUNTIMES_PASSTHROUGH "${LLVM_ENABLE_RUNTIMES}") 323 list(APPEND ${name}_extra_args -DLLVM_ENABLE_RUNTIMES=${LLVM_ENABLE_RUNTIMES_PASSTHROUGH}) 324 endif() 325 326 llvm_ExternalProject_Add(runtimes-${name} 327 ${CMAKE_CURRENT_SOURCE_DIR}/../../runtimes 328 DEPENDS ${${name}_deps} 329 # Builtins were built separately above 330 CMAKE_ARGS -DCOMPILER_RT_BUILD_BUILTINS=Off 331 -DLLVM_INCLUDE_TESTS=${LLVM_INCLUDE_TESTS} 332 -DLLVM_DEFAULT_TARGET_TRIPLE=${target} 333 -DLLVM_ENABLE_PROJECTS_USED=${LLVM_ENABLE_PROJECTS_USED} 334 -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON 335 -DCMAKE_C_COMPILER_WORKS=ON 336 -DCMAKE_CXX_COMPILER_WORKS=ON 337 -DCMAKE_ASM_COMPILER_WORKS=ON 338 -DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON 339 -DLLVM_RUNTIMES_TARGET=${name} 340 ${${name}_extra_args} 341 EXTRA_TARGETS ${${name}_extra_targets} 342 ${${name}_test_targets} 343 USE_TOOLCHAIN 344 TARGET_TRIPLE ${target} 345 ${EXTRA_ARGS}) 346endfunction() 347 348if(runtimes) 349 # Create a runtimes target that uses this file as its top-level CMake file. 350 # The runtimes target is a configuration of all the runtime libraries 351 # together in a single CMake invocaiton. 352 if(NOT LLVM_RUNTIME_TARGETS) 353 runtime_default_target( 354 DEPENDS ${deps} 355 PREFIXES ${prefixes}) 356 set(test_targets check-runtimes) 357 else() 358 if("default" IN_LIST LLVM_RUNTIME_TARGETS) 359 runtime_default_target( 360 DEPENDS ${deps} 361 PREFIXES ${prefixes}) 362 list(REMOVE_ITEM LLVM_RUNTIME_TARGETS "default") 363 else() 364 add_custom_target(runtimes) 365 add_custom_target(runtimes-configure) 366 add_custom_target(install-runtimes) 367 add_custom_target(install-runtimes-stripped) 368 if(LLVM_INCLUDE_TESTS) 369 add_custom_target(check-runtimes) 370 add_custom_target(runtimes-test-depends) 371 set(test_targets "") 372 endif() 373 foreach(runtime_name ${runtime_names}) 374 add_custom_target(${runtime_name}) 375 add_custom_target(install-${runtime_name}) 376 add_custom_target(install-${runtime_name}-stripped) 377 endforeach() 378 if(LLVM_RUNTIME_DISTRIBUTION_COMPONENTS) 379 foreach(component ${LLVM_RUNTIME_DISTRIBUTION_COMPONENTS}) 380 add_custom_target(${component}) 381 add_custom_target(install-${component}) 382 add_custom_target(install-${component}-stripped) 383 endforeach() 384 endif() 385 endif() 386 387 foreach(name ${LLVM_RUNTIME_TARGETS}) 388 runtime_register_target(${name} ${name} 389 DEPENDS ${deps}) 390 391 add_dependencies(runtimes runtimes-${name}) 392 add_dependencies(runtimes-configure runtimes-${name}-configure) 393 add_dependencies(install-runtimes install-runtimes-${name}) 394 add_dependencies(install-runtimes-stripped install-runtimes-${name}-stripped) 395 if(LLVM_INCLUDE_TESTS) 396 add_dependencies(check-runtimes check-runtimes-${name}) 397 add_dependencies(runtimes-test-depends runtimes-test-depends-${name}) 398 endif() 399 foreach(runtime_name ${runtime_names}) 400 add_dependencies(${runtime_name} ${runtime_name}-${name}) 401 add_dependencies(install-${runtime_name} install-${runtime_name}-${name}) 402 add_dependencies(install-${runtime_name}-stripped install-${runtime_name}-${name}-stripped) 403 endforeach() 404 endforeach() 405 406 foreach(multilib ${LLVM_RUNTIME_MULTILIBS}) 407 foreach(name ${LLVM_RUNTIME_MULTILIB_${multilib}_TARGETS}) 408 runtime_register_target(${name}+${multilib} ${name} 409 DEPENDS runtimes-${name} 410 CMAKE_ARGS -DLLVM_RUNTIMES_PREFIX=${name}/ 411 -DLLVM_RUNTIMES_LIBDIR_SUBDIR=${multilib}) 412 add_dependencies(runtimes runtimes-${name}+${multilib}) 413 add_dependencies(runtimes-configure runtimes-${name}+${multilib}-configure) 414 add_dependencies(install-runtimes install-runtimes-${name}+${multilib}) 415 add_dependencies(install-runtimes-stripped install-runtimes-${name}+${multilib}-stripped) 416 foreach(runtime_name ${runtime_names}) 417 add_dependencies(${runtime_name} ${runtime_name}-${name}+${multilib}) 418 add_dependencies(install-${runtime_name} install-${runtime_name}-${name}+${multilib}) 419 add_dependencies(install-${runtime_name}-stripped install-${runtime_name}-${name}+${multilib}-stripped) 420 endforeach() 421 endforeach() 422 endforeach() 423 endif() 424 425 if(NOT LLVM_BUILD_INSTRUMENTED AND CLANG_ENABLE_BOOTSTRAP) 426 # TODO: This is a hack needed because the libcxx headers are copied into the 427 # build directory during configuration. Without that step the clang in the 428 # build directory cannot find the C++ headers in certain configurations. 429 # I need to build a mechanism for runtime projects to provide CMake code 430 # that executes at LLVM configuration time to handle this case. 431 add_dependencies(clang-bootstrap-deps runtimes-configure) 432 # We need to add the runtimes as a dependency because compiler-rt can be 433 # built as part of runtimes and we need the profile runtime for PGO 434 add_dependencies(clang-bootstrap-deps runtimes) 435 endif() 436 437 if(LLVM_INCLUDE_TESTS) 438 set_property(GLOBAL APPEND PROPERTY LLVM_ADDITIONAL_TEST_DEPENDS runtimes-test-depends) 439 set_property(GLOBAL APPEND PROPERTY LLVM_ADDITIONAL_TEST_TARGETS check-runtimes) 440 441 set(RUNTIMES_TEST_DEPENDS 442 FileCheck 443 count 444 llvm-nm 445 llvm-objdump 446 llvm-xray 447 not 448 obj2yaml 449 sancov 450 sanstats 451 gtest_main 452 gtest 453 ) 454 foreach(target ${test_targets} ${SUB_CHECK_TARGETS}) 455 add_dependencies(${target} ${RUNTIMES_TEST_DEPENDS}) 456 endforeach() 457 endif() 458endif() 459