xref: /llvm-project/llvm/cmake/modules/AddLLVM.cmake (revision ab6d41eae12b29bcb99ed66ca8edb48296ccfe42)
1include(GNUInstallDirs)
2include(LLVMDistributionSupport)
3include(LLVMProcessSources)
4include(LLVM-Config)
5include(DetermineGCCCompatible)
6
7# get_subproject_title(titlevar)
8#   Set ${outvar} to the title of the current LLVM subproject (Clang, MLIR ...)
9#
10# The title is set in the subproject's top-level using the variable
11# LLVM_SUBPROJECT_TITLE. If it does not exist, it is assumed it is LLVM itself.
12# The title is not semantically significant, but use to create folders in
13# CMake-generated IDE projects (Visual Studio/XCode).
14function(get_subproject_title outvar)
15  if (LLVM_SUBPROJECT_TITLE)
16    set(${outvar} "${LLVM_SUBPROJECT_TITLE}" PARENT_SCOPE)
17  else ()
18    set(${outvar} "LLVM" PARENT_SCOPE)
19  endif ()
20endfunction(get_subproject_title)
21
22function(llvm_update_compile_flags name)
23  get_property(sources TARGET ${name} PROPERTY SOURCES)
24  if("${sources}" MATCHES "\\.c(;|$)")
25    set(update_src_props ON)
26  endif()
27
28  list(APPEND LLVM_COMPILE_CFLAGS " ${LLVM_COMPILE_FLAGS}")
29
30  # LLVM_REQUIRES_EH is an internal flag that individual targets can use to
31  # force EH
32  if(LLVM_REQUIRES_EH OR LLVM_ENABLE_EH)
33    if(NOT (LLVM_REQUIRES_RTTI OR LLVM_ENABLE_RTTI))
34      message(AUTHOR_WARNING "Exception handling requires RTTI. Enabling RTTI for ${name}")
35      set(LLVM_REQUIRES_RTTI ON)
36    endif()
37    if(MSVC)
38      list(APPEND LLVM_COMPILE_FLAGS "/EHsc")
39    endif()
40  else()
41    if(LLVM_COMPILER_IS_GCC_COMPATIBLE)
42      list(APPEND LLVM_COMPILE_FLAGS "-fno-exceptions")
43      if(LLVM_ENABLE_UNWIND_TABLES)
44        list(APPEND LLVM_COMPILE_FLAGS "-funwind-tables")
45      else()
46        list(APPEND LLVM_COMPILE_FLAGS "-fno-unwind-tables")
47        list(APPEND LLVM_COMPILE_FLAGS "-fno-asynchronous-unwind-tables")
48      endif()
49    elseif(MSVC)
50      list(APPEND LLVM_COMPILE_DEFINITIONS _HAS_EXCEPTIONS=0)
51      list(APPEND LLVM_COMPILE_FLAGS "/EHs-c-")
52    elseif (CMAKE_CXX_COMPILER_ID MATCHES "XL")
53      list(APPEND LLVM_COMPILE_FLAGS "-qnoeh")
54    endif()
55  endif()
56
57  # LLVM_REQUIRES_RTTI is an internal flag that individual
58  # targets can use to force RTTI
59  set(LLVM_CONFIG_HAS_RTTI YES CACHE INTERNAL "")
60  if(NOT (LLVM_REQUIRES_RTTI OR LLVM_ENABLE_RTTI))
61    set(LLVM_CONFIG_HAS_RTTI NO CACHE INTERNAL "")
62    list(APPEND LLVM_COMPILE_DEFINITIONS GTEST_HAS_RTTI=0)
63    if (LLVM_COMPILER_IS_GCC_COMPATIBLE)
64      list(APPEND LLVM_COMPILE_FLAGS "-fno-rtti")
65    elseif (MSVC)
66      list(APPEND LLVM_COMPILE_FLAGS "/GR-")
67    elseif (CMAKE_CXX_COMPILER_ID MATCHES "XL")
68      list(APPEND LLVM_COMPILE_FLAGS "-qnortti")
69    endif ()
70  elseif(MSVC)
71    list(APPEND LLVM_COMPILE_FLAGS "/GR")
72  endif()
73
74  # Assume that;
75  #   - LLVM_COMPILE_FLAGS is list.
76  #   - PROPERTY COMPILE_FLAGS is string.
77  string(REPLACE ";" " " target_compile_flags " ${LLVM_COMPILE_FLAGS}")
78  string(REPLACE ";" " " target_compile_cflags " ${LLVM_COMPILE_CFLAGS}")
79
80  if(update_src_props)
81    foreach(fn ${sources})
82      get_filename_component(suf ${fn} EXT)
83      if("${suf}" STREQUAL ".cpp")
84        set_property(SOURCE ${fn} APPEND_STRING PROPERTY
85          COMPILE_FLAGS "${target_compile_flags}")
86      endif()
87      if("${suf}" STREQUAL ".c")
88        set_property(SOURCE ${fn} APPEND_STRING PROPERTY
89          COMPILE_FLAGS "${target_compile_cflags}")
90      endif()
91    endforeach()
92  else()
93    # Update target props, since all sources are C++.
94    set_property(TARGET ${name} APPEND_STRING PROPERTY
95      COMPILE_FLAGS "${target_compile_flags}")
96  endif()
97
98  set_property(TARGET ${name} APPEND PROPERTY COMPILE_DEFINITIONS ${LLVM_COMPILE_DEFINITIONS})
99endfunction()
100
101function(add_llvm_symbol_exports target_name export_file)
102  if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
103    set(native_export_file "${target_name}.exports")
104    add_custom_command(OUTPUT ${native_export_file}
105      COMMAND sed -e "s/^/_/" < ${export_file} > ${native_export_file}
106      DEPENDS ${export_file}
107      VERBATIM
108      COMMENT "Creating export file for ${target_name}")
109    set_property(TARGET ${target_name} APPEND_STRING PROPERTY
110                 LINK_FLAGS " -Wl,-exported_symbols_list,\"${CMAKE_CURRENT_BINARY_DIR}/${native_export_file}\"")
111  elseif(${CMAKE_SYSTEM_NAME} MATCHES "AIX")
112    # FIXME: `-Wl,-bE:` bypasses whatever handling there is in the build
113    # compiler driver to defer to the specified export list.
114    set(native_export_file "${export_file}")
115    set_property(TARGET ${target_name} APPEND_STRING PROPERTY
116                 LINK_FLAGS " -Wl,-bE:${export_file}")
117  elseif(LLVM_HAVE_LINK_VERSION_SCRIPT)
118    # Gold and BFD ld require a version script rather than a plain list.
119    set(native_export_file "${target_name}.exports")
120    # FIXME: Don't write the "local:" line on OpenBSD.
121    # in the export file, also add a linker script to version LLVM symbols (form: LLVM_N.M)
122    add_custom_command(OUTPUT ${native_export_file}
123      COMMAND "${Python3_EXECUTABLE}" "-c"
124      "import sys; \
125       lines = ['    ' + l.rstrip() for l in sys.stdin] + ['  local: *;']; \
126       print('LLVM_${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR} {'); \
127       print('  global:') if len(lines) > 1 else None; \
128       print(';\\n'.join(lines) + '\\n};')"
129      < ${export_file} > ${native_export_file}
130      DEPENDS ${export_file}
131      VERBATIM
132      COMMENT "Creating export file for ${target_name}")
133    if (${LLVM_LINKER_IS_SOLARISLD})
134      set_property(TARGET ${target_name} APPEND_STRING PROPERTY
135                   LINK_FLAGS "  -Wl,-M,\"${CMAKE_CURRENT_BINARY_DIR}/${native_export_file}\"")
136    else()
137      set_property(TARGET ${target_name} APPEND_STRING PROPERTY
138                   LINK_FLAGS "  -Wl,--version-script,\"${CMAKE_CURRENT_BINARY_DIR}/${native_export_file}\"")
139    endif()
140  elseif(WIN32)
141    set(native_export_file "${target_name}.def")
142
143    add_custom_command(OUTPUT ${native_export_file}
144      COMMAND "${Python3_EXECUTABLE}" -c "import sys;print(''.join(['EXPORTS\\n']+sys.stdin.readlines(),))"
145        < ${export_file} > ${native_export_file}
146      DEPENDS ${export_file}
147      VERBATIM
148      COMMENT "Creating export file for ${target_name}")
149    set(export_file_linker_flag "${CMAKE_CURRENT_BINARY_DIR}/${native_export_file}")
150    if(MSVC)
151      # cl.exe or clang-cl, i.e. MSVC style command line interface
152      set(export_file_linker_flag "LINKER:/DEF:${export_file_linker_flag}")
153    elseif(CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC")
154      # clang in msvc mode, calling a link.exe/lld-link style linker
155      set(export_file_linker_flag "-Wl,/DEF:${export_file_linker_flag}")
156    elseif(MINGW)
157      # ${export_file_linker_flag}, which is the plain file name, works as is
158      # when passed to the compiler driver, which then passes it on to the
159      # linker as an input file.
160      set(export_file_linker_flag "${export_file_linker_flag}")
161    else()
162      message(FATAL_ERROR "Unsupported Windows toolchain")
163    endif()
164    set_property(TARGET ${target_name} APPEND PROPERTY
165                 LINK_OPTIONS "${export_file_linker_flag}")
166  endif()
167
168  add_custom_target(${target_name}_exports DEPENDS ${native_export_file})
169  get_subproject_title(subproject_title)
170  set_target_properties(${target_name}_exports PROPERTIES FOLDER "${subproject_title}/API")
171
172  get_property(srcs TARGET ${target_name} PROPERTY SOURCES)
173  foreach(src ${srcs})
174    get_filename_component(extension ${src} EXT)
175    if(extension STREQUAL ".cpp")
176      set(first_source_file ${src})
177      break()
178    endif()
179  endforeach()
180
181  # Force re-linking when the exports file changes. Actually, it
182  # forces recompilation of the source file. The LINK_DEPENDS target
183  # property only works for makefile-based generators.
184  # FIXME: This is not safe because this will create the same target
185  # ${native_export_file} in several different file:
186  # - One where we emitted ${target_name}_exports
187  # - One where we emitted the build command for the following object.
188  # set_property(SOURCE ${first_source_file} APPEND PROPERTY
189  #   OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${native_export_file})
190
191  set_property(DIRECTORY APPEND
192    PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${native_export_file})
193
194  add_dependencies(${target_name} ${target_name}_exports)
195
196  # Add dependency to *_exports later -- CMake issue 14747
197  list(APPEND LLVM_COMMON_DEPENDS ${target_name}_exports)
198  set(LLVM_COMMON_DEPENDS ${LLVM_COMMON_DEPENDS} PARENT_SCOPE)
199endfunction(add_llvm_symbol_exports)
200
201if (NOT DEFINED LLVM_LINKER_DETECTED AND NOT WIN32)
202  # Detect what linker we have here.
203  if(APPLE)
204    # Linkers with ld64-compatible flags.
205    set(version_flag "-Wl,-v")
206  else()
207    # Linkers with BFD ld-compatible flags.
208    set(version_flag "-Wl,--version")
209  endif()
210
211  if (CMAKE_HOST_WIN32)
212    set(DEVNULL "NUL")
213  else()
214    set(DEVNULL "/dev/null")
215  endif()
216
217  if(LLVM_USE_LINKER)
218    set(command ${CMAKE_C_COMPILER} -fuse-ld=${LLVM_USE_LINKER} ${version_flag} -o ${DEVNULL})
219  else()
220    separate_arguments(flags UNIX_COMMAND "${CMAKE_EXE_LINKER_FLAGS}")
221    set(command ${CMAKE_C_COMPILER} ${flags} ${version_flag} -o ${DEVNULL})
222  endif()
223  execute_process(
224    COMMAND ${command}
225    OUTPUT_VARIABLE stdout
226    ERROR_VARIABLE stderr
227    )
228
229  if(APPLE)
230    if("${stderr}" MATCHES "PROGRAM:ld")
231      set(LLVM_LINKER_DETECTED YES CACHE INTERNAL "")
232      set(LLVM_LINKER_IS_APPLE YES CACHE INTERNAL "")
233      message(STATUS "Linker detection: Apple")
234    elseif("${stderr}" MATCHES "^LLD" OR
235           "${stdout}" MATCHES "^LLD")
236      set(LLVM_LINKER_DETECTED YES CACHE INTERNAL "")
237      set(LLVM_LINKER_IS_LLD YES CACHE INTERNAL "")
238      message(STATUS "Linker detection: lld")
239    else()
240      set(LLVM_LINKER_DETECTED NO CACHE INTERNAL "")
241      message(STATUS "Linker detection: unknown")
242    endif()
243  else()
244    if("${stdout}" MATCHES "^mold")
245      set(LLVM_LINKER_DETECTED YES CACHE INTERNAL "")
246      set(LLVM_LINKER_IS_MOLD YES CACHE INTERNAL "")
247      message(STATUS "Linker detection: mold")
248    elseif("${stdout}" MATCHES "GNU gold")
249      set(LLVM_LINKER_DETECTED YES CACHE INTERNAL "")
250      set(LLVM_LINKER_IS_GOLD YES CACHE INTERNAL "")
251      message(STATUS "Linker detection: GNU Gold")
252    elseif("${stdout}" MATCHES "^LLD")
253      set(LLVM_LINKER_DETECTED YES CACHE INTERNAL "")
254      set(LLVM_LINKER_IS_LLD YES CACHE INTERNAL "")
255      message(STATUS "Linker detection: LLD")
256    elseif("${stdout}" MATCHES "GNU ld")
257      set(LLVM_LINKER_DETECTED YES CACHE INTERNAL "")
258      set(LLVM_LINKER_IS_GNULD YES CACHE INTERNAL "")
259      message(STATUS "Linker detection: GNU ld")
260    elseif("${stderr}" MATCHES "(illumos)" OR
261           "${stdout}" MATCHES "(illumos)")
262      set(LLVM_LINKER_DETECTED YES CACHE INTERNAL "")
263      set(LLVM_LINKER_IS_SOLARISLD YES CACHE INTERNAL "")
264      set(LLVM_LINKER_IS_SOLARISLD_ILLUMOS YES CACHE INTERNAL "")
265      message(STATUS "Linker detection: Solaris ld (illumos)")
266    elseif("${stderr}" MATCHES "Solaris Link Editors" OR
267           "${stdout}" MATCHES "Solaris Link Editors")
268      set(LLVM_LINKER_DETECTED YES CACHE INTERNAL "")
269      set(LLVM_LINKER_IS_SOLARISLD YES CACHE INTERNAL "")
270      message(STATUS "Linker detection: Solaris ld")
271    else()
272      set(LLVM_LINKER_DETECTED NO CACHE INTERNAL "")
273      message(STATUS "Linker detection: unknown")
274    endif()
275  endif()
276
277  if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
278    include(CheckLinkerFlag)
279    # Linkers that support Darwin allow a setting to internalize all symbol exports,
280    # aiding in reducing binary size and often is applicable for executables.
281    check_linker_flag(C "-Wl,-no_exported_symbols" LLVM_LINKER_SUPPORTS_NO_EXPORTED_SYMBOLS)
282
283    if (NOT LLVM_USE_LINKER)
284      # Apple's linker complains about duplicate libraries, which CMake likes to do
285      # to support ELF platforms. To silence that warning, we can use
286      # -no_warn_duplicate_libraries, but only in versions of the linker that
287      # support that flag.
288      check_linker_flag(C "-Wl,-no_warn_duplicate_libraries" LLVM_LINKER_SUPPORTS_NO_WARN_DUPLICATE_LIBRARIES)
289    else()
290      set(LLVM_LINKER_SUPPORTS_NO_WARN_DUPLICATE_LIBRARIES OFF CACHE INTERNAL "")
291    endif()
292
293  else()
294    set(LLVM_LINKER_SUPPORTS_NO_EXPORTED_SYMBOLS OFF CACHE INTERNAL "")
295  endif()
296endif()
297
298function(add_link_opts target_name)
299  get_llvm_distribution(${target_name} in_distribution in_distribution_var)
300  if(NOT in_distribution)
301    # Don't LTO optimize targets that aren't part of any distribution.
302    if (LLVM_ENABLE_LTO)
303      # We may consider avoiding LTO altogether by using -fembed-bitcode
304      # and teaching the linker to select machine code from .o files, see
305      # https://lists.llvm.org/pipermail/llvm-dev/2021-April/149843.html
306      if((UNIX OR MINGW) AND LINKER_IS_LLD)
307        set_property(TARGET ${target_name} APPEND_STRING PROPERTY
308                      LINK_FLAGS " -Wl,--lto-O0")
309      elseif(LINKER_IS_LLD_LINK)
310        set_property(TARGET ${target_name} APPEND_STRING PROPERTY
311                      LINK_FLAGS " /opt:lldlto=0")
312      elseif(APPLE AND NOT uppercase_LLVM_ENABLE_LTO STREQUAL "THIN")
313        set_property(TARGET ${target_name} APPEND_STRING PROPERTY
314                      LINK_FLAGS " -Wl,-mllvm,-O0")
315      endif()
316    endif()
317  endif()
318
319  # Don't use linker optimizations in debug builds since it slows down the
320  # linker in a context where the optimizations are not important.
321  if (NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG")
322    if(NOT LLVM_NO_DEAD_STRIP)
323      if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
324        # ld64's implementation of -dead_strip breaks tools that use plugins.
325        set_property(TARGET ${target_name} APPEND_STRING PROPERTY
326                     LINK_FLAGS " -Wl,-dead_strip")
327      elseif(${CMAKE_SYSTEM_NAME} MATCHES "SunOS" AND LLVM_LINKER_IS_SOLARISLD)
328        # Support for ld -z discard-unused=sections was only added in
329        # Solaris 11.4.  GNU ld ignores it, but warns every time.
330        include(CheckLinkerFlag)
331        check_linker_flag(CXX "-Wl,-z,discard-unused=sections" LINKER_SUPPORTS_Z_DISCARD_UNUSED)
332        if (LINKER_SUPPORTS_Z_DISCARD_UNUSED)
333          set_property(TARGET ${target_name} APPEND_STRING PROPERTY
334                       LINK_FLAGS " -Wl,-z,discard-unused=sections")
335        endif()
336      elseif(NOT MSVC AND NOT CMAKE_SYSTEM_NAME MATCHES "AIX|OS390")
337        # TODO Revisit this later on z/OS.
338        set_property(TARGET ${target_name} APPEND_STRING PROPERTY
339                     LINK_FLAGS " -Wl,--gc-sections")
340      endif()
341    else() #LLVM_NO_DEAD_STRIP
342      if(${CMAKE_SYSTEM_NAME} MATCHES "AIX")
343        set_property(TARGET ${target_name} APPEND_STRING PROPERTY
344                     LINK_FLAGS " -Wl,-bnogc")
345      endif()
346    endif()
347  endif()
348
349  if(LLVM_LINKER_SUPPORTS_NO_WARN_DUPLICATE_LIBRARIES)
350    set_property(TARGET ${target_name} APPEND_STRING PROPERTY
351                 LINK_FLAGS " -Wl,-no_warn_duplicate_libraries")
352  endif()
353
354  if(ARG_SUPPORT_PLUGINS AND ${CMAKE_SYSTEM_NAME} MATCHES "AIX")
355    set_property(TARGET ${target_name} APPEND_STRING PROPERTY
356                 LINK_FLAGS " -Wl,-brtl")
357  endif()
358endfunction(add_link_opts)
359
360# Set each output directory according to ${CMAKE_CONFIGURATION_TYPES}.
361# Note: Don't set variables CMAKE_*_OUTPUT_DIRECTORY any more,
362# or a certain builder, for eaxample, msbuild.exe, would be confused.
363function(set_output_directory target)
364  cmake_parse_arguments(ARG "" "BINARY_DIR;LIBRARY_DIR" "" ${ARGN})
365
366  # module_dir -- corresponding to LIBRARY_OUTPUT_DIRECTORY.
367  # It affects output of add_library(MODULE).
368  if(WIN32 OR CYGWIN)
369    # DLL platform
370    set(module_dir ${ARG_BINARY_DIR})
371  else()
372    set(module_dir ${ARG_LIBRARY_DIR})
373  endif()
374  if(NOT "${CMAKE_CFG_INTDIR}" STREQUAL ".")
375    foreach(build_mode ${CMAKE_CONFIGURATION_TYPES})
376      string(TOUPPER "${build_mode}" CONFIG_SUFFIX)
377      if(ARG_BINARY_DIR)
378        string(REPLACE ${CMAKE_CFG_INTDIR} ${build_mode} bi ${ARG_BINARY_DIR})
379        set_target_properties(${target} PROPERTIES "RUNTIME_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${bi})
380      endif()
381      if(ARG_LIBRARY_DIR)
382        string(REPLACE ${CMAKE_CFG_INTDIR} ${build_mode} li ${ARG_LIBRARY_DIR})
383        set_target_properties(${target} PROPERTIES "ARCHIVE_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${li})
384      endif()
385      if(module_dir)
386        string(REPLACE ${CMAKE_CFG_INTDIR} ${build_mode} mi ${module_dir})
387        set_target_properties(${target} PROPERTIES "LIBRARY_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${mi})
388      endif()
389    endforeach()
390  else()
391    if(ARG_BINARY_DIR)
392      set_target_properties(${target} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${ARG_BINARY_DIR})
393    endif()
394    if(ARG_LIBRARY_DIR)
395      set_target_properties(${target} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${ARG_LIBRARY_DIR})
396    endif()
397    if(module_dir)
398      set_target_properties(${target} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${module_dir})
399    endif()
400  endif()
401endfunction()
402
403# If on Windows and building with MSVC, add the resource script containing the
404# VERSIONINFO data to the project.  This embeds version resource information
405# into the output .exe or .dll.
406# TODO: Enable for MinGW Windows builds too.
407#
408function(add_windows_version_resource_file OUT_VAR)
409  set(sources ${ARGN})
410  if (MSVC AND CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
411    set(resource_file ${LLVM_SOURCE_DIR}/resources/windows_version_resource.rc)
412    if(EXISTS ${resource_file})
413      set(sources ${sources} ${resource_file})
414      source_group("Resource Files" ${resource_file})
415      set(windows_resource_file ${resource_file} PARENT_SCOPE)
416    endif()
417  endif(MSVC AND CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
418
419  set(${OUT_VAR} ${sources} PARENT_SCOPE)
420endfunction(add_windows_version_resource_file)
421
422# set_windows_version_resource_properties(name resource_file...
423#   VERSION_MAJOR int
424#     Optional major version number (defaults to LLVM_VERSION_MAJOR)
425#   VERSION_MINOR int
426#     Optional minor version number (defaults to LLVM_VERSION_MINOR)
427#   VERSION_PATCHLEVEL int
428#     Optional patchlevel version number (defaults to LLVM_VERSION_PATCH)
429#   VERSION_STRING
430#     Optional version string (defaults to PACKAGE_VERSION)
431#   PRODUCT_NAME
432#     Optional product name string (defaults to "LLVM")
433#   )
434function(set_windows_version_resource_properties name resource_file)
435  cmake_parse_arguments(ARG
436    ""
437    "VERSION_MAJOR;VERSION_MINOR;VERSION_PATCHLEVEL;VERSION_STRING;PRODUCT_NAME"
438    ""
439    ${ARGN})
440
441  if (NOT DEFINED ARG_VERSION_MAJOR)
442    if (${LLVM_VERSION_MAJOR})
443      set(ARG_VERSION_MAJOR ${LLVM_VERSION_MAJOR})
444    else()
445      set(ARG_VERSION_MAJOR 0)
446    endif()
447  endif()
448
449  if (NOT DEFINED ARG_VERSION_MINOR)
450    if (${LLVM_VERSION_MINOR})
451      set(ARG_VERSION_MINOR ${LLVM_VERSION_MINOR})
452    else()
453      set(ARG_VERSION_MINOR 0)
454    endif()
455  endif()
456
457  if (NOT DEFINED ARG_VERSION_PATCHLEVEL)
458    if (${LLVM_VERSION_PATCH})
459      set(ARG_VERSION_PATCHLEVEL ${LLVM_VERSION_PATCH})
460    else()
461      set(ARG_VERSION_PATCHLEVEL 0)
462    endif()
463  endif()
464
465  if (NOT DEFINED ARG_VERSION_STRING)
466    if (${PACKAGE_VERSION})
467      set(ARG_VERSION_STRING ${PACKAGE_VERSION})
468    else()
469      set(ARG_VERSION_STRING 0)
470    endif()
471  endif()
472
473  if (NOT DEFINED ARG_PRODUCT_NAME)
474    set(ARG_PRODUCT_NAME "LLVM")
475  endif()
476
477  set_property(SOURCE ${resource_file}
478               PROPERTY COMPILE_FLAGS /nologo)
479  set_property(SOURCE ${resource_file}
480               PROPERTY COMPILE_DEFINITIONS
481               "RC_VERSION_FIELD_1=${ARG_VERSION_MAJOR}"
482               "RC_VERSION_FIELD_2=${ARG_VERSION_MINOR}"
483               "RC_VERSION_FIELD_3=${ARG_VERSION_PATCHLEVEL}"
484               "RC_VERSION_FIELD_4=0"
485               "RC_FILE_VERSION=\"${ARG_VERSION_STRING}\""
486               "RC_INTERNAL_NAME=\"${name}\""
487               "RC_PRODUCT_NAME=\"${ARG_PRODUCT_NAME}\""
488               "RC_PRODUCT_VERSION=\"${ARG_VERSION_STRING}\"")
489endfunction(set_windows_version_resource_properties)
490
491# llvm_add_library(name sources...
492#   SHARED;STATIC
493#     STATIC by default w/o BUILD_SHARED_LIBS.
494#     SHARED by default w/  BUILD_SHARED_LIBS.
495#   OBJECT
496#     Also create an OBJECT library target. Default if STATIC && SHARED.
497#   MODULE
498#     Target ${name} might not be created on unsupported platforms.
499#     Check with "if(TARGET ${name})".
500#   DISABLE_LLVM_LINK_LLVM_DYLIB
501#     Do not link this library to libLLVM, even if
502#     LLVM_LINK_LLVM_DYLIB is enabled.
503#   OUTPUT_NAME name
504#     Corresponds to OUTPUT_NAME in target properties.
505#   DEPENDS targets...
506#     Same semantics as add_dependencies().
507#   LINK_COMPONENTS components...
508#     Same as the variable LLVM_LINK_COMPONENTS.
509#   LINK_LIBS lib_targets...
510#     Same semantics as target_link_libraries().
511#   ADDITIONAL_HEADERS
512#     May specify header files for IDE generators.
513#   SONAME
514#     Should set SONAME link flags and create symlinks
515#   NO_INSTALL_RPATH
516#     Suppress default RPATH settings in shared libraries.
517#   PLUGIN_TOOL
518#     The tool (i.e. cmake target) that this plugin will link against
519#   COMPONENT_LIB
520#      This is used to specify that this is a component library of
521#      LLVM which means that the source resides in llvm/lib/ and it is a
522#      candidate for inclusion into libLLVM.so.
523#   )
524function(llvm_add_library name)
525  cmake_parse_arguments(ARG
526    "MODULE;SHARED;STATIC;OBJECT;DISABLE_LLVM_LINK_LLVM_DYLIB;SONAME;NO_INSTALL_RPATH;COMPONENT_LIB"
527    "OUTPUT_NAME;PLUGIN_TOOL;ENTITLEMENTS;BUNDLE_PATH"
528    "ADDITIONAL_HEADERS;DEPENDS;LINK_COMPONENTS;LINK_LIBS;OBJLIBS"
529    ${ARGN})
530  list(APPEND LLVM_COMMON_DEPENDS ${ARG_DEPENDS})
531  if(ARG_ADDITIONAL_HEADERS)
532    # Pass through ADDITIONAL_HEADERS.
533    set(ARG_ADDITIONAL_HEADERS ADDITIONAL_HEADERS ${ARG_ADDITIONAL_HEADERS})
534  endif()
535  if(ARG_OBJLIBS)
536    set(ALL_FILES ${ARG_OBJLIBS})
537  else()
538    llvm_process_sources(ALL_FILES ${ARG_UNPARSED_ARGUMENTS} ${ARG_ADDITIONAL_HEADERS})
539  endif()
540
541  if(ARG_MODULE)
542    if(ARG_SHARED OR ARG_STATIC)
543      message(WARNING "MODULE with SHARED|STATIC doesn't make sense.")
544    endif()
545    # Plugins that link against a tool are allowed even when plugins in general are not
546    if(NOT LLVM_ENABLE_PLUGINS AND NOT (ARG_PLUGIN_TOOL AND LLVM_EXPORT_SYMBOLS_FOR_PLUGINS))
547      message(STATUS "${name} ignored -- Loadable modules not supported on this platform.")
548      return()
549    endif()
550  else()
551    if(ARG_PLUGIN_TOOL)
552      message(WARNING "PLUGIN_TOOL without MODULE doesn't make sense.")
553    endif()
554    if(BUILD_SHARED_LIBS AND NOT ARG_STATIC)
555      set(ARG_SHARED TRUE)
556    endif()
557    if(NOT ARG_SHARED)
558      set(ARG_STATIC TRUE)
559    endif()
560  endif()
561
562  get_subproject_title(subproject_title)
563
564  # Generate objlib
565  if((ARG_SHARED AND ARG_STATIC) OR ARG_OBJECT)
566    # Generate an obj library for both targets.
567    set(obj_name "obj.${name}")
568    add_library(${obj_name} OBJECT EXCLUDE_FROM_ALL
569      ${ALL_FILES}
570      )
571    llvm_update_compile_flags(${obj_name})
572    if(CMAKE_GENERATOR STREQUAL "Xcode")
573      set(DUMMY_FILE ${CMAKE_CURRENT_BINARY_DIR}/Dummy.c)
574      file(WRITE ${DUMMY_FILE} "// This file intentionally empty\n")
575      set_property(SOURCE ${DUMMY_FILE} APPEND_STRING PROPERTY COMPILE_FLAGS "-Wno-empty-translation-unit")
576    endif()
577    set(ALL_FILES "$<TARGET_OBJECTS:${obj_name}>" ${DUMMY_FILE})
578
579    # Do add_dependencies(obj) later due to CMake issue 14747.
580    list(APPEND objlibs ${obj_name})
581
582    # Bring in the target include directories from our original target.
583    target_include_directories(${obj_name} PRIVATE $<TARGET_PROPERTY:${name},INCLUDE_DIRECTORIES>)
584
585    set_target_properties(${obj_name} PROPERTIES FOLDER "${subproject_title}/Object Libraries")
586    if(ARG_DEPENDS)
587      add_dependencies(${obj_name} ${ARG_DEPENDS})
588    endif()
589    # Treat link libraries like PUBLIC dependencies.  LINK_LIBS might
590    # result in generating header files.  Add a dependendency so that
591    # the generated header is created before this object library.
592    if(ARG_LINK_LIBS)
593      cmake_parse_arguments(LINK_LIBS_ARG
594        ""
595        ""
596        "PUBLIC;PRIVATE"
597        ${ARG_LINK_LIBS})
598      foreach(link_lib ${LINK_LIBS_ARG_PUBLIC})
599        if(LLVM_PTHREAD_LIB)
600          # Can't specify a dependence on -lpthread
601          if(NOT ${link_lib} STREQUAL ${LLVM_PTHREAD_LIB})
602            add_dependencies(${obj_name} ${link_lib})
603          endif()
604        else()
605          add_dependencies(${obj_name} ${link_lib})
606        endif()
607      endforeach()
608    endif()
609
610    if(ARG_DISABLE_LLVM_LINK_LLVM_DYLIB)
611      target_compile_definitions(${obj_name} PRIVATE LLVM_BUILD_STATIC)
612    endif()
613  endif()
614
615  if(ARG_SHARED AND ARG_STATIC)
616    # static
617    set(name_static "${name}_static")
618    if(ARG_OUTPUT_NAME)
619      set(output_name OUTPUT_NAME "${ARG_OUTPUT_NAME}")
620    endif()
621    # DEPENDS has been appended to LLVM_COMMON_LIBS.
622    llvm_add_library(${name_static} STATIC
623      ${output_name}
624      OBJLIBS ${ALL_FILES} # objlib
625      LINK_LIBS ${ARG_LINK_LIBS}
626      LINK_COMPONENTS ${ARG_LINK_COMPONENTS}
627      )
628    set_target_properties(${name_static} PROPERTIES FOLDER "${subproject_title}/Libraries")
629
630    # Bring in the target link info from our original target.
631    target_link_directories(${name_static} PRIVATE $<TARGET_PROPERTY:${name},LINK_DIRECTORIES>)
632    target_link_libraries(${name_static} PRIVATE $<TARGET_PROPERTY:${name},LINK_LIBRARIES>)
633
634    # FIXME: Add name_static to anywhere in TARGET ${name}'s PROPERTY.
635    set(ARG_STATIC)
636  endif()
637
638  if(ARG_MODULE)
639    add_library(${name} MODULE ${ALL_FILES})
640  elseif(ARG_SHARED)
641    add_windows_version_resource_file(ALL_FILES ${ALL_FILES})
642    add_library(${name} SHARED ${ALL_FILES})
643  else()
644    add_library(${name} STATIC ${ALL_FILES})
645  endif()
646  set_target_properties(${name} PROPERTIES FOLDER "${subproject_title}/Libraries")
647
648  ## If were compiling with clang-cl use /Zc:dllexportInlines- to exclude inline
649  ## class members from being dllexport'ed to reduce compile time.
650  ## This will also keep us below the 64k exported symbol limit
651  ## https://blog.llvm.org/2018/11/30-faster-windows-builds-with-clang-cl_14.html
652  if(LLVM_BUILD_LLVM_DYLIB AND NOT LLVM_DYLIB_EXPORT_INLINES AND
653     MSVC AND CMAKE_CXX_COMPILER_ID MATCHES Clang)
654    target_compile_options(${name} PUBLIC /Zc:dllexportInlines-)
655    if(TARGET ${obj_name})
656      target_compile_options(${obj_name} PUBLIC /Zc:dllexportInlines-)
657    endif()
658  endif()
659
660  if(ARG_COMPONENT_LIB)
661    set_target_properties(${name} PROPERTIES LLVM_COMPONENT TRUE)
662    if(LLVM_BUILD_LLVM_DYLIB OR BUILD_SHARED_LIBS)
663      target_compile_definitions(${name} PRIVATE LLVM_EXPORTS)
664    endif()
665
666    # When building shared objects for each target there are some internal APIs
667    # that are used across shared objects which we can't hide.
668    if (LLVM_BUILD_LLVM_DYLIB_VIS AND NOT BUILD_SHARED_LIBS AND NOT APPLE AND
669        (NOT (WIN32 OR CYGWIN) OR (MINGW AND CMAKE_CXX_COMPILER_ID MATCHES "Clang")) AND
670        NOT (${CMAKE_SYSTEM_NAME} MATCHES "AIX") AND
671        NOT DEFINED CMAKE_CXX_VISIBILITY_PRESET)
672
673      set_target_properties(${name} PROPERTIES
674                            C_VISIBILITY_PRESET hidden
675                            CXX_VISIBILITY_PRESET hidden
676                            VISIBILITY_INLINES_HIDDEN YES)
677    endif()
678    set_property(GLOBAL APPEND PROPERTY LLVM_COMPONENT_LIBS ${name})
679  endif()
680
681  if(NOT ARG_NO_INSTALL_RPATH)
682    if(ARG_MODULE OR ARG_SHARED)
683      llvm_setup_rpath(${name})
684    endif()
685  endif()
686
687  setup_dependency_debugging(${name} ${LLVM_COMMON_DEPENDS})
688
689  if(DEFINED windows_resource_file)
690    set_windows_version_resource_properties(${name} ${windows_resource_file})
691    set(windows_resource_file ${windows_resource_file} PARENT_SCOPE)
692  endif()
693
694  set_output_directory(${name} BINARY_DIR ${LLVM_RUNTIME_OUTPUT_INTDIR} LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR})
695  # $<TARGET_OBJECTS> doesn't require compile flags.
696  if(NOT obj_name)
697    llvm_update_compile_flags(${name})
698  endif()
699  add_link_opts( ${name} )
700  if(ARG_OUTPUT_NAME)
701    set_target_properties(${name}
702      PROPERTIES
703      OUTPUT_NAME ${ARG_OUTPUT_NAME}
704      )
705  endif()
706
707  if(ARG_MODULE)
708    set_target_properties(${name} PROPERTIES
709      PREFIX ""
710      SUFFIX ${LLVM_PLUGIN_EXT}
711      )
712  endif()
713
714  if(ARG_SHARED)
715    if(MSVC)
716      set_target_properties(${name} PROPERTIES
717        PREFIX ""
718        )
719    endif()
720
721    # Set SOVERSION on shared libraries that lack explicit SONAME
722    # specifier, on *nix systems that are not Darwin.
723    if(UNIX AND NOT APPLE AND NOT ARG_SONAME)
724      set_target_properties(${name}
725        PROPERTIES
726        # Since 18.1.0, the ABI version is indicated by the major and minor version.
727        SOVERSION ${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}${LLVM_VERSION_SUFFIX}
728        VERSION ${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}${LLVM_VERSION_SUFFIX})
729    endif()
730  endif()
731
732  if(ARG_MODULE OR ARG_SHARED)
733    # Do not add -Dname_EXPORTS to the command-line when building files in this
734    # target. Doing so is actively harmful for the modules build because it
735    # creates extra module variants, and not useful because we don't use these
736    # macros.
737    set_target_properties( ${name} PROPERTIES DEFINE_SYMBOL "" )
738
739    if (LLVM_EXPORTED_SYMBOL_FILE)
740      add_llvm_symbol_exports( ${name} ${LLVM_EXPORTED_SYMBOL_FILE} )
741    endif()
742  endif()
743
744  if(ARG_SHARED)
745    if(NOT APPLE AND ARG_SONAME)
746      get_target_property(output_name ${name} OUTPUT_NAME)
747      if(${output_name} STREQUAL "output_name-NOTFOUND")
748        set(output_name ${name})
749      endif()
750      set(library_name ${output_name}-${LLVM_VERSION_MAJOR}${LLVM_VERSION_SUFFIX})
751      set(api_name ${output_name}-${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}${LLVM_VERSION_SUFFIX})
752      set_target_properties(${name} PROPERTIES OUTPUT_NAME ${library_name})
753      if(UNIX)
754        llvm_install_library_symlink(${api_name} ${library_name} SHARED
755          COMPONENT ${name})
756        llvm_install_library_symlink(${output_name} ${library_name} SHARED
757          COMPONENT ${name})
758      endif()
759    endif()
760  endif()
761
762  if(ARG_STATIC)
763    set(libtype PUBLIC)
764  else()
765    # We can use PRIVATE since SO knows its dependent libs.
766    set(libtype PRIVATE)
767  endif()
768
769  if(ARG_MODULE AND LLVM_EXPORT_SYMBOLS_FOR_PLUGINS AND ARG_PLUGIN_TOOL AND (WIN32 OR CYGWIN))
770    # On DLL platforms symbols are imported from the tool by linking against it.
771    set(llvm_libs ${ARG_PLUGIN_TOOL})
772  elseif (NOT ARG_COMPONENT_LIB)
773    if (LLVM_LINK_LLVM_DYLIB AND NOT ARG_DISABLE_LLVM_LINK_LLVM_DYLIB)
774      set(llvm_libs LLVM)
775    else()
776      if(ARG_DISABLE_LLVM_LINK_LLVM_DYLIB)
777        target_compile_definitions(${name} PRIVATE LLVM_BUILD_STATIC)
778      endif()
779      llvm_map_components_to_libnames(llvm_libs
780       ${ARG_LINK_COMPONENTS}
781       ${LLVM_LINK_COMPONENTS}
782       )
783    endif()
784  else()
785    # Components have not been defined explicitly in CMake, so add the
786    # dependency information for this library through their name, and let
787    # LLVMBuildResolveComponentsLink resolve the mapping.
788    #
789    # It would be nice to verify that we have the dependencies for this library
790    # name, but using get_property(... SET) doesn't suffice to determine if a
791    # property has been set to an empty value.
792    set_property(TARGET ${name} PROPERTY LLVM_LINK_COMPONENTS ${ARG_LINK_COMPONENTS} ${LLVM_LINK_COMPONENTS})
793
794    # This property is an internal property only used to make sure the
795    # link step applied in LLVMBuildResolveComponentsLink uses the same
796    # property as the target_link_libraries call below.
797    set_property(TARGET ${name} PROPERTY LLVM_LIBTYPE ${libtype})
798  endif()
799
800  target_link_libraries(${name} ${libtype}
801      ${ARG_LINK_LIBS}
802      ${lib_deps}
803      ${llvm_libs}
804      )
805
806  if(LLVM_COMMON_DEPENDS)
807    add_dependencies(${name} ${LLVM_COMMON_DEPENDS})
808    # Add dependencies also to objlibs.
809    # CMake issue 14747 --  add_dependencies() might be ignored to objlib's user.
810    foreach(objlib ${objlibs})
811      add_dependencies(${objlib} ${LLVM_COMMON_DEPENDS})
812    endforeach()
813  endif()
814
815  add_custom_linker_flags(${name})
816
817  if(ARG_SHARED OR ARG_MODULE)
818    llvm_externalize_debuginfo(${name})
819    llvm_codesign(${name} ENTITLEMENTS ${ARG_ENTITLEMENTS} BUNDLE_PATH ${ARG_BUNDLE_PATH})
820  endif()
821  # clang and newer versions of ninja use high-resolutions timestamps,
822  # but older versions of libtool on Darwin don't, so the archive will
823  # often get an older timestamp than the last object that was added
824  # or updated.  To fix this, we add a custom command to touch archive
825  # after it's been built so that ninja won't rebuild it unnecessarily
826  # the next time it's run.
827  if(ARG_STATIC AND LLVM_TOUCH_STATIC_LIBRARIES)
828    add_custom_command(TARGET ${name}
829      POST_BUILD
830      COMMAND touch ${LLVM_LIBRARY_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}${name}${CMAKE_STATIC_LIBRARY_SUFFIX}
831      )
832  endif()
833endfunction()
834
835function(add_llvm_install_targets target)
836  cmake_parse_arguments(ARG "" "COMPONENT;PREFIX;SYMLINK" "DEPENDS" ${ARGN})
837  if(ARG_COMPONENT)
838    set(component_option -DCMAKE_INSTALL_COMPONENT="${ARG_COMPONENT}")
839  endif()
840  if(ARG_PREFIX)
841    set(prefix_option -DCMAKE_INSTALL_PREFIX="${ARG_PREFIX}")
842  endif()
843
844  set(file_dependencies)
845  set(target_dependencies)
846  foreach(dependency ${ARG_DEPENDS})
847    if(TARGET ${dependency})
848      list(APPEND target_dependencies ${dependency})
849    else()
850      list(APPEND file_dependencies ${dependency})
851    endif()
852  endforeach()
853
854  get_subproject_title(subproject_title)
855
856  add_custom_target(${target}
857                    DEPENDS ${file_dependencies}
858                    COMMAND "${CMAKE_COMMAND}"
859                            ${component_option}
860                            ${prefix_option}
861                            -P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
862                    USES_TERMINAL)
863  set_target_properties(${target} PROPERTIES FOLDER "${subproject_title}/Installation")
864  add_custom_target(${target}-stripped
865                    DEPENDS ${file_dependencies}
866                    COMMAND "${CMAKE_COMMAND}"
867                            ${component_option}
868                            ${prefix_option}
869                            -DCMAKE_INSTALL_DO_STRIP=1
870                            -P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
871                    USES_TERMINAL)
872  set_target_properties(${target}-stripped PROPERTIES FOLDER "${subproject_title}/Installation")
873  if(target_dependencies)
874    add_dependencies(${target} ${target_dependencies})
875    add_dependencies(${target}-stripped ${target_dependencies})
876  endif()
877
878  if(ARG_SYMLINK)
879    add_dependencies(${target} install-${ARG_SYMLINK})
880    add_dependencies(${target}-stripped install-${ARG_SYMLINK}-stripped)
881  endif()
882endfunction()
883
884# Define special targets that behave like a component group. They don't have any
885# source attached but other components can add themselves to them. If the
886# component supports is a Target and it supports JIT compilation, HAS_JIT must
887# be passed. One can use ADD_TO_COMPONENT option from add_llvm_component_library
888# to link extra component into an existing group.
889function(add_llvm_component_group name)
890  cmake_parse_arguments(ARG "HAS_JIT" "" "LINK_COMPONENTS" ${ARGN})
891  add_custom_target(${name})
892  get_subproject_title(subproject_title)
893  set_target_properties(${name} PROPERTIES FOLDER "${subproject_title}/Component Groups")
894  if(ARG_HAS_JIT)
895    set_property(TARGET ${name} PROPERTY COMPONENT_HAS_JIT ON)
896  endif()
897  if(ARG_LINK_COMPONENTS)
898    set_property(TARGET ${name} PROPERTY LLVM_LINK_COMPONENTS ${ARG_LINK_COMPONENTS})
899  endif()
900endfunction()
901
902# An LLVM component is a cmake target with the following cmake properties
903# eventually set:
904#   - LLVM_COMPONENT_NAME: the name of the component, which can be the name of
905#     the associated library or the one specified through COMPONENT_NAME
906#   - LLVM_LINK_COMPONENTS: a list of component this component depends on
907#   - COMPONENT_HAS_JIT: (only for group component) whether this target group
908#     supports JIT compilation
909# Additionnaly, the ADD_TO_COMPONENT <component> option make it possible to add this
910# component to the LLVM_LINK_COMPONENTS of <component>.
911function(add_llvm_component_library name)
912  cmake_parse_arguments(ARG
913    ""
914    "COMPONENT_NAME;ADD_TO_COMPONENT"
915    ""
916    ${ARGN})
917  add_llvm_library(${name} COMPONENT_LIB ${ARG_UNPARSED_ARGUMENTS})
918  string(REGEX REPLACE "^LLVM" "" component_name ${name})
919  set_property(TARGET ${name} PROPERTY LLVM_COMPONENT_NAME ${component_name})
920
921  if(ARG_COMPONENT_NAME)
922    set_property(GLOBAL PROPERTY LLVM_COMPONENT_NAME_${ARG_COMPONENT_NAME} ${component_name})
923  endif()
924
925  if(ARG_ADD_TO_COMPONENT)
926    set_property(TARGET ${ARG_ADD_TO_COMPONENT} APPEND PROPERTY LLVM_LINK_COMPONENTS ${component_name})
927    get_subproject_title(subproject_title)
928    set_target_properties(${name} PROPERTIES FOLDER "${subproject_title}/Libraries/${ARG_ADD_TO_COMPONENT}")
929  endif()
930
931endfunction()
932
933macro(add_llvm_library name)
934  cmake_parse_arguments(ARG
935    "SHARED;BUILDTREE_ONLY;MODULE;INSTALL_WITH_TOOLCHAIN;NO_EXPORT"
936    ""
937    ""
938    ${ARGN})
939  if(ARG_MODULE)
940    llvm_add_library(${name} MODULE ${ARG_UNPARSED_ARGUMENTS})
941  elseif( BUILD_SHARED_LIBS OR ARG_SHARED )
942    llvm_add_library(${name} SHARED ${ARG_UNPARSED_ARGUMENTS})
943  else()
944    llvm_add_library(${name} ${ARG_UNPARSED_ARGUMENTS})
945  endif()
946
947  # Libraries that are meant to only be exposed via the build tree only are
948  # never installed and are only exported as a target in the special build tree
949  # config file.
950  if (NOT ARG_BUILDTREE_ONLY AND NOT ARG_MODULE)
951    set_property( GLOBAL APPEND PROPERTY LLVM_LIBS ${name} )
952    set(in_llvm_libs YES)
953  endif()
954
955  if (ARG_MODULE AND NOT TARGET ${name})
956    # Add empty "phony" target
957    add_custom_target(${name})
958  elseif( EXCLUDE_FROM_ALL )
959    set_target_properties( ${name} PROPERTIES EXCLUDE_FROM_ALL ON)
960  elseif(ARG_BUILDTREE_ONLY)
961    set_property(GLOBAL APPEND PROPERTY LLVM_EXPORTS_BUILDTREE_ONLY ${name})
962  else()
963    if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY OR ARG_INSTALL_WITH_TOOLCHAIN)
964      if(in_llvm_libs)
965        set(umbrella UMBRELLA llvm-libraries)
966      else()
967        set(umbrella)
968      endif()
969
970      if(ARG_NO_EXPORT)
971        set(export_to_llvmexports)
972      else()
973        get_target_export_arg(${name} LLVM export_to_llvmexports ${umbrella})
974      endif()
975      install(TARGETS ${name}
976              ${export_to_llvmexports}
977              LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX} COMPONENT ${name}
978              ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX} COMPONENT ${name}
979              RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT ${name})
980
981      if (NOT LLVM_ENABLE_IDE)
982        add_llvm_install_targets(install-${name}
983                                 DEPENDS ${name}
984                                 COMPONENT ${name})
985      endif()
986    endif()
987    if(NOT ARG_NO_EXPORT)
988      set_property(GLOBAL APPEND PROPERTY LLVM_EXPORTS ${name})
989    endif()
990  endif()
991
992  get_subproject_title(subproject_title)
993  if (ARG_MODULE)
994    set_target_properties(${name} PROPERTIES FOLDER "${subproject_title}/Loadable Modules")
995  else()
996    set_target_properties(${name} PROPERTIES FOLDER "${subproject_title}/Libraries")
997  endif()
998endmacro(add_llvm_library name)
999
1000macro(generate_llvm_objects name)
1001  cmake_parse_arguments(ARG "GENERATE_DRIVER" "" "DEPENDS" ${ARGN})
1002
1003  llvm_process_sources( ALL_FILES ${ARG_UNPARSED_ARGUMENTS} )
1004
1005  list(APPEND LLVM_COMMON_DEPENDS ${ARG_DEPENDS})
1006
1007  # Generate objlib
1008  if(LLVM_ENABLE_OBJLIB OR (ARG_GENERATE_DRIVER AND LLVM_TOOL_LLVM_DRIVER_BUILD))
1009    # Generate an obj library for both targets.
1010    set(obj_name "obj.${name}")
1011    add_library(${obj_name} OBJECT EXCLUDE_FROM_ALL
1012      ${ALL_FILES}
1013      )
1014    llvm_update_compile_flags(${obj_name})
1015    set(ALL_FILES "$<TARGET_OBJECTS:${obj_name}>")
1016    if(ARG_DEPENDS)
1017      add_dependencies(${obj_name} ${ARG_DEPENDS})
1018    endif()
1019
1020    get_subproject_title(subproject_title)
1021    set_target_properties(${obj_name} PROPERTIES FOLDER "${subproject_title}/Object Libraries")
1022  endif()
1023
1024  if (ARG_GENERATE_DRIVER)
1025    string(REPLACE "-" "_" TOOL_NAME ${name})
1026    foreach(path ${CMAKE_MODULE_PATH})
1027      if(EXISTS ${path}/llvm-driver-template.cpp.in)
1028        configure_file(
1029          ${path}/llvm-driver-template.cpp.in
1030          ${CMAKE_CURRENT_BINARY_DIR}/${name}-driver.cpp)
1031        break()
1032      endif()
1033    endforeach()
1034
1035    list(APPEND ALL_FILES ${CMAKE_CURRENT_BINARY_DIR}/${name}-driver.cpp)
1036
1037    if (LLVM_TOOL_LLVM_DRIVER_BUILD
1038        AND (NOT LLVM_DISTRIBUTION_COMPONENTS OR ${name} IN_LIST LLVM_DISTRIBUTION_COMPONENTS)
1039       )
1040      set_property(GLOBAL APPEND PROPERTY LLVM_DRIVER_COMPONENTS ${LLVM_LINK_COMPONENTS})
1041      set_property(GLOBAL APPEND PROPERTY LLVM_DRIVER_DEPS ${ARG_DEPENDS} ${LLVM_COMMON_DEPENDS})
1042      set_property(GLOBAL APPEND PROPERTY LLVM_DRIVER_OBJLIBS "${obj_name}")
1043
1044      set_property(GLOBAL APPEND PROPERTY LLVM_DRIVER_TOOLS ${name})
1045      set_property(GLOBAL APPEND PROPERTY LLVM_DRIVER_TOOL_ALIASES_${name} ${name})
1046      target_link_libraries(${obj_name} ${LLVM_PTHREAD_LIB})
1047      llvm_config(${obj_name} ${USE_SHARED} ${LLVM_LINK_COMPONENTS} )
1048    endif()
1049  endif()
1050endmacro()
1051
1052macro(add_llvm_executable name)
1053  cmake_parse_arguments(ARG
1054    "DISABLE_LLVM_LINK_LLVM_DYLIB;IGNORE_EXTERNALIZE_DEBUGINFO;NO_INSTALL_RPATH;SUPPORT_PLUGINS;EXPORT_SYMBOLS"
1055    "ENTITLEMENTS;BUNDLE_PATH"
1056    ""
1057    ${ARGN})
1058  generate_llvm_objects(${name} ${ARG_UNPARSED_ARGUMENTS})
1059  add_windows_version_resource_file(ALL_FILES ${ALL_FILES})
1060
1061  if(XCODE)
1062    # Note: the dummy.cpp source file provides no definitions. However,
1063    # it forces Xcode to properly link the static library.
1064    list(APPEND ALL_FILES "${LLVM_MAIN_SRC_DIR}/cmake/dummy.cpp")
1065  endif()
1066
1067  if( EXCLUDE_FROM_ALL )
1068    add_executable(${name} EXCLUDE_FROM_ALL ${ALL_FILES})
1069  else()
1070    add_executable(${name} ${ALL_FILES})
1071  endif()
1072  get_subproject_title(subproject_title)
1073  set_target_properties(${name} PROPERTIES FOLDER "${subproject_title}/Executables")
1074
1075  setup_dependency_debugging(${name} ${LLVM_COMMON_DEPENDS})
1076
1077  if(NOT ARG_NO_INSTALL_RPATH)
1078    llvm_setup_rpath(${name})
1079  elseif(NOT "${LLVM_LOCAL_RPATH}" STREQUAL "")
1080    # Enable BUILD_WITH_INSTALL_RPATH unless CMAKE_BUILD_RPATH is set.
1081    if("${CMAKE_BUILD_RPATH}" STREQUAL "")
1082      set_property(TARGET ${name} PROPERTY BUILD_WITH_INSTALL_RPATH ON)
1083    endif()
1084
1085    set_property(TARGET ${name} PROPERTY INSTALL_RPATH "${LLVM_LOCAL_RPATH}")
1086  endif()
1087
1088  if(DEFINED windows_resource_file)
1089    set_windows_version_resource_properties(${name} ${windows_resource_file})
1090  endif()
1091
1092  # $<TARGET_OBJECTS> doesn't require compile flags.
1093  if(NOT LLVM_ENABLE_OBJLIB)
1094    llvm_update_compile_flags(${name})
1095  endif()
1096
1097  if (ARG_SUPPORT_PLUGINS AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "AIX")
1098    set(LLVM_NO_DEAD_STRIP On)
1099  endif()
1100
1101  add_link_opts( ${name} )
1102
1103  # Do not add -Dname_EXPORTS to the command-line when building files in this
1104  # target. Doing so is actively harmful for the modules build because it
1105  # creates extra module variants, and not useful because we don't use these
1106  # macros.
1107  set_target_properties( ${name} PROPERTIES DEFINE_SYMBOL "" )
1108
1109  if (LLVM_EXPORTED_SYMBOL_FILE)
1110    add_llvm_symbol_exports( ${name} ${LLVM_EXPORTED_SYMBOL_FILE} )
1111  endif(LLVM_EXPORTED_SYMBOL_FILE)
1112
1113  if (DEFINED LLVM_ENABLE_EXPORTED_SYMBOLS_IN_EXECUTABLES AND
1114      NOT LLVM_ENABLE_EXPORTED_SYMBOLS_IN_EXECUTABLES AND
1115      NOT ARG_EXPORT_SYMBOLS)
1116    if(LLVM_LINKER_SUPPORTS_NO_EXPORTED_SYMBOLS)
1117      set_property(TARGET ${name} APPEND_STRING PROPERTY
1118        LINK_FLAGS " -Wl,-no_exported_symbols")
1119    else()
1120      message(FATAL_ERROR
1121        "LLVM_ENABLE_EXPORTED_SYMBOLS_IN_EXECUTABLES cannot be disabled when linker does not support \"-no_exported_symbols\"")
1122    endif()
1123  endif()
1124
1125  if (LLVM_LINK_LLVM_DYLIB AND NOT ARG_DISABLE_LLVM_LINK_LLVM_DYLIB)
1126    set(USE_SHARED USE_SHARED)
1127  endif()
1128
1129  set(EXCLUDE_FROM_ALL OFF)
1130  set_output_directory(${name} BINARY_DIR ${LLVM_RUNTIME_OUTPUT_INTDIR} LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR})
1131  llvm_config( ${name} ${USE_SHARED} ${LLVM_LINK_COMPONENTS} )
1132  if( LLVM_COMMON_DEPENDS )
1133    add_dependencies( ${name} ${LLVM_COMMON_DEPENDS} )
1134    foreach(objlib ${obj_name})
1135      add_dependencies(${objlib} ${LLVM_COMMON_DEPENDS})
1136    endforeach()
1137  endif( LLVM_COMMON_DEPENDS )
1138
1139  add_custom_linker_flags(${name})
1140
1141  if(NOT ARG_IGNORE_EXTERNALIZE_DEBUGINFO)
1142    llvm_externalize_debuginfo(${name})
1143  endif()
1144  if (LLVM_PTHREAD_LIB)
1145    # libpthreads overrides some standard library symbols, so main
1146    # executable must be linked with it in order to provide consistent
1147    # API for all shared libaries loaded by this executable.
1148    target_link_libraries(${name} PRIVATE ${LLVM_PTHREAD_LIB})
1149  endif()
1150
1151  if(HAVE_LLVM_LIBC)
1152    target_link_libraries(${name} PRIVATE llvmlibc)
1153  endif()
1154
1155  llvm_codesign(${name} ENTITLEMENTS ${ARG_ENTITLEMENTS} BUNDLE_PATH ${ARG_BUNDLE_PATH})
1156
1157  if (ARG_EXPORT_SYMBOLS)
1158    export_executable_symbols(${name})
1159  endif()
1160
1161  if(ARG_DISABLE_LLVM_LINK_LLVM_DYLIB OR NOT LLVM_LINK_LLVM_DYLIB)
1162    target_compile_definitions(${name} PRIVATE LLVM_BUILD_STATIC)
1163  endif()
1164
1165  if(LLVM_BUILD_LLVM_DYLIB_VIS AND NOT LLVM_DYLIB_EXPORT_INLINES AND
1166     MSVC AND CMAKE_CXX_COMPILER_ID MATCHES Clang)
1167    # This has to match how the libraries the executable is linked to are built or there be linker errors.
1168    target_compile_options(${name} PRIVATE /Zc:dllexportInlines-)
1169  endif()
1170endmacro(add_llvm_executable name)
1171
1172# add_llvm_pass_plugin(name [NO_MODULE] ...)
1173#   Add ${name} as an llvm plugin.
1174#   If option LLVM_${name_upper}_LINK_INTO_TOOLS is set to ON, the plugin is registered statically.
1175#   Otherwise a pluggable shared library is registered.
1176#
1177#   If NO_MODULE is specified, when option LLVM_${name_upper}_LINK_INTO_TOOLS is set to OFF,
1178#   only an object library is built, and no module is built. This is specific to the Polly use case.
1179#
1180#   The SUBPROJECT argument contains the LLVM project the plugin belongs
1181#   to. If set, the plugin will link statically by default it if the
1182#   project was enabled.
1183function(add_llvm_pass_plugin name)
1184  cmake_parse_arguments(ARG
1185    "NO_MODULE" "SUBPROJECT" ""
1186    ${ARGN})
1187
1188  string(TOUPPER ${name} name_upper)
1189
1190  # Enable the plugin by default if it was explicitly enabled by the user.
1191  # Note: If was set to "all", LLVM's CMakeLists.txt replaces it with a
1192  # list of all projects, counting as explicitly enabled.
1193  set(link_into_tools_default OFF)
1194  if (ARG_SUBPROJECT AND LLVM_TOOL_${name_upper}_BUILD)
1195    set(link_into_tools_default ON)
1196  endif()
1197  option(LLVM_${name_upper}_LINK_INTO_TOOLS "Statically link ${name} into tools (if available)" ${link_into_tools_default})
1198
1199  # If we statically link the plugin, don't use llvm dylib because we're going
1200  # to be part of it.
1201  if(LLVM_${name_upper}_LINK_INTO_TOOLS)
1202      list(APPEND ARG_UNPARSED_ARGUMENTS DISABLE_LLVM_LINK_LLVM_DYLIB)
1203  endif()
1204
1205  if(LLVM_${name_upper}_LINK_INTO_TOOLS)
1206    list(REMOVE_ITEM ARG_UNPARSED_ARGUMENTS BUILDTREE_ONLY)
1207    # process_llvm_pass_plugins takes care of the actual linking, just create an
1208    # object library as of now
1209    add_llvm_library(${name} OBJECT ${ARG_UNPARSED_ARGUMENTS})
1210    target_compile_definitions(${name} PRIVATE LLVM_${name_upper}_LINK_INTO_TOOLS)
1211    set_property(TARGET ${name} APPEND PROPERTY COMPILE_DEFINITIONS LLVM_LINK_INTO_TOOLS)
1212    if (TARGET intrinsics_gen)
1213      add_dependencies(obj.${name} intrinsics_gen)
1214    endif()
1215    if (TARGET omp_gen)
1216      add_dependencies(obj.${name} omp_gen)
1217    endif()
1218    if (TARGET acc_gen)
1219      add_dependencies(obj.${name} acc_gen)
1220    endif()
1221    set_property(GLOBAL APPEND PROPERTY LLVM_STATIC_EXTENSIONS ${name})
1222  elseif(NOT ARG_NO_MODULE)
1223    add_llvm_library(${name} MODULE NO_EXPORT ${ARG_UNPARSED_ARGUMENTS})
1224  else()
1225    add_llvm_library(${name} OBJECT NO_EXPORT ${ARG_UNPARSED_ARGUMENTS})
1226  endif()
1227  message(STATUS "Registering ${name} as a pass plugin (static build: ${LLVM_${name_upper}_LINK_INTO_TOOLS})")
1228
1229endfunction(add_llvm_pass_plugin)
1230
1231# process_llvm_pass_plugins([GEN_CONFIG])
1232#
1233# Correctly set lib dependencies between plugins and tools, based on tools
1234# registered with the ENABLE_PLUGINS option.
1235#
1236# if GEN_CONFIG option is set, also generate X Macro file for extension
1237# handling. It provides a HANDLE_EXTENSION(extension_namespace, ExtensionProject)
1238# call for each extension allowing client code to define
1239# HANDLE_EXTENSION to have a specific code be run for each extension.
1240#
1241function(process_llvm_pass_plugins)
1242  cmake_parse_arguments(ARG
1243      "GEN_CONFIG" "" ""
1244    ${ARGN})
1245
1246  if(ARG_GEN_CONFIG)
1247      get_property(LLVM_STATIC_EXTENSIONS GLOBAL PROPERTY LLVM_STATIC_EXTENSIONS)
1248  else()
1249      include(LLVMConfigExtensions)
1250  endif()
1251
1252  # Add static plugins to the Extension component
1253  foreach(llvm_extension ${LLVM_STATIC_EXTENSIONS})
1254      set_property(TARGET LLVMExtensions APPEND PROPERTY LINK_LIBRARIES ${llvm_extension})
1255      set_property(TARGET LLVMExtensions APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${llvm_extension})
1256  endforeach()
1257
1258  # Eventually generate the extension headers, and store config to a cmake file
1259  # for usage in third-party configuration.
1260  if(ARG_GEN_CONFIG)
1261
1262      ## Part 1: Extension header to be included whenever we need extension
1263      #  processing.
1264      if(NOT DEFINED LLVM_INSTALL_PACKAGE_DIR)
1265          message(FATAL_ERROR "LLVM_INSTALL_PACKAGE_DIR must be defined and writable. GEN_CONFIG should only be passe when building LLVM proper.")
1266      endif()
1267      # LLVM_INSTALL_PACKAGE_DIR might be absolute, so don't reuse below.
1268      string(REPLACE "${CMAKE_CFG_INTDIR}" "." llvm_cmake_builddir "${LLVM_LIBRARY_DIR}")
1269      set(llvm_cmake_builddir "${llvm_cmake_builddir}/cmake/llvm")
1270      file(WRITE
1271          "${llvm_cmake_builddir}/LLVMConfigExtensions.cmake"
1272          "set(LLVM_STATIC_EXTENSIONS ${LLVM_STATIC_EXTENSIONS})")
1273      install(FILES
1274          ${llvm_cmake_builddir}/LLVMConfigExtensions.cmake
1275          DESTINATION ${LLVM_INSTALL_PACKAGE_DIR}
1276          COMPONENT cmake-exports)
1277
1278      set(ExtensionDef "${LLVM_BINARY_DIR}/include/llvm/Support/Extension.def")
1279      file(WRITE "${ExtensionDef}.tmp" "//extension handlers\n")
1280      foreach(llvm_extension ${LLVM_STATIC_EXTENSIONS})
1281          file(APPEND "${ExtensionDef}.tmp" "HANDLE_EXTENSION(${llvm_extension})\n")
1282      endforeach()
1283      file(APPEND "${ExtensionDef}.tmp" "#undef HANDLE_EXTENSION\n")
1284
1285      # only replace if there's an actual change
1286      execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
1287          "${ExtensionDef}.tmp"
1288          "${ExtensionDef}")
1289      file(REMOVE "${ExtensionDef}.tmp")
1290
1291      ## Part 2: Extension header that captures each extension dependency, to be
1292      #  used by llvm-config.
1293      set(ExtensionDeps "${LLVM_BINARY_DIR}/tools/llvm-config/ExtensionDependencies.inc")
1294
1295      # Max needed to correctly size the required library array.
1296      set(llvm_plugin_max_deps_length 0)
1297      foreach(llvm_extension ${LLVM_STATIC_EXTENSIONS})
1298        get_property(llvm_plugin_deps TARGET ${llvm_extension} PROPERTY LINK_LIBRARIES)
1299        list(LENGTH llvm_plugin_deps llvm_plugin_deps_length)
1300        if(llvm_plugin_deps_length GREATER llvm_plugin_max_deps_length)
1301            set(llvm_plugin_max_deps_length ${llvm_plugin_deps_length})
1302        endif()
1303      endforeach()
1304
1305      list(LENGTH LLVM_STATIC_EXTENSIONS llvm_static_extension_count)
1306      file(WRITE
1307          "${ExtensionDeps}.tmp"
1308          "#include <array>\n\
1309           struct ExtensionDescriptor {\n\
1310              const char* Name;\n\
1311              const char* RequiredLibraries[1 + 1 + ${llvm_plugin_max_deps_length}];\n\
1312           };\n\
1313           std::array<ExtensionDescriptor, ${llvm_static_extension_count}> AvailableExtensions{\n")
1314
1315      foreach(llvm_extension ${LLVM_STATIC_EXTENSIONS})
1316        get_property(llvm_plugin_deps TARGET ${llvm_extension} PROPERTY LINK_LIBRARIES)
1317
1318        file(APPEND "${ExtensionDeps}.tmp" "ExtensionDescriptor{\"${llvm_extension}\", {")
1319        foreach(llvm_plugin_dep ${llvm_plugin_deps})
1320            # Turn library dependency back to component name, if possible.
1321            # That way llvm-config can avoid redundant dependencies.
1322            STRING(REGEX REPLACE "^-l" ""  plugin_dep_name ${llvm_plugin_dep})
1323            STRING(REGEX MATCH "^LLVM" is_llvm_library ${plugin_dep_name})
1324            if(is_llvm_library)
1325                STRING(REGEX REPLACE "^LLVM" ""  plugin_dep_name ${plugin_dep_name})
1326                STRING(TOLOWER ${plugin_dep_name} plugin_dep_name)
1327            endif()
1328            file(APPEND "${ExtensionDeps}.tmp" "\"${plugin_dep_name}\", ")
1329        endforeach()
1330
1331        # Self + mandatory trailing null, because the number of RequiredLibraries differs between extensions.
1332        file(APPEND "${ExtensionDeps}.tmp" \"${llvm_extension}\", "nullptr}},\n")
1333      endforeach()
1334      file(APPEND "${ExtensionDeps}.tmp" "};\n")
1335
1336      # only replace if there's an actual change
1337      execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
1338          "${ExtensionDeps}.tmp"
1339          "${ExtensionDeps}")
1340      file(REMOVE "${ExtensionDeps}.tmp")
1341  endif()
1342endfunction()
1343
1344function(export_executable_symbols target)
1345  if (LLVM_EXPORTED_SYMBOL_FILE)
1346    # The symbol file should contain the symbols we want the executable to
1347    # export
1348    set_target_properties(${target} PROPERTIES ENABLE_EXPORTS 1)
1349  elseif (LLVM_EXPORT_SYMBOLS_FOR_PLUGINS)
1350    # Extract the symbols to export from the static libraries that the
1351    # executable links against.
1352    set_target_properties(${target} PROPERTIES ENABLE_EXPORTS 1)
1353    set(exported_symbol_file ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${target}.symbols)
1354    # We need to consider not just the direct link dependencies, but also the
1355    # transitive link dependencies. Do this by starting with the set of direct
1356    # dependencies, then the dependencies of those dependencies, and so on.
1357    get_target_property(new_libs ${target} LINK_LIBRARIES)
1358    set(link_libs ${new_libs})
1359    while(NOT "${new_libs}" STREQUAL "")
1360      foreach(lib ${new_libs})
1361        if(TARGET ${lib})
1362          get_target_property(lib_type ${lib} TYPE)
1363          if("${lib_type}" STREQUAL "STATIC_LIBRARY")
1364            list(APPEND static_libs ${lib})
1365          else()
1366            list(APPEND other_libs ${lib})
1367          endif()
1368          get_target_property(transitive_libs ${lib} INTERFACE_LINK_LIBRARIES)
1369          foreach(transitive_lib ${transitive_libs})
1370            if(TARGET ${transitive_lib} AND NOT ${transitive_lib} IN_LIST link_libs)
1371              list(APPEND newer_libs ${transitive_lib})
1372              list(APPEND link_libs ${transitive_lib})
1373            endif()
1374          endforeach(transitive_lib)
1375        endif()
1376      endforeach(lib)
1377      set(new_libs ${newer_libs})
1378      set(newer_libs "")
1379    endwhile()
1380    list(REMOVE_DUPLICATES static_libs)
1381    if (MSVC)
1382      set(mangling microsoft)
1383    else()
1384      set(mangling itanium)
1385    endif()
1386    get_host_tool_path(llvm-nm LLVM_NM llvm_nm_exe llvm_nm_target)
1387    get_host_tool_path(llvm-readobj LLVM_READOBJ llvm_readobj_exe llvm_readobj_target)
1388    add_custom_command(OUTPUT ${exported_symbol_file}
1389                       COMMAND "${Python3_EXECUTABLE}"
1390                         ${LLVM_MAIN_SRC_DIR}/utils/extract_symbols.py
1391                         --mangling=${mangling} ${static_libs}
1392                         -o ${exported_symbol_file}
1393                         --nm=${llvm_nm_exe}
1394                         --readobj=${llvm_readobj_exe}
1395                       WORKING_DIRECTORY ${LLVM_LIBRARY_OUTPUT_INTDIR}
1396                       DEPENDS ${LLVM_MAIN_SRC_DIR}/utils/extract_symbols.py
1397                         ${static_libs} ${llvm_nm_target} ${llvm_readobj_target}
1398                       VERBATIM
1399                       COMMENT "Generating export list for ${target}")
1400    add_llvm_symbol_exports( ${target} ${exported_symbol_file} )
1401    # If something links against this executable then we want a
1402    # transitive link against only the libraries whose symbols
1403    # we aren't exporting.
1404    set_target_properties(${target} PROPERTIES INTERFACE_LINK_LIBRARIES "${other_libs}")
1405    # The default import library suffix that cmake uses for cygwin/mingw is
1406    # ".dll.a", but for clang.exe that causes a collision with libclang.dll,
1407    # where the import libraries of both get named libclang.dll.a. Use a suffix
1408    # of ".exe.a" to avoid this.
1409    if(CYGWIN OR MINGW)
1410      set_target_properties(${target} PROPERTIES IMPORT_SUFFIX ".exe.a")
1411    endif()
1412  elseif(NOT (WIN32 OR CYGWIN))
1413    # On Windows auto-exporting everything doesn't work because of the limit on
1414    # the size of the exported symbol table, but on other platforms we can do
1415    # it without any trouble.
1416    set_target_properties(${target} PROPERTIES ENABLE_EXPORTS 1)
1417    # CMake doesn't set CMAKE_EXE_EXPORTS_${lang}_FLAG on Solaris, so
1418    # ENABLE_EXPORTS has no effect.  While Solaris ld defaults to -rdynamic
1419    # behaviour, GNU ld needs it.
1420    if (APPLE OR ${CMAKE_SYSTEM_NAME} STREQUAL "SunOS")
1421      set_property(TARGET ${target} APPEND_STRING PROPERTY
1422        LINK_FLAGS " -rdynamic")
1423    endif()
1424  endif()
1425endfunction()
1426
1427# Export symbols if LLVM plugins are enabled.
1428function(export_executable_symbols_for_plugins target)
1429  if(LLVM_ENABLE_PLUGINS OR LLVM_EXPORT_SYMBOLS_FOR_PLUGINS)
1430    export_executable_symbols(${target})
1431  endif()
1432endfunction()
1433
1434if(NOT LLVM_TOOLCHAIN_TOOLS)
1435  set (LLVM_TOOLCHAIN_TOOLS
1436    llvm-ar
1437    llvm-cov
1438    llvm-cxxfilt
1439    llvm-dlltool
1440    llvm-dwp
1441    llvm-ranlib
1442    llvm-lib
1443    llvm-mca
1444    llvm-ml
1445    llvm-nm
1446    llvm-objcopy
1447    llvm-objdump
1448    llvm-pdbutil
1449    llvm-rc
1450    llvm-readobj
1451    llvm-size
1452    llvm-strings
1453    llvm-strip
1454    llvm-profdata
1455    llvm-profgen
1456    llvm-symbolizer
1457    # symlink version of some of above tools that are enabled by
1458    # LLVM_INSTALL_BINUTILS_SYMLINKS.
1459    addr2line
1460    ar
1461    c++filt
1462    ranlib
1463    nm
1464    objcopy
1465    objdump
1466    readelf
1467    size
1468    strings
1469    strip
1470    )
1471  # Build llvm-mt if libxml2 is enabled. Can be used by runtimes.
1472  if (LLVM_ENABLE_LIBXML2)
1473    list(APPEND LLVM_TOOLCHAIN_TOOLS llvm-mt)
1474  endif()
1475  if (LLVM_TOOL_LLVM_DRIVER_BUILD)
1476    list(APPEND LLVM_TOOLCHAIN_TOOLS llvm-driver)
1477  endif()
1478endif()
1479
1480macro(llvm_add_tool project name)
1481  cmake_parse_arguments(ARG "DEPENDS;GENERATE_DRIVER" "" "" ${ARGN})
1482  if( NOT LLVM_BUILD_TOOLS )
1483    set(EXCLUDE_FROM_ALL ON)
1484  endif()
1485  if(ARG_GENERATE_DRIVER
1486     AND LLVM_TOOL_LLVM_DRIVER_BUILD
1487     AND (NOT LLVM_DISTRIBUTION_COMPONENTS OR ${name} IN_LIST LLVM_DISTRIBUTION_COMPONENTS)
1488    )
1489    generate_llvm_objects(${name} ${ARGN})
1490    add_custom_target(${name} DEPENDS llvm-driver)
1491  else()
1492    add_llvm_executable(${name} ${ARGN})
1493
1494    if ( ${name} IN_LIST LLVM_TOOLCHAIN_TOOLS OR NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
1495      if( LLVM_BUILD_TOOLS )
1496        get_target_export_arg(${name} ${project} export_to_llvmexports)
1497        install(TARGETS ${name}
1498                ${export_to_llvmexports}
1499                RUNTIME DESTINATION ${${project}_TOOLS_INSTALL_DIR}
1500                COMPONENT ${name})
1501
1502        if (NOT LLVM_ENABLE_IDE)
1503          add_llvm_install_targets(install-${name}
1504                                  DEPENDS ${name}
1505                                  COMPONENT ${name})
1506        endif()
1507      endif()
1508    endif()
1509    if( LLVM_BUILD_TOOLS )
1510      string(TOUPPER "${project}" project_upper)
1511      set_property(GLOBAL APPEND PROPERTY ${project_upper}_EXPORTS ${name})
1512    endif()
1513  endif()
1514  get_subproject_title(subproject_title)
1515  set_target_properties(${name} PROPERTIES FOLDER "${subproject_title}/Tools")
1516  set_target_properties(${name} PROPERTIES XCODE_GENERATE_SCHEME ON)
1517endmacro(llvm_add_tool project name)
1518
1519macro(add_llvm_tool name)
1520  llvm_add_tool(LLVM ${ARGV})
1521endmacro()
1522
1523
1524macro(add_llvm_example name)
1525  if( NOT LLVM_BUILD_EXAMPLES )
1526    set(EXCLUDE_FROM_ALL ON)
1527  endif()
1528  add_llvm_executable(${name} EXPORT_SYMBOLS ${ARGN})
1529  if( LLVM_BUILD_EXAMPLES )
1530    install(TARGETS ${name} RUNTIME DESTINATION "${LLVM_EXAMPLES_INSTALL_DIR}")
1531  endif()
1532  get_subproject_title(subproject_title)
1533  set_target_properties(${name} PROPERTIES FOLDER "${subproject_title}/Examples")
1534endmacro(add_llvm_example name)
1535
1536macro(add_llvm_example_library name)
1537  if( NOT LLVM_BUILD_EXAMPLES )
1538    set(EXCLUDE_FROM_ALL ON)
1539    add_llvm_library(${name} BUILDTREE_ONLY ${ARGN})
1540  else()
1541    add_llvm_library(${name} ${ARGN})
1542  endif()
1543
1544  get_subproject_title(subproject_title)
1545  set_target_properties(${name} PROPERTIES FOLDER "${subproject_title}/Examples")
1546endmacro(add_llvm_example_library name)
1547
1548# This is a macro that is used to create targets for executables that are needed
1549# for development, but that are not intended to be installed by default.
1550macro(add_llvm_utility name)
1551  if ( NOT LLVM_BUILD_UTILS )
1552    set(EXCLUDE_FROM_ALL ON)
1553  endif()
1554
1555  add_llvm_executable(${name} DISABLE_LLVM_LINK_LLVM_DYLIB ${ARGN})
1556  get_subproject_title(subproject_title)
1557  set_target_properties(${name} PROPERTIES FOLDER "${subproject_title}/Utils")
1558  if ( ${name} IN_LIST LLVM_TOOLCHAIN_UTILITIES OR NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
1559    if (LLVM_INSTALL_UTILS AND LLVM_BUILD_UTILS)
1560      get_target_export_arg(${name} LLVM export_to_llvmexports)
1561      install(TARGETS ${name}
1562              ${export_to_llvmexports}
1563              RUNTIME DESTINATION ${LLVM_UTILS_INSTALL_DIR}
1564              COMPONENT ${name})
1565
1566      if (NOT LLVM_ENABLE_IDE)
1567        add_llvm_install_targets(install-${name}
1568                                 DEPENDS ${name}
1569                                 COMPONENT ${name})
1570      endif()
1571      set_property(GLOBAL APPEND PROPERTY LLVM_EXPORTS ${name})
1572    elseif(LLVM_BUILD_UTILS)
1573      set_property(GLOBAL APPEND PROPERTY LLVM_EXPORTS_BUILDTREE_ONLY ${name})
1574    endif()
1575  endif()
1576endmacro(add_llvm_utility name)
1577
1578macro(add_llvm_fuzzer name)
1579  cmake_parse_arguments(ARG "" "DUMMY_MAIN" "" ${ARGN})
1580  get_subproject_title(subproject_title)
1581  if( LLVM_LIB_FUZZING_ENGINE )
1582    set(LLVM_OPTIONAL_SOURCES ${ARG_DUMMY_MAIN})
1583    add_llvm_executable(${name} ${ARG_UNPARSED_ARGUMENTS})
1584    target_link_libraries(${name} PRIVATE ${LLVM_LIB_FUZZING_ENGINE})
1585    set_target_properties(${name} PROPERTIES FOLDER "${subproject_title}/Fuzzers")
1586  elseif( LLVM_USE_SANITIZE_COVERAGE )
1587    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=fuzzer")
1588    set(LLVM_OPTIONAL_SOURCES ${ARG_DUMMY_MAIN})
1589    add_llvm_executable(${name} ${ARG_UNPARSED_ARGUMENTS})
1590    set_target_properties(${name} PROPERTIES FOLDER "${subproject_title}/Fuzzers")
1591  elseif( ARG_DUMMY_MAIN )
1592    add_llvm_executable(${name} ${ARG_DUMMY_MAIN} ${ARG_UNPARSED_ARGUMENTS})
1593    set_target_properties(${name} PROPERTIES FOLDER "${subproject_title}/Fuzzers")
1594  endif()
1595endmacro()
1596
1597macro(add_llvm_target target_name)
1598  include_directories(BEFORE
1599    ${CMAKE_CURRENT_BINARY_DIR}
1600    ${CMAKE_CURRENT_SOURCE_DIR})
1601  add_llvm_component_library(LLVM${target_name} ${ARGN})
1602  set( CURRENT_LLVM_TARGET LLVM${target_name} )
1603endmacro(add_llvm_target)
1604
1605function(canonicalize_tool_name name output)
1606  string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" nameStrip ${name})
1607  string(REPLACE "-" "_" nameUNDERSCORE ${nameStrip})
1608  string(TOUPPER ${nameUNDERSCORE} nameUPPER)
1609  set(${output} "${nameUPPER}" PARENT_SCOPE)
1610endfunction(canonicalize_tool_name)
1611
1612# Custom add_subdirectory wrapper
1613# Takes in a project name (i.e. LLVM), the subdirectory name, and an optional
1614# path if it differs from the name.
1615function(add_llvm_subdirectory project type name)
1616  set(add_llvm_external_dir "${ARGN}")
1617  if("${add_llvm_external_dir}" STREQUAL "")
1618    set(add_llvm_external_dir ${name})
1619  endif()
1620  canonicalize_tool_name(${name} nameUPPER)
1621  set(canonical_full_name ${project}_${type}_${nameUPPER})
1622  get_property(already_processed GLOBAL PROPERTY ${canonical_full_name}_PROCESSED)
1623  if(already_processed)
1624    return()
1625  endif()
1626  set_property(GLOBAL PROPERTY ${canonical_full_name}_PROCESSED YES)
1627
1628  if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${add_llvm_external_dir}/CMakeLists.txt)
1629    # Treat it as in-tree subproject.
1630    option(${canonical_full_name}_BUILD
1631           "Whether to build ${name} as part of ${project}" On)
1632    mark_as_advanced(${project}_${type}_${name}_BUILD)
1633    if(${canonical_full_name}_BUILD)
1634      add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${add_llvm_external_dir} ${add_llvm_external_dir})
1635    endif()
1636  else()
1637    set(LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR
1638      "${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR}"
1639      CACHE PATH "Path to ${name} source directory")
1640    set(${canonical_full_name}_BUILD_DEFAULT ON)
1641    if(NOT LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR OR NOT EXISTS ${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR})
1642      set(${canonical_full_name}_BUILD_DEFAULT OFF)
1643    endif()
1644    if("${LLVM_EXTERNAL_${nameUPPER}_BUILD}" STREQUAL "OFF")
1645      set(${canonical_full_name}_BUILD_DEFAULT OFF)
1646    endif()
1647    option(${canonical_full_name}_BUILD
1648      "Whether to build ${name} as part of LLVM"
1649      ${${canonical_full_name}_BUILD_DEFAULT})
1650    if (${canonical_full_name}_BUILD)
1651      if(EXISTS ${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR})
1652        add_subdirectory(${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR} ${add_llvm_external_dir})
1653      elseif(NOT "${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR}" STREQUAL "")
1654        message(WARNING "Nonexistent directory for ${name}: ${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR}")
1655      endif()
1656    endif()
1657  endif()
1658endfunction()
1659
1660# Add external project that may want to be built as part of llvm such as Clang,
1661# lld, and Polly. This adds two options. One for the source directory of the
1662# project, which defaults to ${CMAKE_CURRENT_SOURCE_DIR}/${name}. Another to
1663# enable or disable building it with everything else.
1664# Additional parameter can be specified as the name of directory.
1665macro(add_llvm_external_project name)
1666  add_llvm_subdirectory(LLVM TOOL ${name} ${ARGN})
1667endmacro()
1668
1669macro(add_llvm_tool_subdirectory name)
1670  add_llvm_external_project(${name})
1671endmacro(add_llvm_tool_subdirectory)
1672
1673macro(add_custom_linker_flags name)
1674  if (LLVM_${name}_LINKER_FLAGS)
1675    message(DEBUG "Applying ${LLVM_${name}_LINKER_FLAGS} to ${name}")
1676    target_link_options(${name} PRIVATE ${LLVM_${name}_LINKER_FLAGS})
1677  endif()
1678endmacro()
1679
1680function(get_project_name_from_src_var var output)
1681  string(REGEX MATCH "LLVM_EXTERNAL_(.*)_SOURCE_DIR"
1682         MACHED_TOOL "${var}")
1683  if(MACHED_TOOL)
1684    set(${output} ${CMAKE_MATCH_1} PARENT_SCOPE)
1685  else()
1686    set(${output} PARENT_SCOPE)
1687  endif()
1688endfunction()
1689
1690function(create_subdirectory_options project type)
1691  file(GLOB sub-dirs "${CMAKE_CURRENT_SOURCE_DIR}/*")
1692  foreach(dir ${sub-dirs})
1693    if(IS_DIRECTORY "${dir}" AND EXISTS "${dir}/CMakeLists.txt")
1694      canonicalize_tool_name(${dir} name)
1695      option(${project}_${type}_${name}_BUILD
1696           "Whether to build ${name} as part of ${project}" On)
1697      mark_as_advanced(${project}_${type}_${name}_BUILD)
1698    endif()
1699  endforeach()
1700endfunction(create_subdirectory_options)
1701
1702function(create_llvm_tool_options)
1703  create_subdirectory_options(LLVM TOOL)
1704endfunction(create_llvm_tool_options)
1705
1706function(llvm_add_implicit_projects project)
1707  set(list_of_implicit_subdirs "")
1708  file(GLOB sub-dirs "${CMAKE_CURRENT_SOURCE_DIR}/*")
1709  foreach(dir ${sub-dirs})
1710    if(IS_DIRECTORY "${dir}" AND EXISTS "${dir}/CMakeLists.txt")
1711      canonicalize_tool_name(${dir} name)
1712      # I don't like special casing things by order, but the llvm-driver ends up
1713      # linking the object libraries from all the tools that opt-in, so adding
1714      # it separately at the end is probably the simplest case.
1715      if("${name}" STREQUAL "LLVM_DRIVER")
1716        continue()
1717      endif()
1718      if (${project}_TOOL_${name}_BUILD)
1719        get_filename_component(fn "${dir}" NAME)
1720        list(APPEND list_of_implicit_subdirs "${fn}")
1721      endif()
1722    endif()
1723  endforeach()
1724
1725  foreach(external_proj ${list_of_implicit_subdirs})
1726    add_llvm_subdirectory(${project} TOOL "${external_proj}" ${ARGN})
1727  endforeach()
1728endfunction(llvm_add_implicit_projects)
1729
1730function(add_llvm_implicit_projects)
1731  llvm_add_implicit_projects(LLVM)
1732endfunction(add_llvm_implicit_projects)
1733
1734# Generic support for adding a unittest.
1735function(add_unittest test_suite test_name)
1736  if( NOT LLVM_BUILD_TESTS )
1737    set(EXCLUDE_FROM_ALL ON)
1738  endif()
1739
1740  if (SUPPORTS_VARIADIC_MACROS_FLAG)
1741    list(APPEND LLVM_COMPILE_FLAGS "-Wno-variadic-macros")
1742  endif()
1743  # Some parts of gtest rely on this GNU extension, don't warn on it.
1744  if(SUPPORTS_GNU_ZERO_VARIADIC_MACRO_ARGUMENTS_FLAG)
1745    list(APPEND LLVM_COMPILE_FLAGS "-Wno-gnu-zero-variadic-macro-arguments")
1746  endif()
1747
1748  if (NOT DEFINED LLVM_REQUIRES_RTTI)
1749    set(LLVM_REQUIRES_RTTI OFF)
1750  endif()
1751
1752  list(APPEND LLVM_LINK_COMPONENTS Support) # gtest needs it for raw_ostream
1753  add_llvm_executable(${test_name} IGNORE_EXTERNALIZE_DEBUGINFO NO_INSTALL_RPATH ${ARGN})
1754  get_subproject_title(subproject_title)
1755  set_target_properties(${test_name} PROPERTIES FOLDER "${subproject_title}/Tests/Unit")
1756
1757  # The runtime benefits of LTO don't outweight the compile time costs for tests.
1758  if(LLVM_ENABLE_LTO)
1759    if((UNIX OR MINGW) AND LINKER_IS_LLD)
1760      if(LLVM_ENABLE_FATLTO AND NOT APPLE)
1761        # When using FatLTO, just use relocatable linking.
1762        set_property(TARGET ${test_name} APPEND_STRING PROPERTY
1763                      LINK_FLAGS " -Wl,--no-fat-lto-objects")
1764      else()
1765        set_property(TARGET ${test_name} APPEND_STRING PROPERTY
1766                      LINK_FLAGS " -Wl,--lto-O0")
1767      endif()
1768    elseif(LINKER_IS_LLD_LINK)
1769      set_property(TARGET ${test_name} APPEND_STRING PROPERTY
1770                    LINK_FLAGS " /opt:lldlto=0")
1771    elseif(APPLE AND NOT uppercase_LLVM_ENABLE_LTO STREQUAL "THIN")
1772      set_property(TARGET ${target_name} APPEND_STRING PROPERTY
1773                    LINK_FLAGS " -Wl,-mllvm,-O0")
1774    endif()
1775  endif()
1776
1777  target_link_options(${test_name} PRIVATE "${LLVM_UNITTEST_LINK_FLAGS}")
1778
1779  set(outdir ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR})
1780  set_output_directory(${test_name} BINARY_DIR ${outdir} LIBRARY_DIR ${outdir})
1781  # libpthreads overrides some standard library symbols, so main
1782  # executable must be linked with it in order to provide consistent
1783  # API for all shared libaries loaded by this executable.
1784  target_link_libraries(${test_name} PRIVATE llvm_gtest_main llvm_gtest ${LLVM_PTHREAD_LIB})
1785
1786  add_dependencies(${test_suite} ${test_name})
1787endfunction()
1788
1789# Use for test binaries that call llvm::getInputFileDirectory(). Use of this
1790# is discouraged.
1791function(add_unittest_with_input_files test_suite test_name)
1792  set(LLVM_UNITTEST_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
1793  configure_file(
1794    ${LLVM_MAIN_SRC_DIR}/unittests/unittest.cfg.in
1795    ${CMAKE_CURRENT_BINARY_DIR}/llvm.srcdir.txt)
1796
1797  add_unittest(${test_suite} ${test_name} ${ARGN})
1798endfunction()
1799
1800# Generic support for adding a benchmark.
1801function(add_benchmark benchmark_name)
1802  if( NOT LLVM_BUILD_BENCHMARKS )
1803    set(EXCLUDE_FROM_ALL ON)
1804  endif()
1805
1806  add_llvm_executable(${benchmark_name} IGNORE_EXTERNALIZE_DEBUGINFO NO_INSTALL_RPATH ${ARGN})
1807  set(outdir ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR})
1808  set_output_directory(${benchmark_name} BINARY_DIR ${outdir} LIBRARY_DIR ${outdir})
1809  get_subproject_title(subproject_title)
1810  set_property(TARGET ${benchmark_name} PROPERTY FOLDER "${subproject_title}/Benchmarks")
1811  target_link_libraries(${benchmark_name} PRIVATE benchmark)
1812endfunction()
1813
1814# This function canonicalize the CMake variables passed by names
1815# from CMake boolean to 0/1 suitable for passing into Python or C++,
1816# in place.
1817function(llvm_canonicalize_cmake_booleans)
1818  foreach(var ${ARGN})
1819    if(${var})
1820      set(${var} 1 PARENT_SCOPE)
1821    else()
1822      set(${var} 0 PARENT_SCOPE)
1823    endif()
1824  endforeach()
1825endfunction(llvm_canonicalize_cmake_booleans)
1826
1827macro(set_llvm_build_mode)
1828  # Configuration-time: See Unit/lit.site.cfg.in
1829  if (CMAKE_CFG_INTDIR STREQUAL ".")
1830    set(LLVM_BUILD_MODE ".")
1831  else ()
1832    set(LLVM_BUILD_MODE "%(build_mode)s")
1833  endif ()
1834endmacro()
1835
1836# Takes a list of path names in pathlist and a base directory, and returns
1837# a list of paths relative to the base directory in out_pathlist.
1838# Paths that are on a different drive than the basedir (on Windows) or that
1839# contain symlinks are returned absolute.
1840# Use with LLVM_LIT_PATH_FUNCTION below.
1841function(make_paths_relative out_pathlist basedir pathlist)
1842  # Passing ARG_PATH_VALUES as-is to execute_process() makes cmake strip
1843  # empty list entries. So escape the ;s in the list and do the splitting
1844  # ourselves. cmake has no relpath function, so use Python for that.
1845  string(REPLACE ";" "\\;" pathlist_escaped "${pathlist}")
1846  execute_process(COMMAND "${Python3_EXECUTABLE}" "-c" "\n
1847import os, sys\n
1848base = sys.argv[1]
1849def haslink(p):\n
1850    if not p or p == os.path.dirname(p): return False\n
1851    return os.path.islink(p) or haslink(os.path.dirname(p))\n
1852def relpath(p):\n
1853    if not p: return ''\n
1854    if os.path.splitdrive(p)[0] != os.path.splitdrive(base)[0]: return p\n
1855    if haslink(p) or haslink(base): return p\n
1856    return os.path.relpath(p, base)\n
1857if len(sys.argv) < 3: sys.exit(0)\n
1858sys.stdout.write(';'.join(relpath(p) for p in sys.argv[2].split(';')))"
1859    ${basedir}
1860    ${pathlist_escaped}
1861    OUTPUT_VARIABLE pathlist_relative
1862    ERROR_VARIABLE error
1863    RESULT_VARIABLE result)
1864  if (NOT result EQUAL 0)
1865    message(FATAL_ERROR "make_paths_relative() failed due to error '${result}', with stderr\n${error}")
1866  endif()
1867  set(${out_pathlist} "${pathlist_relative}" PARENT_SCOPE)
1868endfunction()
1869
1870# Converts a file that's relative to the current python file to an absolute
1871# path. Since this uses __file__, it has to be emitted into python files that
1872# use it and can't be in a lit module. Use with make_paths_relative().
1873string(CONCAT LLVM_LIT_PATH_FUNCTION
1874  "# Allow generated file to be relocatable.\n"
1875  "import os\n"
1876  "import platform\n"
1877  "def path(p):\n"
1878  "    if not p: return ''\n"
1879  "    # Follows lit.util.abs_path_preserve_drive, which cannot be imported here.\n"
1880  "    if platform.system() == 'Windows':\n"
1881  "        return os.path.abspath(os.path.join(os.path.dirname(__file__), p))\n"
1882  "    else:\n"
1883  "        return os.path.realpath(os.path.join(os.path.dirname(__file__), p))\n"
1884  )
1885
1886# This function provides an automatic way to 'configure'-like generate a file
1887# based on a set of common and custom variables, specifically targeting the
1888# variables needed for the 'lit.site.cfg' files. This function bundles the
1889# common variables that any Lit instance is likely to need, and custom
1890# variables can be passed in.
1891# The keyword PATHS is followed by a list of cmake variable names that are
1892# mentioned as `path("@varname@")` in the lit.cfg.py.in file. Variables in that
1893# list are treated as paths that are relative to the directory the generated
1894# lit.cfg.py file is in, and the `path()` function converts the relative
1895# path back to absolute form. This makes it possible to move a build directory
1896# containing lit.cfg.py files from one machine to another.
1897function(configure_lit_site_cfg site_in site_out)
1898  cmake_parse_arguments(ARG "" "" "MAIN_CONFIG;PATHS" ${ARGN})
1899
1900  if ("${ARG_MAIN_CONFIG}" STREQUAL "")
1901    get_filename_component(INPUT_DIR ${site_in} DIRECTORY)
1902    set(ARG_MAIN_CONFIG "${INPUT_DIR}/lit.cfg")
1903  endif()
1904
1905  foreach(c ${LLVM_TARGETS_TO_BUILD})
1906    set(TARGETS_BUILT "${TARGETS_BUILT} ${c}")
1907  endforeach(c)
1908  set(TARGETS_TO_BUILD ${TARGETS_BUILT})
1909
1910  set(SHLIBEXT "${LTDL_SHLIB_EXT}")
1911
1912  set_llvm_build_mode()
1913
1914  # For standalone builds of subprojects, these might not be the build tree but
1915  # a provided binary tree.
1916  set(LLVM_SOURCE_DIR ${LLVM_MAIN_SRC_DIR})
1917  set(LLVM_BINARY_DIR ${LLVM_BINARY_DIR})
1918  string(REPLACE "${CMAKE_CFG_INTDIR}" "${LLVM_BUILD_MODE}" LLVM_TOOLS_DIR "${LLVM_TOOLS_BINARY_DIR}")
1919  string(REPLACE "${CMAKE_CFG_INTDIR}" "${LLVM_BUILD_MODE}" LLVM_LIBS_DIR  "${LLVM_LIBRARY_DIR}")
1920  # Like LLVM_{TOOLS,LIBS}_DIR, but pointing at the build tree.
1921  string(REPLACE "${CMAKE_CFG_INTDIR}" "${LLVM_BUILD_MODE}" CURRENT_TOOLS_DIR "${LLVM_RUNTIME_OUTPUT_INTDIR}")
1922  string(REPLACE "${CMAKE_CFG_INTDIR}" "${LLVM_BUILD_MODE}" CURRENT_LIBS_DIR  "${LLVM_LIBRARY_OUTPUT_INTDIR}")
1923  string(REPLACE "${CMAKE_CFG_INTDIR}" "${LLVM_BUILD_MODE}" SHLIBDIR "${LLVM_SHLIB_OUTPUT_INTDIR}")
1924
1925  # FIXME: "ENABLE_SHARED" doesn't make sense, since it is used just for
1926  # plugins. We may rename it.
1927  if(LLVM_ENABLE_PLUGINS)
1928    set(ENABLE_SHARED "1")
1929  else()
1930    set(ENABLE_SHARED "0")
1931  endif()
1932
1933  if(LLVM_ENABLE_ASSERTIONS)
1934    set(ENABLE_ASSERTIONS "1")
1935  else()
1936    set(ENABLE_ASSERTIONS "0")
1937  endif()
1938
1939  set(HOST_OS ${CMAKE_SYSTEM_NAME})
1940  set(HOST_ARCH ${CMAKE_SYSTEM_PROCESSOR})
1941
1942  set(HOST_CC "${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1}")
1943  set(HOST_CXX "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1}")
1944  set(HOST_LDFLAGS "${CMAKE_EXE_LINKER_FLAGS}")
1945
1946  string(CONCAT LIT_SITE_CFG_IN_HEADER
1947    "# Autogenerated from ${site_in}\n# Do not edit!\n\n"
1948    "${LLVM_LIT_PATH_FUNCTION}"
1949    )
1950
1951  # Override config_target_triple (and the env)
1952  if(LLVM_TARGET_TRIPLE_ENV)
1953    # This is expanded into the heading.
1954    string(CONCAT LIT_SITE_CFG_IN_HEADER "${LIT_SITE_CFG_IN_HEADER}"
1955      "import os\n"
1956      "target_env = \"${LLVM_TARGET_TRIPLE_ENV}\"\n"
1957      "config.target_triple = config.environment[target_env] = os.environ.get(target_env, \"${LLVM_TARGET_TRIPLE}\")\n"
1958      )
1959
1960    # This is expanded to; config.target_triple = ""+config.target_triple+""
1961    set(LLVM_TARGET_TRIPLE "\"+config.target_triple+\"")
1962  endif()
1963
1964  if (ARG_PATHS)
1965    # Walk ARG_PATHS and collect the current value of the variables in there.
1966    # list(APPEND) ignores empty elements exactly if the list is empty,
1967    # so start the list with a dummy element and drop it, to make sure that
1968    # even empty values make it into the values list.
1969    set(ARG_PATH_VALUES "dummy")
1970    foreach(path ${ARG_PATHS})
1971      list(APPEND ARG_PATH_VALUES "${${path}}")
1972    endforeach()
1973    list(REMOVE_AT ARG_PATH_VALUES 0)
1974
1975    get_filename_component(OUTPUT_DIR ${site_out} DIRECTORY)
1976    make_paths_relative(
1977        ARG_PATH_VALUES_RELATIVE "${OUTPUT_DIR}" "${ARG_PATH_VALUES}")
1978
1979    list(LENGTH ARG_PATHS len_paths)
1980    list(LENGTH ARG_PATH_VALUES len_path_values)
1981    list(LENGTH ARG_PATH_VALUES_RELATIVE len_path_value_rels)
1982    if ((NOT ${len_paths} EQUAL ${len_path_values}) OR
1983        (NOT ${len_paths} EQUAL ${len_path_value_rels}))
1984      message(SEND_ERROR "PATHS lengths got confused")
1985    endif()
1986
1987    # Transform variables mentioned in ARG_PATHS to relative paths for
1988    # the configure_file() call. Variables are copied to subscopeds by cmake,
1989    # so this only modifies the local copy of the variables.
1990    math(EXPR arg_path_limit "${len_paths} - 1")
1991    foreach(i RANGE ${arg_path_limit})
1992      list(GET ARG_PATHS ${i} val1)
1993      list(GET ARG_PATH_VALUES_RELATIVE ${i} val2)
1994      set(${val1} ${val2})
1995    endforeach()
1996  endif()
1997
1998  configure_file(${site_in} ${site_out} @ONLY)
1999
2000  if (EXISTS "${ARG_MAIN_CONFIG}")
2001    # Remember main config / generated site config for llvm-lit.in.
2002    get_property(LLVM_LIT_CONFIG_FILES GLOBAL PROPERTY LLVM_LIT_CONFIG_FILES)
2003    list(APPEND LLVM_LIT_CONFIG_FILES "${ARG_MAIN_CONFIG}" "${site_out}")
2004    set_property(GLOBAL PROPERTY LLVM_LIT_CONFIG_FILES ${LLVM_LIT_CONFIG_FILES})
2005  endif()
2006endfunction()
2007
2008function(dump_all_cmake_variables)
2009  get_cmake_property(_variableNames VARIABLES)
2010  foreach (_variableName ${_variableNames})
2011    message(STATUS "${_variableName}=${${_variableName}}")
2012  endforeach()
2013endfunction()
2014
2015function(get_llvm_lit_path base_dir file_name)
2016  cmake_parse_arguments(ARG "ALLOW_EXTERNAL" "" "" ${ARGN})
2017
2018  if (ARG_ALLOW_EXTERNAL)
2019    set (LLVM_EXTERNAL_LIT "" CACHE STRING "Command used to spawn lit")
2020    if ("${LLVM_EXTERNAL_LIT}" STREQUAL "")
2021      set(LLVM_EXTERNAL_LIT "${LLVM_DEFAULT_EXTERNAL_LIT}")
2022    endif()
2023
2024    if (NOT "${LLVM_EXTERNAL_LIT}" STREQUAL "")
2025      if (EXISTS ${LLVM_EXTERNAL_LIT})
2026        get_filename_component(LIT_FILE_NAME ${LLVM_EXTERNAL_LIT} NAME)
2027        get_filename_component(LIT_BASE_DIR ${LLVM_EXTERNAL_LIT} DIRECTORY)
2028        set(${file_name} ${LIT_FILE_NAME} PARENT_SCOPE)
2029        set(${base_dir} ${LIT_BASE_DIR} PARENT_SCOPE)
2030        return()
2031      elseif (NOT DEFINED CACHE{LLVM_EXTERNAL_LIT_MISSING_WARNED_ONCE})
2032        message(WARNING "LLVM_EXTERNAL_LIT set to ${LLVM_EXTERNAL_LIT}, but the path does not exist.")
2033        set(LLVM_EXTERNAL_LIT_MISSING_WARNED_ONCE YES CACHE INTERNAL "")
2034      endif()
2035    endif()
2036  endif()
2037
2038  set(lit_file_name "llvm-lit")
2039  if (CMAKE_HOST_WIN32 AND NOT CYGWIN)
2040    # llvm-lit needs suffix.py for multiprocess to find a main module.
2041    set(lit_file_name "${lit_file_name}.py")
2042  endif ()
2043  set(${file_name} ${lit_file_name} PARENT_SCOPE)
2044
2045  get_property(LLVM_LIT_BASE_DIR GLOBAL PROPERTY LLVM_LIT_BASE_DIR)
2046  if (NOT "${LLVM_LIT_BASE_DIR}" STREQUAL "")
2047    set(${base_dir} ${LLVM_LIT_BASE_DIR} PARENT_SCOPE)
2048  endif()
2049
2050  # Allow individual projects to provide an override
2051  if (NOT "${LLVM_LIT_OUTPUT_DIR}" STREQUAL "")
2052    set(LLVM_LIT_BASE_DIR ${LLVM_LIT_OUTPUT_DIR})
2053  elseif(NOT "${LLVM_RUNTIME_OUTPUT_INTDIR}" STREQUAL "")
2054    set(LLVM_LIT_BASE_DIR ${LLVM_RUNTIME_OUTPUT_INTDIR})
2055  else()
2056    set(LLVM_LIT_BASE_DIR "")
2057  endif()
2058
2059  # Cache this so we don't have to do it again and have subsequent calls
2060  # potentially disagree on the value.
2061  set_property(GLOBAL PROPERTY LLVM_LIT_BASE_DIR ${LLVM_LIT_BASE_DIR})
2062  set(${base_dir} ${LLVM_LIT_BASE_DIR} PARENT_SCOPE)
2063endfunction()
2064
2065# A raw function to create a lit target. This is used to implement the testuite
2066# management functions.
2067function(add_lit_target target comment)
2068  cmake_parse_arguments(ARG "" "" "PARAMS;DEPENDS;ARGS" ${ARGN})
2069  set(LIT_ARGS "${ARG_ARGS} ${LLVM_LIT_ARGS}")
2070  separate_arguments(LIT_ARGS)
2071  if (NOT CMAKE_CFG_INTDIR STREQUAL ".")
2072    list(APPEND LIT_ARGS --param build_mode=${CMAKE_CFG_INTDIR})
2073  endif ()
2074
2075  # Get the path to the lit to *run* tests with.  This can be overriden by
2076  # the user by specifying -DLLVM_EXTERNAL_LIT=<path-to-lit.py>
2077  get_llvm_lit_path(
2078    lit_base_dir
2079    lit_file_name
2080    ALLOW_EXTERNAL
2081    )
2082
2083  set(LIT_COMMAND "${Python3_EXECUTABLE};${lit_base_dir}/${lit_file_name}")
2084  list(APPEND LIT_COMMAND ${LIT_ARGS})
2085  foreach(param ${ARG_PARAMS})
2086    list(APPEND LIT_COMMAND --param ${param})
2087  endforeach()
2088  if (ARG_UNPARSED_ARGUMENTS)
2089    add_custom_target(${target}
2090      COMMAND ${LIT_COMMAND} ${ARG_UNPARSED_ARGUMENTS}
2091      COMMENT "${comment}"
2092      USES_TERMINAL
2093      )
2094  else()
2095    add_custom_target(${target}
2096      COMMAND ${CMAKE_COMMAND} -E echo "${target} does nothing, no tools built.")
2097    message(STATUS "${target} does nothing.")
2098  endif()
2099  get_subproject_title(subproject_title)
2100  set_target_properties(${target} PROPERTIES FOLDER "${subproject_title}/Tests")
2101
2102  if (ARG_DEPENDS)
2103    add_dependencies(${target} ${ARG_DEPENDS})
2104  endif()
2105
2106  # Tests should be excluded from "Build Solution".
2107  set_target_properties(${target} PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD ON)
2108  set_target_properties(${target} PROPERTIES XCODE_GENERATE_SCHEME ON)
2109endfunction()
2110
2111# Convert a target name like check-clang to a variable name like CLANG.
2112function(umbrella_lit_testsuite_var target outvar)
2113  if (NOT target MATCHES "^check-")
2114    message(FATAL_ERROR "umbrella lit suites must be check-*, not '${target}'")
2115  endif()
2116  string(SUBSTRING "${target}" 6 -1 var)
2117  string(REPLACE "-" "_" var ${var})
2118  string(TOUPPER "${var}" var)
2119  set(${outvar} "${var}" PARENT_SCOPE)
2120endfunction()
2121
2122# Start recording all lit test suites for a combined 'check-foo' target.
2123# The recording continues until umbrella_lit_testsuite_end() creates the target.
2124function(umbrella_lit_testsuite_begin target)
2125  umbrella_lit_testsuite_var(${target} name)
2126  set_property(GLOBAL APPEND PROPERTY LLVM_LIT_UMBRELLAS ${name})
2127endfunction()
2128
2129# Create a combined 'check-foo' target for a set of related test suites.
2130# It runs all suites added since the matching umbrella_lit_testsuite_end() call.
2131# Tests marked EXCLUDE_FROM_CHECK_ALL are not gathered.
2132function(umbrella_lit_testsuite_end target)
2133  umbrella_lit_testsuite_var(${target} name)
2134
2135  get_property(testsuites GLOBAL PROPERTY LLVM_${name}_LIT_TESTSUITES)
2136  get_property(params GLOBAL PROPERTY LLVM_${name}_LIT_PARAMS)
2137  get_property(depends GLOBAL PROPERTY LLVM_${name}_LIT_DEPENDS)
2138  get_property(extra_args GLOBAL PROPERTY LLVM_${name}_LIT_EXTRA_ARGS)
2139  # Additional test targets are not gathered, but may be set externally.
2140  get_property(additional_test_targets
2141               GLOBAL PROPERTY LLVM_${name}_ADDITIONAL_TEST_TARGETS)
2142
2143  string(TOLOWER ${name} name)
2144  add_lit_target(${target}
2145    "Running ${name} regression tests"
2146    ${testsuites}
2147    PARAMS ${params}
2148    DEPENDS ${depends} ${additional_test_targets}
2149    ARGS ${extra_args}
2150    )
2151endfunction()
2152
2153# A function to add a set of lit test suites to be driven through 'check-*' targets.
2154function(add_lit_testsuite target comment)
2155  cmake_parse_arguments(ARG "EXCLUDE_FROM_CHECK_ALL" "" "PARAMS;DEPENDS;ARGS" ${ARGN})
2156
2157  # EXCLUDE_FROM_ALL excludes the test ${target} out of check-all.
2158  if(NOT ARG_EXCLUDE_FROM_CHECK_ALL)
2159    get_property(gather_names GLOBAL PROPERTY LLVM_LIT_UMBRELLAS)
2160    foreach(name ${gather_names})
2161    # Register the testsuites, params and depends for the umbrella check rule.
2162      set_property(GLOBAL APPEND PROPERTY LLVM_${name}_LIT_TESTSUITES ${ARG_UNPARSED_ARGUMENTS})
2163      set_property(GLOBAL APPEND PROPERTY LLVM_${name}_LIT_PARAMS ${ARG_PARAMS})
2164      set_property(GLOBAL APPEND PROPERTY LLVM_${name}_LIT_DEPENDS ${ARG_DEPENDS})
2165      set_property(GLOBAL APPEND PROPERTY LLVM_${name}_LIT_EXTRA_ARGS ${ARG_ARGS})
2166    endforeach()
2167  endif()
2168
2169  # Produce a specific suffixed check rule.
2170  add_lit_target(${target} ${comment}
2171    ${ARG_UNPARSED_ARGUMENTS}
2172    PARAMS ${ARG_PARAMS}
2173    DEPENDS ${ARG_DEPENDS}
2174    ARGS ${ARG_ARGS}
2175    )
2176endfunction()
2177
2178function(add_lit_testsuites project directory)
2179  if (NOT LLVM_ENABLE_IDE)
2180    cmake_parse_arguments(ARG "EXCLUDE_FROM_CHECK_ALL" "FOLDER" "PARAMS;DEPENDS;ARGS" ${ARGN})
2181
2182    if (NOT ARG_FOLDER)
2183      get_subproject_title(subproject_title)
2184      set(ARG_FOLDER "${subproject_title}/Tests/LIT Testsuites")
2185    endif()
2186
2187    # Search recursively for test directories by assuming anything not
2188    # in a directory called Inputs contains tests.
2189    file(GLOB_RECURSE to_process LIST_DIRECTORIES true ${directory}/*)
2190    foreach(lit_suite ${to_process})
2191      if(NOT IS_DIRECTORY ${lit_suite})
2192        continue()
2193      endif()
2194      string(FIND ${lit_suite} Inputs is_inputs)
2195      string(FIND ${lit_suite} Output is_output)
2196      if (NOT (is_inputs EQUAL -1 AND is_output EQUAL -1))
2197        continue()
2198      endif()
2199
2200      # Create a check- target for the directory.
2201      string(REPLACE ${directory} "" name_slash ${lit_suite})
2202      if (name_slash)
2203        string(REPLACE "/" "-" name_slash ${name_slash})
2204        string(REPLACE "\\" "-" name_dashes ${name_slash})
2205        string(TOLOWER "${project}${name_dashes}" name_var)
2206        add_lit_target("check-${name_var}" "Running lit suite ${lit_suite}"
2207          ${lit_suite}
2208          ${EXCLUDE_FROM_CHECK_ALL}
2209          PARAMS ${ARG_PARAMS}
2210          DEPENDS ${ARG_DEPENDS}
2211          ARGS ${ARG_ARGS}
2212        )
2213        set_target_properties(check-${name_var} PROPERTIES FOLDER ${ARG_FOLDER})
2214      endif()
2215    endforeach()
2216  endif()
2217endfunction()
2218
2219function(llvm_install_library_symlink name dest type)
2220  cmake_parse_arguments(ARG "FULL_DEST" "COMPONENT" "" ${ARGN})
2221  foreach(path ${CMAKE_MODULE_PATH})
2222    if(EXISTS ${path}/LLVMInstallSymlink.cmake)
2223      set(INSTALL_SYMLINK ${path}/LLVMInstallSymlink.cmake)
2224      break()
2225    endif()
2226  endforeach()
2227
2228  set(component ${ARG_COMPONENT})
2229  if(NOT component)
2230    set(component ${name})
2231  endif()
2232
2233  set(full_name ${CMAKE_${type}_LIBRARY_PREFIX}${name}${CMAKE_${type}_LIBRARY_SUFFIX})
2234  if (ARG_FULL_DEST)
2235    set(full_dest ${dest})
2236  else()
2237    set(full_dest ${CMAKE_${type}_LIBRARY_PREFIX}${dest}${CMAKE_${type}_LIBRARY_SUFFIX})
2238  endif()
2239
2240  if(LLVM_USE_SYMLINKS)
2241    set(LLVM_LINK_OR_COPY create_symlink)
2242  else()
2243    set(LLVM_LINK_OR_COPY copy)
2244  endif()
2245
2246  set(output_dir lib${LLVM_LIBDIR_SUFFIX})
2247  if(WIN32 AND "${type}" STREQUAL "SHARED")
2248    set(output_dir "${CMAKE_INSTALL_BINDIR}")
2249  endif()
2250
2251  install(SCRIPT ${INSTALL_SYMLINK}
2252          CODE "install_symlink(\"${full_name}\" \"${full_dest}\" \"${output_dir}\" \"${LLVM_LINK_OR_COPY}\")"
2253          COMPONENT ${component})
2254
2255endfunction()
2256
2257function(llvm_install_symlink project name dest)
2258  get_property(LLVM_DRIVER_TOOLS GLOBAL PROPERTY LLVM_DRIVER_TOOLS)
2259  if(LLVM_TOOL_LLVM_DRIVER_BUILD
2260     AND ${dest} IN_LIST LLVM_DRIVER_TOOLS
2261     AND (NOT LLVM_DISTRIBUTION_COMPONENTS OR ${dest} IN_LIST LLVM_DISTRIBUTION_COMPONENTS)
2262    )
2263    return()
2264  endif()
2265  cmake_parse_arguments(ARG "ALWAYS_GENERATE" "COMPONENT" "" ${ARGN})
2266  foreach(path ${CMAKE_MODULE_PATH})
2267    if(EXISTS ${path}/LLVMInstallSymlink.cmake)
2268      set(INSTALL_SYMLINK ${path}/LLVMInstallSymlink.cmake)
2269      break()
2270    endif()
2271  endforeach()
2272
2273  if(ARG_COMPONENT)
2274    set(component ${ARG_COMPONENT})
2275  else()
2276    if(ARG_ALWAYS_GENERATE)
2277      set(component ${dest})
2278    else()
2279      set(component ${name})
2280    endif()
2281  endif()
2282
2283  set(full_name ${name}${CMAKE_EXECUTABLE_SUFFIX})
2284  set(full_dest ${dest}${CMAKE_EXECUTABLE_SUFFIX})
2285  if (${dest} STREQUAL "llvm-driver")
2286    set(full_dest llvm${CMAKE_EXECUTABLE_SUFFIX})
2287  endif()
2288
2289  if(LLVM_USE_SYMLINKS)
2290    set(LLVM_LINK_OR_COPY create_symlink)
2291  else()
2292    set(LLVM_LINK_OR_COPY copy)
2293  endif()
2294
2295  set(output_dir "${${project}_TOOLS_INSTALL_DIR}")
2296
2297  install(SCRIPT ${INSTALL_SYMLINK}
2298          CODE "install_symlink(\"${full_name}\" \"${full_dest}\" \"${output_dir}\" \"${LLVM_LINK_OR_COPY}\")"
2299          COMPONENT ${component})
2300
2301  if (NOT LLVM_ENABLE_IDE AND NOT ARG_ALWAYS_GENERATE)
2302    add_llvm_install_targets(install-${name}
2303                             DEPENDS ${name} ${dest}
2304                             COMPONENT ${component}
2305                             SYMLINK ${dest})
2306  endif()
2307endfunction()
2308
2309function(llvm_add_tool_symlink project link_name target)
2310  cmake_parse_arguments(ARG "ALWAYS_GENERATE" "OUTPUT_DIR" "" ${ARGN})
2311
2312  get_property(LLVM_DRIVER_TOOLS GLOBAL PROPERTY LLVM_DRIVER_TOOLS)
2313
2314  if (${target} IN_LIST LLVM_DRIVER_TOOLS)
2315    set_property(GLOBAL APPEND PROPERTY LLVM_DRIVER_TOOL_ALIASES_${target} ${link_name})
2316  endif()
2317  set(dest_binary "$<TARGET_FILE:${target}>")
2318
2319  # This got a bit gross... For multi-configuration generators the target
2320  # properties return the resolved value of the string, not the build system
2321  # expression. To reconstruct the platform-agnostic path we have to do some
2322  # magic. First we grab one of the types, and a type-specific path. Then from
2323  # the type-specific path we find the last occurrence of the type in the path,
2324  # and replace it with CMAKE_CFG_INTDIR. This allows the build step to be type
2325  # agnostic again.
2326  if(NOT ARG_OUTPUT_DIR)
2327    # If you're not overriding the OUTPUT_DIR, we can make the link relative in
2328    # the same directory.
2329    if(LLVM_USE_SYMLINKS)
2330      set(dest_binary "$<TARGET_FILE_NAME:${target}>")
2331    endif()
2332    if(CMAKE_CONFIGURATION_TYPES)
2333      list(GET CMAKE_CONFIGURATION_TYPES 0 first_type)
2334      string(TOUPPER ${first_type} first_type_upper)
2335      set(first_type_suffix _${first_type_upper})
2336    endif()
2337    get_target_property(target_type ${target} TYPE)
2338    if(${target_type} STREQUAL "STATIC_LIBRARY")
2339      get_target_property(ARG_OUTPUT_DIR ${target} ARCHIVE_OUTPUT_DIRECTORY${first_type_suffix})
2340    elseif(UNIX AND ${target_type} STREQUAL "SHARED_LIBRARY")
2341      get_target_property(ARG_OUTPUT_DIR ${target} LIBRARY_OUTPUT_DIRECTORY${first_type_suffix})
2342    else()
2343      get_target_property(ARG_OUTPUT_DIR ${target} RUNTIME_OUTPUT_DIRECTORY${first_type_suffix})
2344    endif()
2345    if(CMAKE_CONFIGURATION_TYPES)
2346      string(FIND "${ARG_OUTPUT_DIR}" "/${first_type}/" type_start REVERSE)
2347      string(SUBSTRING "${ARG_OUTPUT_DIR}" 0 ${type_start} path_prefix)
2348      string(SUBSTRING "${ARG_OUTPUT_DIR}" ${type_start} -1 path_suffix)
2349      string(REPLACE "/${first_type}/" "/${CMAKE_CFG_INTDIR}/"
2350             path_suffix ${path_suffix})
2351      set(ARG_OUTPUT_DIR ${path_prefix}${path_suffix})
2352    endif()
2353  endif()
2354
2355  if(LLVM_USE_SYMLINKS)
2356    set(LLVM_LINK_OR_COPY create_symlink)
2357  else()
2358    set(LLVM_LINK_OR_COPY copy)
2359  endif()
2360
2361  set(output_path "${ARG_OUTPUT_DIR}/${link_name}${CMAKE_EXECUTABLE_SUFFIX}")
2362
2363  set(target_name ${link_name})
2364  if(TARGET ${link_name})
2365    set(target_name ${link_name}-link)
2366  endif()
2367
2368
2369  if(ARG_ALWAYS_GENERATE)
2370    set_property(DIRECTORY APPEND PROPERTY
2371      ADDITIONAL_MAKE_CLEAN_FILES ${dest_binary})
2372    add_custom_command(TARGET ${target} POST_BUILD
2373      COMMAND ${CMAKE_COMMAND} -E ${LLVM_LINK_OR_COPY} "${dest_binary}" "${output_path}")
2374  else()
2375    add_custom_command(OUTPUT ${output_path}
2376                     COMMAND ${CMAKE_COMMAND} -E ${LLVM_LINK_OR_COPY} "${dest_binary}" "${output_path}"
2377                     DEPENDS ${target})
2378
2379    # TODO: Make use of generator expressions below once CMake 3.19 or higher is the minimum supported version.
2380    set(should_build_all)
2381    get_target_property(target_excluded_from_all ${target} EXCLUDE_FROM_ALL)
2382    if (NOT target_excluded_from_all)
2383      set(should_build_all ALL)
2384    endif()
2385    add_custom_target(${target_name} ${should_build_all} DEPENDS ${target} ${output_path})
2386    get_subproject_title(subproject_title)
2387    set_target_properties(${target_name} PROPERTIES FOLDER "${subproject_title}/Tools")
2388
2389    # Make sure both the link and target are toolchain tools
2390    if (${link_name} IN_LIST LLVM_TOOLCHAIN_TOOLS AND ${target} IN_LIST LLVM_TOOLCHAIN_TOOLS)
2391      set(TOOL_IS_TOOLCHAIN ON)
2392    endif()
2393
2394    if ((TOOL_IS_TOOLCHAIN OR NOT LLVM_INSTALL_TOOLCHAIN_ONLY) AND LLVM_BUILD_TOOLS)
2395      llvm_install_symlink("${project}" ${link_name} ${target})
2396    endif()
2397  endif()
2398endfunction()
2399
2400function(add_llvm_tool_symlink link_name target)
2401  llvm_add_tool_symlink(LLVM ${ARGV})
2402endfunction()
2403
2404function(llvm_externalize_debuginfo name)
2405  if(NOT LLVM_EXTERNALIZE_DEBUGINFO)
2406    return()
2407  endif()
2408
2409  if(NOT LLVM_EXTERNALIZE_DEBUGINFO_SKIP_STRIP)
2410    if(APPLE)
2411      if(NOT CMAKE_STRIP)
2412        set(CMAKE_STRIP xcrun strip)
2413      endif()
2414      set(strip_command COMMAND ${CMAKE_STRIP} -S -x $<TARGET_FILE:${name}>)
2415    else()
2416      set(strip_command COMMAND ${CMAKE_STRIP} -g -x $<TARGET_FILE:${name}>)
2417    endif()
2418  endif()
2419
2420  if(APPLE)
2421    if(LLVM_EXTERNALIZE_DEBUGINFO_EXTENSION)
2422      set(file_ext ${LLVM_EXTERNALIZE_DEBUGINFO_EXTENSION})
2423    else()
2424      set(file_ext dSYM)
2425    endif()
2426
2427    set(output_name "$<TARGET_FILE_NAME:${name}>.${file_ext}")
2428
2429    if(LLVM_EXTERNALIZE_DEBUGINFO_OUTPUT_DIR)
2430      set(output_path "-o=${LLVM_EXTERNALIZE_DEBUGINFO_OUTPUT_DIR}/${output_name}")
2431    else()
2432      set(output_path "-o=${output_name}")
2433    endif()
2434
2435    if(CMAKE_CXX_FLAGS MATCHES "-flto"
2436      OR CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE} MATCHES "-flto")
2437
2438      set(lto_object ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${name}-lto.o)
2439      set_property(TARGET ${name} APPEND_STRING PROPERTY
2440        LINK_FLAGS " -Wl,-object_path_lto,${lto_object}")
2441    endif()
2442    if(NOT CMAKE_DSYMUTIL)
2443      set(CMAKE_DSYMUTIL xcrun dsymutil)
2444    endif()
2445    add_custom_command(TARGET ${name} POST_BUILD
2446      COMMAND ${CMAKE_DSYMUTIL} ${output_path} $<TARGET_FILE:${name}>
2447      ${strip_command}
2448      )
2449  else()
2450    add_custom_command(TARGET ${name} POST_BUILD
2451      COMMAND ${CMAKE_OBJCOPY} --only-keep-debug $<TARGET_FILE:${name}> $<TARGET_FILE:${name}>.debug
2452      ${strip_command} -R .gnu_debuglink
2453      COMMAND ${CMAKE_OBJCOPY} --add-gnu-debuglink=$<TARGET_FILE:${name}>.debug $<TARGET_FILE:${name}>
2454      )
2455  endif()
2456endfunction()
2457
2458# Usage: llvm_codesign(name [FORCE] [ENTITLEMENTS file] [BUNDLE_PATH path])
2459function(llvm_codesign name)
2460  cmake_parse_arguments(ARG "FORCE" "ENTITLEMENTS;BUNDLE_PATH" "" ${ARGN})
2461
2462  if(NOT LLVM_CODESIGNING_IDENTITY)
2463    return()
2464  endif()
2465
2466  if(CMAKE_GENERATOR STREQUAL "Xcode")
2467    set_target_properties(${name} PROPERTIES
2468      XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY ${LLVM_CODESIGNING_IDENTITY}
2469    )
2470    if(DEFINED ARG_ENTITLEMENTS)
2471      set_target_properties(${name} PROPERTIES
2472        XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS ${ARG_ENTITLEMENTS}
2473      )
2474    endif()
2475  elseif(APPLE AND CMAKE_HOST_SYSTEM_NAME MATCHES Darwin)
2476    if(NOT CMAKE_CODESIGN)
2477      set(CMAKE_CODESIGN xcrun codesign)
2478    endif()
2479    if(NOT CMAKE_CODESIGN_ALLOCATE)
2480      execute_process(
2481        COMMAND xcrun -f codesign_allocate
2482        OUTPUT_STRIP_TRAILING_WHITESPACE
2483        OUTPUT_VARIABLE CMAKE_CODESIGN_ALLOCATE
2484      )
2485    endif()
2486    if(DEFINED ARG_ENTITLEMENTS)
2487      set(pass_entitlements --entitlements ${ARG_ENTITLEMENTS})
2488    endif()
2489
2490    if (NOT ARG_BUNDLE_PATH)
2491      set(ARG_BUNDLE_PATH $<TARGET_FILE:${name}>)
2492    endif()
2493
2494    # ld64 now always codesigns the binaries it creates. Apply the force arg
2495    # unconditionally so that we can - for example - add entitlements to the
2496    # targets that need it.
2497    set(force_flag "-f")
2498
2499    add_custom_command(
2500      TARGET ${name} POST_BUILD
2501      COMMAND ${CMAKE_COMMAND} -E
2502              env CODESIGN_ALLOCATE=${CMAKE_CODESIGN_ALLOCATE}
2503              ${CMAKE_CODESIGN} -s ${LLVM_CODESIGNING_IDENTITY}
2504              ${pass_entitlements} ${force_flag} ${ARG_BUNDLE_PATH}
2505    )
2506  endif()
2507endfunction()
2508
2509function(llvm_setup_rpath name)
2510  if(CMAKE_INSTALL_RPATH)
2511    return()
2512  endif()
2513
2514  if(LLVM_INSTALL_PREFIX AND NOT (LLVM_INSTALL_PREFIX STREQUAL CMAKE_INSTALL_PREFIX))
2515    set(extra_libdir ${LLVM_LIBRARY_DIR})
2516  elseif(LLVM_BUILD_LIBRARY_DIR)
2517    set(extra_libdir ${LLVM_LIBRARY_DIR})
2518  endif()
2519
2520  if (APPLE)
2521    set(_install_name_dir INSTALL_NAME_DIR "@rpath")
2522    set(_install_rpath "@loader_path/../lib${LLVM_LIBDIR_SUFFIX}" ${extra_libdir})
2523  elseif(${CMAKE_SYSTEM_NAME} MATCHES "AIX" AND BUILD_SHARED_LIBS)
2524    # $ORIGIN is not interpreted at link time by aix ld.
2525    # Since BUILD_SHARED_LIBS is only recommended for use by developers,
2526    # hardcode the rpath to build/install lib dir first in this mode.
2527    # FIXME: update this when there is better solution.
2528    set(_install_rpath "${LLVM_LIBRARY_OUTPUT_INTDIR}" "${CMAKE_INSTALL_PREFIX}/lib${LLVM_LIBDIR_SUFFIX}" ${extra_libdir})
2529  elseif(UNIX)
2530    set(_build_rpath "\$ORIGIN/../lib${LLVM_LIBDIR_SUFFIX}" ${extra_libdir})
2531    set(_install_rpath "\$ORIGIN/../lib${LLVM_LIBDIR_SUFFIX}")
2532    if(${CMAKE_SYSTEM_NAME} MATCHES "(FreeBSD|DragonFly)")
2533      set_property(TARGET ${name} APPEND_STRING PROPERTY
2534                   LINK_FLAGS " -Wl,-z,origin ")
2535    endif()
2536    if(LLVM_LINKER_IS_GNULD AND NOT ${LLVM_LIBRARY_OUTPUT_INTDIR} STREQUAL "")
2537      # $ORIGIN is not interpreted at link time by ld.bfd
2538      set_property(TARGET ${name} APPEND_STRING PROPERTY
2539                   LINK_FLAGS " -Wl,-rpath-link,${LLVM_LIBRARY_OUTPUT_INTDIR} ")
2540    endif()
2541  else()
2542    return()
2543  endif()
2544
2545  # Enable BUILD_WITH_INSTALL_RPATH unless CMAKE_BUILD_RPATH is set and not
2546  # building for macOS or AIX, as those platforms seemingly require it.
2547  # On AIX, the tool chain doesn't support modifying rpaths/libpaths for XCOFF
2548  # on install at the moment, so BUILD_WITH_INSTALL_RPATH is required.
2549  if("${CMAKE_BUILD_RPATH}" STREQUAL "")
2550    if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin|AIX")
2551      set_property(TARGET ${name} PROPERTY BUILD_WITH_INSTALL_RPATH ON)
2552    else()
2553      set_property(TARGET ${name} APPEND PROPERTY BUILD_RPATH "${_build_rpath}")
2554    endif()
2555  endif()
2556
2557  set_target_properties(${name} PROPERTIES
2558                        INSTALL_RPATH "${_install_rpath}"
2559                        ${_install_name_dir})
2560endfunction()
2561
2562function(setup_dependency_debugging name)
2563  if(NOT LLVM_DEPENDENCY_DEBUGGING)
2564    return()
2565  endif()
2566
2567  if("intrinsics_gen" IN_LIST ARGN)
2568    return()
2569  endif()
2570
2571  set(deny_attributes_inc "(deny file* (literal \"${LLVM_BINARY_DIR}/include/llvm/IR/Attributes.inc\"))")
2572  set(deny_intrinsics_inc "(deny file* (literal \"${LLVM_BINARY_DIR}/include/llvm/IR/Intrinsics.inc\"))")
2573
2574  set(sandbox_command "sandbox-exec -p '(version 1) (allow default) ${deny_attributes_inc} ${deny_intrinsics_inc}'")
2575  set_target_properties(${name} PROPERTIES RULE_LAUNCH_COMPILE ${sandbox_command})
2576endfunction()
2577
2578# If the sources at the given `path` are under version control, set `out_var`
2579# to the the path of a file which will be modified when the VCS revision
2580# changes, attempting to create that file if it does not exist; if no such
2581# file exists and one cannot be created, instead set `out_var` to the
2582# empty string.
2583#
2584# If the sources are not under version control, do not define `out_var`.
2585function(find_first_existing_vc_file path out_var)
2586  if(NOT EXISTS "${path}")
2587    return()
2588  endif()
2589  find_package(Git)
2590  if(GIT_FOUND)
2591    execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --git-dir
2592      WORKING_DIRECTORY ${path}
2593      RESULT_VARIABLE git_result
2594      OUTPUT_VARIABLE git_output
2595      ERROR_QUIET)
2596    if(git_result EQUAL 0)
2597      string(STRIP "${git_output}" git_output)
2598      get_filename_component(git_dir ${git_output} ABSOLUTE BASE_DIR ${path})
2599      # Some branchless cases (e.g. 'repo') may not yet have .git/logs/HEAD
2600      if (NOT EXISTS "${git_dir}/logs/HEAD")
2601        execute_process(COMMAND ${CMAKE_COMMAND} -E touch HEAD
2602          WORKING_DIRECTORY "${git_dir}/logs"
2603          RESULT_VARIABLE touch_head_result
2604          ERROR_QUIET)
2605        if (NOT touch_head_result EQUAL 0)
2606          set(${out_var} "" PARENT_SCOPE)
2607          return()
2608        endif()
2609      endif()
2610      set(${out_var} "${git_dir}/logs/HEAD" PARENT_SCOPE)
2611    endif()
2612  endif()
2613endfunction()
2614
2615function(get_host_tool_path tool_name setting_name exe_var_name target_var_name)
2616  set(${setting_name}_DEFAULT "")
2617
2618  if(LLVM_NATIVE_TOOL_DIR)
2619    if(EXISTS "${LLVM_NATIVE_TOOL_DIR}/${tool_name}${LLVM_HOST_EXECUTABLE_SUFFIX}")
2620      set(${setting_name}_DEFAULT "${LLVM_NATIVE_TOOL_DIR}/${tool_name}${LLVM_HOST_EXECUTABLE_SUFFIX}")
2621    endif()
2622  endif()
2623
2624  set(${setting_name} "${${setting_name}_DEFAULT}" CACHE
2625    STRING "Host ${tool_name} executable. Saves building if cross-compiling.")
2626
2627  if(${setting_name})
2628    set(exe_name ${${setting_name}})
2629    set(target_name "")
2630  elseif(LLVM_USE_HOST_TOOLS)
2631    get_native_tool_path(${tool_name} exe_name)
2632    set(target_name host_${tool_name})
2633  else()
2634    set(exe_name $<TARGET_FILE:${tool_name}>)
2635    set(target_name ${tool_name})
2636  endif()
2637  # Force setting the cache variable because they are only used for being
2638  # global in scope. Using regular variables would require careful audit of the
2639  # code with several parent scope set commands.
2640  set(${exe_var_name} "${exe_name}" CACHE STRING "" FORCE)
2641  set(${target_var_name} "${target_name}" CACHE STRING "" FORCE)
2642endfunction()
2643
2644function(setup_host_tool tool_name setting_name exe_var_name target_var_name)
2645  get_host_tool_path(${tool_name} ${setting_name} ${exe_var_name} ${target_var_name})
2646  # Set up a native tool build if necessary
2647  if(LLVM_USE_HOST_TOOLS AND NOT ${setting_name})
2648    build_native_tool(${tool_name} exe_name DEPENDS ${tool_name})
2649    add_custom_target(${${target_var_name}} DEPENDS ${exe_name})
2650    get_subproject_title(subproject_title)
2651    set_target_properties(${${target_var_name}} PROPERTIES FOLDER "${subproject_title}/Native")
2652  endif()
2653endfunction()
2654