xref: /llvm-project/llvm/runtimes/CMakeLists.txt (revision 5e0844a969a10c1d99ce809c69f17383389c48d1)
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
6set(COMMON_CMAKE_ARGS "-DHAVE_LLVM_LIT=ON;-DCLANG_RESOURCE_DIR=${CLANG_RESOURCE_DIR}")
7foreach(proj ${LLVM_ENABLE_RUNTIMES})
8  set(proj_dir "${CMAKE_CURRENT_SOURCE_DIR}/../../${proj}")
9  if(IS_DIRECTORY ${proj_dir} AND EXISTS ${proj_dir}/CMakeLists.txt)
10    list(APPEND runtimes ${proj_dir})
11  else()
12    message(FATAL_ERROR "LLVM_ENABLE_RUNTIMES requests ${proj} but directory not found: ${proj_dir}")
13  endif()
14  string(TOUPPER "${proj}" canon_name)
15  STRING(REGEX REPLACE "-" "_" canon_name ${canon_name})
16  set(LLVM_EXTERNAL_${canon_name}_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../${proj}")
17endforeach()
18
19function(get_compiler_rt_path path)
20  set(all_runtimes ${runtimes})
21  foreach(name ${LLVM_RUNTIME_TARGETS})
22    foreach(proj ${RUNTIMES_${name}_LLVM_ENABLE_RUNTIMES})
23      set(proj_dir "${CMAKE_CURRENT_SOURCE_DIR}/../../${proj}")
24      if(IS_DIRECTORY ${proj_dir} AND EXISTS ${proj_dir}/CMakeLists.txt)
25        list(APPEND all_runtimes ${proj_dir})
26      endif()
27    endforeach()
28  endforeach()
29  list(REMOVE_DUPLICATES all_runtimes)
30  foreach(entry ${all_runtimes})
31    get_filename_component(projName ${entry} NAME)
32    if("${projName}" MATCHES "compiler-rt")
33      set(${path} ${entry} PARENT_SCOPE)
34      return()
35    endif()
36  endforeach()
37endfunction()
38
39include(LLVMExternalProjectUtils)
40
41if(NOT LLVM_BUILD_RUNTIMES)
42  set(EXTRA_ARGS EXCLUDE_FROM_ALL)
43endif()
44
45function(check_apple_target triple builtin_or_runtime)
46  set(error "\
47compiler-rt for Darwin builds for all platforms and architectures using a \
48single configuration. Specify only a single darwin triple (e.g. x86_64-apple-darwin) \
49in your targets list (and not a triple for a specific platform such as macos). \
50You can use variables such as COMPILER_RT_ENABLE_IOS and DARWIN_ios_ARCHS to \
51control the specific platforms and architectures to build.")
52
53  set(seen_property ${builtin_or_runtime}_darwin_triple_seen)
54  string(REPLACE "-" ";" triple_components ${triple})
55  foreach(component ${triple_components})
56    string(TOLOWER "${component}" component_lower)
57    if(component_lower MATCHES "^darwin")
58      get_property(darwin_triple_seen GLOBAL PROPERTY ${seen_property})
59      if(darwin_triple_seen)
60        message(FATAL_ERROR "${error}")
61      endif()
62      set_property(GLOBAL PROPERTY ${seen_property} YES)
63      if(NOT RUNTIMES_BUILD_ALLOW_DARWIN)
64        message(FATAL_ERROR "\
65${error} Set RUNTIMES_BUILD_ALLOW_DARWIN to allow a single darwin triple.")
66      endif()
67    elseif(component_lower MATCHES "^ios|^macos|^tvos|^watchos")
68      message(FATAL_ERROR "${error}")
69    endif()
70  endforeach()
71endfunction()
72
73macro(set_enable_per_target_runtime_dir)
74  # May have been set by llvm/CMakeLists.txt.
75  if (NOT DEFINED LLVM_ENABLE_PER_TARGET_RUNTIME_DIR)
76    # AIX should fold 32-bit & 64-bit arch libraries into a single archive.
77    if (LLVM_TARGET_TRIPLE MATCHES "aix")
78      set(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR OFF)
79    else()
80      set(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR ON)
81    endif()
82  endif()
83endmacro()
84
85function(builtin_default_target compiler_rt_path)
86  cmake_parse_arguments(ARG "" "" "DEPENDS" ${ARGN})
87
88  set_enable_per_target_runtime_dir()
89
90  llvm_ExternalProject_Add(builtins
91                           ${compiler_rt_path}/lib/builtins
92                           DEPENDS ${ARG_DEPENDS}
93                           CMAKE_ARGS -DLLVM_LIBRARY_OUTPUT_INTDIR=${LLVM_LIBRARY_DIR}
94                                      -DLLVM_RUNTIME_OUTPUT_INTDIR=${LLVM_TOOLS_BINARY_DIR}
95                                      -DLLVM_DEFAULT_TARGET_TRIPLE=${LLVM_TARGET_TRIPLE}
96                                      -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=${LLVM_ENABLE_PER_TARGET_RUNTIME_DIR}
97                                      -DLLVM_CMAKE_DIR=${CMAKE_BINARY_DIR}
98                                      -DCMAKE_C_COMPILER_WORKS=ON
99                                      -DCMAKE_ASM_COMPILER_WORKS=ON
100                                      ${COMMON_CMAKE_ARGS}
101                                      ${BUILTINS_CMAKE_ARGS}
102                           PASSTHROUGH_PREFIXES COMPILER_RT
103                                                DARWIN
104                                                SANITIZER
105                           USE_TOOLCHAIN
106                           TARGET_TRIPLE ${LLVM_TARGET_TRIPLE}
107                           FOLDER "Compiler-RT"
108                           ${EXTRA_ARGS})
109endfunction()
110
111function(builtin_register_target compiler_rt_path name)
112  cmake_parse_arguments(ARG "" "" "DEPENDS;CMAKE_ARGS;EXTRA_ARGS" ${ARGN})
113
114  set(${name}_extra_args ${ARG_CMAKE_ARGS})
115  get_cmake_property(variable_names VARIABLES)
116  foreach(variable_name ${variable_names})
117    string(FIND "${variable_name}" "BUILTINS_${name}" out)
118    if("${out}" EQUAL 0)
119      string(REPLACE "BUILTINS_${name}_" "" new_name ${variable_name})
120      if(new_name STREQUAL CACHE_FILES)
121        foreach(cache IN LISTS ${variable_name})
122          list(APPEND ${name}_extra_args -C ${cache})
123        endforeach()
124      else()
125        string(REPLACE ";" "|" new_value "${${variable_name}}")
126        list(APPEND ${name}_extra_args "-D${new_name}=${new_value}")
127      endif()
128    endif()
129  endforeach()
130
131  llvm_ExternalProject_Add(builtins-${name}
132                           ${compiler_rt_path}/lib/builtins
133                           DEPENDS ${ARG_DEPENDS}
134                           CMAKE_ARGS -DLLVM_LIBRARY_OUTPUT_INTDIR=${LLVM_LIBRARY_DIR}
135                                      -DLLVM_RUNTIME_OUTPUT_INTDIR=${LLVM_TOOLS_BINARY_DIR}
136                                      -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON
137                                      -DLLVM_CMAKE_DIR=${CMAKE_BINARY_DIR}
138                                      -DCMAKE_C_COMPILER_WORKS=ON
139                                      -DCMAKE_ASM_COMPILER_WORKS=ON
140                                      -DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON
141                                      ${COMMON_CMAKE_ARGS}
142                                      ${${name}_extra_args}
143                           USE_TOOLCHAIN
144                           FOLDER "Compiler-RT"
145                           ${EXTRA_ARGS} ${ARG_EXTRA_ARGS})
146endfunction()
147
148# If compiler-rt is present we need to build the builtin libraries first. This
149# is required because the other runtimes need the builtin libraries present
150# before the just-built compiler can pass the configuration tests.
151get_compiler_rt_path(compiler_rt_path)
152if(compiler_rt_path)
153  # If the user did not specify the targets infer them from the runtimes.
154  set(builtin_targets ${LLVM_BUILTIN_TARGETS})
155  if(NOT builtin_targets)
156    if("compiler-rt" IN_LIST LLVM_ENABLE_RUNTIMES)
157      list(APPEND builtin_targets "default")
158    endif()
159    foreach(name ${LLVM_RUNTIME_TARGETS})
160      if("compiler-rt" IN_LIST RUNTIMES_${name}_LLVM_ENABLE_RUNTIMES)
161        list(APPEND builtin_targets ${name})
162      endif()
163    endforeach()
164  endif()
165  if("default" IN_LIST builtin_targets)
166    builtin_default_target(${compiler_rt_path}
167      DEPENDS clang-resource-headers)
168    list(REMOVE_ITEM builtin_targets "default")
169  else()
170    add_custom_target(builtins)
171    add_custom_target(install-builtins)
172    add_custom_target(install-builtins-stripped)
173    set_target_properties(
174      builtins install-builtins install-builtins-stripped
175      PROPERTIES FOLDER "Compiler-RT"
176    )
177  endif()
178
179  foreach(target ${builtin_targets})
180    check_apple_target(${target} builtin)
181
182    builtin_register_target(${compiler_rt_path} ${target}
183      DEPENDS clang-resource-headers
184      CMAKE_ARGS -DLLVM_DEFAULT_TARGET_TRIPLE=${target}
185      EXTRA_ARGS TARGET_TRIPLE ${target})
186
187    add_dependencies(builtins builtins-${target})
188    add_dependencies(install-builtins install-builtins-${target})
189    add_dependencies(install-builtins-stripped install-builtins-${target}-stripped)
190  endforeach()
191  set(builtins_dep builtins)
192  # We don't need to depend on the builtins if we're building instrumented
193  # because the next stage will use the same compiler used to build this stage.
194  if(NOT LLVM_BUILD_INSTRUMENTED AND CLANG_ENABLE_BOOTSTRAP)
195    add_dependencies(clang-bootstrap-deps builtins)
196  endif()
197endif()
198
199function(_get_runtime_name name out_var)
200  string(FIND ${name} "lib" idx)
201  if(idx EQUAL 0 AND NOT ${name} STREQUAL "libc")
202    string(SUBSTRING ${name} 3 -1 name)
203  endif()
204  set(${out_var} ${name} PARENT_SCOPE)
205endfunction()
206
207# Create a list with the names of all the runtime projects in all uppercase and
208# with dashes turned to underscores. This gives us the CMake variable `prefixes`
209# for all variables that will apply to runtimes.
210foreach(entry ${runtimes})
211  get_filename_component(name ${entry} NAME)
212  string(REPLACE "-" "_" canon_name ${name})
213  string(TOUPPER ${canon_name} canon_name)
214  list(APPEND prefixes ${canon_name})
215  if (${canon_name} STREQUAL "OPENMP")
216    list(APPEND prefixes "LIBOMP" "LIBOMPTARGET")
217  endif()
218  # Many compiler-rt options start with SANITIZER_ and DARWIN_ rather than
219  # COMPILER_RT_, so when compiler-rt is enabled, consider both.
220  if(canon_name STREQUAL "COMPILER_RT")
221    list(APPEND prefixes SANITIZER DARWIN)
222  endif()
223  if(canon_name STREQUAL "LIBC")
224    list(APPEND prefixes "LLVM_LIBC")
225    list(APPEND prefixes "LIBC_")
226  endif()
227
228  _get_runtime_name(${name} name)
229  list(APPEND RUNTIME_NAMES ${name})
230endforeach()
231
232function(runtime_default_target)
233  cmake_parse_arguments(ARG "" "" "DEPENDS;CMAKE_ARGS;PREFIXES" ${ARGN})
234
235  include(${LLVM_BINARY_DIR}/runtimes/Components.cmake OPTIONAL)
236  set(SUB_CHECK_TARGETS ${SUB_CHECK_TARGETS} PARENT_SCOPE)
237  set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${LLVM_BINARY_DIR}/runtimes/Components.cmake)
238
239  foreach(runtime_name ${RUNTIME_NAMES})
240    list(APPEND extra_targets
241      ${runtime_name}
242      install-${runtime_name}
243      install-${runtime_name}-stripped)
244    if(LLVM_INCLUDE_TESTS)
245      list(APPEND test_targets check-${runtime_name})
246    endif()
247  endforeach()
248  foreach(component ${LLVM_RUNTIME_DISTRIBUTION_COMPONENTS})
249    if(NOT ${component} IN_LIST SUB_COMPONENTS)
250      list(APPEND extra_targets install-${component} install-${component}-stripped)
251    endif()
252  endforeach()
253
254  if(LLVM_INCLUDE_TESTS)
255    set_property(GLOBAL APPEND PROPERTY LLVM_ALL_LIT_TESTSUITES "@${LLVM_BINARY_DIR}/runtimes/runtimes-bins/lit.tests")
256    list(APPEND test_targets runtimes-test-depends check-runtimes)
257  endif()
258
259  set_enable_per_target_runtime_dir()
260
261  llvm_ExternalProject_Add(runtimes
262                           ${CMAKE_CURRENT_SOURCE_DIR}/../../runtimes
263                           DEPENDS ${ARG_DEPENDS}
264                           # Builtins were built separately above
265                           CMAKE_ARGS -DCOMPILER_RT_BUILD_BUILTINS=Off
266                                      -DLLVM_INCLUDE_TESTS=${LLVM_INCLUDE_TESTS}
267                                      -DLLVM_DEFAULT_TARGET_TRIPLE=${LLVM_TARGET_TRIPLE}
268                                      -DLLVM_ENABLE_PROJECTS_USED=${LLVM_ENABLE_PROJECTS_USED}
269                                      -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=${LLVM_ENABLE_PER_TARGET_RUNTIME_DIR}
270                                      -DLLVM_BUILD_TOOLS=${LLVM_BUILD_TOOLS}
271                                      -DCMAKE_C_COMPILER_WORKS=ON
272                                      -DCMAKE_CXX_COMPILER_WORKS=ON
273                                      -DCMAKE_ASM_COMPILER_WORKS=ON
274                                      ${COMMON_CMAKE_ARGS}
275                                      ${RUNTIMES_CMAKE_ARGS}
276                                      ${ARG_CMAKE_ARGS}
277                           PASSTHROUGH_PREFIXES LLVM_ENABLE_RUNTIMES
278                                                LLVM_USE_LINKER
279                                                CUDA # For runtimes that may look for the CUDA SDK (libc, offload)
280                                                FFI # offload uses libffi
281                                                ${ARG_PREFIXES}
282                           EXTRA_TARGETS ${extra_targets}
283                                         ${test_targets}
284                                         ${SUB_COMPONENTS}
285                                         ${SUB_CHECK_TARGETS}
286                                         ${SUB_INSTALL_TARGETS}
287                           USE_TOOLCHAIN
288                           TARGET_TRIPLE ${LLVM_TARGET_TRIPLE}
289                           FOLDER "Runtimes"
290                           ${EXTRA_ARGS})
291endfunction()
292
293# runtime_register_target(name)
294#   Utility function to register external runtime target.
295function(runtime_register_target name)
296  cmake_parse_arguments(ARG "" "BASE_NAME" "DEPENDS;CMAKE_ARGS;EXTRA_ARGS" ${ARGN})
297  include(${LLVM_BINARY_DIR}/runtimes/${name}/Components.cmake OPTIONAL)
298  set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${LLVM_BINARY_DIR}/runtimes/${name}/Components.cmake)
299
300  set(runtime_names ${RUNTIME_NAMES})
301  foreach(_name IN ITEMS ${ARG_BASE_NAME} ${name})
302    if(RUNTIMES_${_name}_LLVM_ENABLE_RUNTIMES)
303      set(runtime_names)
304      foreach(entry ${RUNTIMES_${_name}_LLVM_ENABLE_RUNTIMES})
305        _get_runtime_name(${entry} runtime_name)
306        list(APPEND runtime_names ${runtime_name})
307      endforeach()
308    endif()
309  endforeach()
310
311  foreach(runtime_name ${runtime_names})
312    set(${runtime_name}-${name} ${runtime_name})
313    set(install-${runtime_name}-${name} install-${runtime_name})
314    set(install-${runtime_name}-${name}-stripped install-${runtime_name}-stripped)
315    list(APPEND ${name}_extra_targets ${runtime_name}-${name} install-${runtime_name}-${name} install-${runtime_name}-${name}-stripped)
316    if(LLVM_INCLUDE_TESTS)
317      set(check-${runtime_name}-${name} check-${runtime_name} )
318      list(APPEND ${name}_test_targets check-${runtime_name}-${name})
319    endif()
320  endforeach()
321
322  foreach(component IN LISTS SUB_COMPONENTS)
323    set(${component}-${name} ${component})
324    list(APPEND ${name}_extra_targets ${component}-${name})
325  endforeach()
326
327  foreach(target IN LISTS SUB_INSTALL_TARGETS)
328    set(${target}-${name} ${target})
329    set(${target}-${name}-stripped ${target}-stripped)
330    list(APPEND ${name}_extra_targets ${target}-${name} ${target}-${name}-stripped)
331  endforeach()
332
333  foreach(component ${LLVM_RUNTIME_DISTRIBUTION_COMPONENTS})
334    if(NOT component IN_LIST SUB_COMPONENTS)
335      set(${component}-${name} ${component})
336      set(install-${component}-${name} install-${component})
337      set(install-${component}-${name}-stripped install-${component}-stripped)
338      list(APPEND ${name}_extra_targets ${component}-${name} install-${component}-${name} install-${component}-${name}-stripped)
339    endif()
340  endforeach()
341
342  if(LLVM_INCLUDE_TESTS)
343    set_property(GLOBAL APPEND PROPERTY LLVM_ALL_LIT_TESTSUITES "@${LLVM_BINARY_DIR}/runtimes/runtimes-${name}-bins/lit.tests")
344    set(runtimes-test-depends-${name} runtimes-test-depends)
345    set(check-runtimes-${name} check-runtimes)
346    list(APPEND ${name}_test_targets runtimes-test-depends-${name} check-runtimes-${name})
347    list(APPEND test_targets ${${name}_test_targets})
348
349    set(component_check_targets)
350    foreach(component IN LISTS LLVM_RUNTIME_DISTRIBUTION_COMPONENTS)
351      if(NOT "check-${component}" IN_LIST SUB_CHECK_TARGETS)
352        list(APPEND component_check_targets "check-${component}")
353      endif()
354    endforeach()
355
356    foreach(target IN LISTS SUB_CHECK_TARGETS component_check_targets)
357      set(${target}-${name} ${target})
358      list(APPEND ${name}_test_targets ${target}-${name})
359      list(APPEND test_targets ${target}-${name})
360    endforeach()
361    set(test_targets "${test_targets}" PARENT_SCOPE)
362  endif()
363
364  set(${name}_extra_args ${ARG_CMAKE_ARGS})
365  string(REPLACE ";" "|" LLVM_ENABLE_RUNTIMES_PASSTHROUGH "${LLVM_ENABLE_RUNTIMES}")
366  list(APPEND ${name}_extra_args -DLLVM_ENABLE_RUNTIMES=${LLVM_ENABLE_RUNTIMES_PASSTHROUGH})
367  list(APPEND ${name}_extra_args -DLLVM_USE_LINKER=${LLVM_USE_LINKER})
368
369  get_cmake_property(variable_names VARIABLES)
370  foreach(extra_name IN ITEMS ${ARG_BASE_NAME} ${name})
371    foreach(variable_name ${variable_names})
372      string(FIND "${variable_name}" "RUNTIMES_${extra_name}_" out)
373      if("${out}" EQUAL 0)
374        string(REPLACE "RUNTIMES_${extra_name}_" "" new_name ${variable_name})
375        if(new_name STREQUAL CACHE_FILES)
376          foreach(cache IN LISTS ${variable_name})
377            list(APPEND ${name}_extra_args -C ${cache})
378          endforeach()
379        else()
380          string(REPLACE ";" "|" new_value "${${variable_name}}")
381          list(APPEND ${name}_extra_args "-D${new_name}=${new_value}")
382        endif()
383      endif()
384    endforeach()
385    foreach(variable_name ${${name}_extra_args})
386      string(FIND "${variable_name}" "-DRUNTIMES_${extra_name}_" out)
387      if("${out}" EQUAL 0)
388        string(REPLACE "-DRUNTIMES_${extra_name}_" "" new_name ${variable_name})
389        string(REPLACE ";" "|" new_value "${new_name}")
390        list(APPEND ${name}_extra_args "-D${new_value}")
391      endif()
392    endforeach()
393  endforeach()
394
395  set_enable_per_target_runtime_dir()
396
397  llvm_ExternalProject_Add(runtimes-${name}
398                           ${CMAKE_CURRENT_SOURCE_DIR}/../../runtimes
399                           DEPENDS ${ARG_DEPENDS}
400                           # Builtins were built separately above
401                           CMAKE_ARGS -DCOMPILER_RT_BUILD_BUILTINS=OFF
402                                      -DLLVM_INCLUDE_TESTS=${LLVM_INCLUDE_TESTS}
403                                      -DLLVM_ENABLE_PROJECTS_USED=${LLVM_ENABLE_PROJECTS_USED}
404                                      -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=${LLVM_ENABLE_PER_TARGET_RUNTIME_DIR}
405                                      -DCMAKE_C_COMPILER_WORKS=ON
406                                      -DCMAKE_CXX_COMPILER_WORKS=ON
407                                      -DCMAKE_ASM_COMPILER_WORKS=ON
408                                      -DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON
409                                      -DLLVM_RUNTIMES_TARGET=${name}
410                                      ${COMMON_CMAKE_ARGS}
411                                      ${${name}_extra_args}
412                           EXTRA_TARGETS ${${name}_extra_targets}
413                                         ${${name}_test_targets}
414                           USE_TOOLCHAIN
415                           FOLDER "Runtimes"
416                           ${EXTRA_ARGS} ${ARG_EXTRA_ARGS})
417
418  add_dependencies(runtimes runtimes-${name})
419  add_dependencies(runtimes-configure runtimes-${name}-configure)
420  add_dependencies(install-runtimes install-runtimes-${name})
421  add_dependencies(install-runtimes-stripped install-runtimes-${name}-stripped)
422  if(LLVM_INCLUDE_TESTS)
423    add_dependencies(check-runtimes check-runtimes-${name})
424    add_dependencies(runtimes-test-depends runtimes-test-depends-${name})
425  endif()
426  foreach(runtime_name ${runtime_names})
427    if(NOT TARGET ${runtime_name})
428      add_custom_target(${runtime_name})
429      set_target_properties(${runtime_name} PROPERTIES FOLDER "${runtime_name}")
430    endif()
431    add_dependencies(${runtime_name} ${runtime_name}-${name})
432    if(NOT TARGET install-${runtime_name})
433      add_custom_target(install-${runtime_name})
434      set_target_properties(install-${runtime_name} PROPERTIES FOLDER "${runtime_name}")
435    endif()
436    add_dependencies(install-${runtime_name} install-${runtime_name}-${name})
437    if(NOT TARGET install-${runtime_name}-stripped)
438      add_custom_target(install-${runtime_name}-stripped)
439      set_target_properties(install-${runtime_name} PROPERTIES FOLDER "${runtime_name}")
440    endif()
441    add_dependencies(install-${runtime_name}-stripped install-${runtime_name}-${name}-stripped)
442  endforeach()
443  foreach(component ${LLVM_RUNTIME_DISTRIBUTION_COMPONENTS})
444    add_dependencies(${component} ${component}-${name})
445    add_dependencies(install-${component} install-${component}-${name})
446    add_dependencies(install-${component}-stripped install-${component}-${name}-stripped)
447  endforeach()
448endfunction()
449
450# Check if we have any runtimes to build.
451if(runtimes)
452  set(build_runtimes TRUE)
453endif()
454foreach(name ${LLVM_RUNTIME_TARGETS})
455  if(RUNTIMES_${name}_LLVM_ENABLE_RUNTIMES)
456    set(build_runtimes TRUE)
457  endif()
458endforeach()
459
460if(build_runtimes)
461  # Create a runtimes target that uses this file as its top-level CMake file.
462  # The runtimes target is a configuration of all the runtime libraries
463  # together in a single CMake invocation.
464  set(extra_deps "")
465  set(extra_cmake_args "")
466
467  if(LLVM_INCLUDE_TESTS)
468    foreach(dep FileCheck
469                clang
470                count
471                lld
472                lli
473                llvm-cov
474                llvm-lto
475                llvm-jitlink
476                llvm-nm
477                llvm-objdump
478                llvm-profdata
479                llvm-size
480                llvm-symbolizer
481                llvm-xray
482                not
483                obj2yaml
484                opt
485                sancov
486                sanstats
487                llvm_gtest_main
488                llvm_gtest
489                split-file)
490      if(TARGET ${dep})
491        list(APPEND extra_deps ${dep})
492      endif()
493    endforeach()
494  endif()
495
496  # Forward user-provived system configuration to runtimes for requirement introspection.
497  # CMAKE_PREFIX_PATH is the search path for CMake packages.
498  if(CMAKE_PREFIX_PATH)
499    list(APPEND extra_cmake_args "-DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}")
500  endif()
501  # CMAKE_PROGRAM_PATH is the search path for executables such as python.
502  if(CMAKE_PROGRAM_PATH)
503    list(APPEND extra_cmake_args "-DCMAKE_PROGRAM_PATH=${CMAKE_PROGRAM_PATH}")
504  endif()
505
506  if("openmp" IN_LIST LLVM_ENABLE_RUNTIMES)
507    if (${LLVM_TOOL_FLANG_BUILD})
508      message(STATUS "Configuring build of omp_lib.mod and omp_lib_kinds.mod via flang")
509      set(LIBOMP_FORTRAN_MODULES_COMPILER "${CMAKE_BINARY_DIR}/bin/flang")
510      set(LIBOMP_MODULES_INSTALL_PATH "${CMAKE_INSTALL_INCLUDEDIR}/flang")
511      # TODO: This is a workaround until flang becomes a first-class project
512      # in llvm/CMakeList.txt.  Until then, this line ensures that flang is
513      # built before "openmp" is built as a runtime project.  Besides "flang"
514      # to build the compiler, we also need to add "module_files" to make sure
515      # that all .mod files are also properly build.
516      list(APPEND extra_deps "flang" "module_files")
517    endif()
518    foreach(dep opt llvm-link llvm-extract clang clang-offload-packager)
519      if(TARGET ${dep})
520        list(APPEND extra_deps ${dep})
521      endif()
522    endforeach()
523  endif()
524  if(LLVM_LIBC_GPU_BUILD)
525    list(APPEND extra_cmake_args "-DLLVM_LIBC_GPU_BUILD=ON")
526    if("libc" IN_LIST RUNTIMES_amdgcn-amd-amdhsa_LLVM_ENABLE_RUNTIMES)
527      if(TARGET amdhsa-loader)
528        list(APPEND extra_cmake_args
529             "-DRUNTIMES_amdgcn-amd-amdhsa_LIBC_GPU_LOADER_EXECUTABLE=$<TARGET_FILE:amdhsa-loader>")
530        list(APPEND extra_deps amdhsa-loader)
531      endif()
532      list(APPEND extra_cmake_args "-DRUNTIMES_amdgcn-amd-amdhsa_LLVM_LIBC_FULL_BUILD=ON")
533    endif()
534    if("libc" IN_LIST RUNTIMES_nvptx64-nvidia-cuda_LLVM_ENABLE_RUNTIMES)
535      if(TARGET nvptx-loader)
536        list(APPEND extra_cmake_args
537             "-DRUNTIMES_nvptx64-nvidia-cuda_LIBC_GPU_LOADER_EXECUTABLE=$<TARGET_FILE:nvptx-loader>")
538        list(APPEND extra_deps nvptx-loader)
539      endif()
540      list(APPEND extra_cmake_args "-DRUNTIMES_nvptx64-nvidia-cuda_LLVM_LIBC_FULL_BUILD=ON")
541    endif()
542    if(TARGET clang-offload-packager)
543      list(APPEND extra_deps clang-offload-packager)
544    endif()
545    if(TARGET clang-nvlink-wrapper)
546      list(APPEND extra_deps clang-nvlink-wrapper)
547    endif()
548  endif()
549  if(LLVM_LIBC_FULL_BUILD)
550    list(APPEND extra_cmake_args "-DLLVM_LIBC_FULL_BUILD=ON")
551  endif()
552
553  if(NOT LLVM_RUNTIME_TARGETS)
554    runtime_default_target(
555      DEPENDS ${builtins_dep} ${extra_deps}
556      CMAKE_ARGS ${extra_cmake_args}
557      PREFIXES ${prefixes})
558    set(test_targets check-runtimes)
559  else()
560    if("default" IN_LIST LLVM_RUNTIME_TARGETS)
561      runtime_default_target(
562        DEPENDS ${builtins_dep} ${extra_deps}
563        CMAKE_ARGS ${extra_cmake_args}
564        PREFIXES ${prefixes})
565      list(REMOVE_ITEM LLVM_RUNTIME_TARGETS "default")
566    else()
567      add_custom_target(runtimes)
568      add_custom_target(runtimes-configure)
569      add_custom_target(install-runtimes)
570      add_custom_target(install-runtimes-stripped)
571      set_target_properties(
572        runtimes runtimes-configure install-runtimes install-runtimes-stripped
573        PROPERTIES FOLDER "Runtimes"
574      )
575      if(LLVM_INCLUDE_TESTS)
576        add_custom_target(check-runtimes)
577        add_custom_target(runtimes-test-depends)
578        set_target_properties(
579          check-runtimes runtimes-test-depends
580          PROPERTIES FOLDER "Runtimes"
581        )
582        set(test_targets "")
583      endif()
584      if(LLVM_RUNTIME_DISTRIBUTION_COMPONENTS)
585        foreach(component ${LLVM_RUNTIME_DISTRIBUTION_COMPONENTS})
586          add_custom_target(${component})
587          add_custom_target(install-${component})
588          add_custom_target(install-${component}-stripped)
589          set_target_properties(
590            ${component} install-${component} install-${component}-stripped
591            PROPERTIES FOLDER "${component}"
592          )
593        endforeach()
594      endif()
595    endif()
596
597    foreach(name ${LLVM_RUNTIME_TARGETS})
598      if(builtins_dep)
599        if (LLVM_BUILTIN_TARGETS)
600          set(builtins_dep_name "${builtins_dep}-${name}")
601        else()
602          set(builtins_dep_name ${builtins_dep})
603        endif()
604      endif()
605
606      check_apple_target(${name} runtime)
607
608      runtime_register_target(${name}
609        DEPENDS ${builtins_dep_name} ${extra_deps}
610        CMAKE_ARGS -DLLVM_DEFAULT_TARGET_TRIPLE=${name} ${extra_cmake_args}
611        EXTRA_ARGS TARGET_TRIPLE ${name})
612    endforeach()
613
614    foreach(multilib ${LLVM_RUNTIME_MULTILIBS})
615      foreach(name ${LLVM_RUNTIME_MULTILIB_${multilib}_TARGETS})
616        runtime_register_target(${name}+${multilib}
617          DEPENDS runtimes-${name}
618          CMAKE_ARGS -DLLVM_DEFAULT_TARGET_TRIPLE=${name}
619                     -DLLVM_RUNTIMES_PREFIX=${name}/
620                     -DLLVM_RUNTIMES_LIBDIR_SUBDIR=${multilib}
621                     ${extra_cmake_args}
622          BASE_NAME ${name}
623          EXTRA_ARGS TARGET_TRIPLE ${name})
624      endforeach()
625    endforeach()
626  endif()
627
628  if(NOT LLVM_BUILD_INSTRUMENTED AND CLANG_ENABLE_BOOTSTRAP)
629    # TODO: This is a hack needed because the libcxx headers are copied into the
630    # build directory during configuration. Without that step the clang in the
631    # build directory cannot find the C++ headers in certain configurations.
632    # I need to build a mechanism for runtime projects to provide CMake code
633    # that executes at LLVM configuration time to handle this case.
634    add_dependencies(clang-bootstrap-deps runtimes-configure)
635    # We need to add the runtimes as a dependency because compiler-rt can be
636    # built as part of runtimes and we need the profile runtime for PGO
637    add_dependencies(clang-bootstrap-deps runtimes)
638    # The bootstrap build will attempt to configure the offload runtime
639    # before the openmp project which will error out due to failing to
640    # find libomp.so. We must add omp as a dependency before runtimes
641    # are configured.
642    if("openmp" IN_LIST LLVM_ENABLE_PROJECTS AND "offload" IN_LIST LLVM_ENABLE_RUNTIMES)
643      add_dependencies(clang-bootstrap-deps omp)
644    endif()
645  endif()
646
647  if(LLVM_INCLUDE_TESTS)
648    set_property(GLOBAL APPEND PROPERTY LLVM_ALL_ADDITIONAL_TEST_DEPENDS runtimes-test-depends)
649
650    foreach(target ${test_targets} ${SUB_CHECK_TARGETS})
651      add_dependencies(${target} ${extra_deps})
652    endforeach()
653
654    set_property(GLOBAL APPEND PROPERTY LLVM_ALL_ADDITIONAL_TEST_TARGETS runtimes ${extra_deps})
655  endif()
656endif()
657