brintos

brintos / llvm-project-archived public Read only

0
0
Text · 102.7 KiB · 2480d73 Raw
2709 lines · plain
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 variable11# 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 in13# 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 to31  # force EH32  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 individual58  # targets can use to force RTTI59  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 PROPERTY85          COMPILE_FLAGS "${target_compile_flags}")86      endif()87      if("${suf}" STREQUAL ".c")88        set_property(SOURCE ${fn} APPEND_STRING PROPERTY89          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 PROPERTY95      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      VERBATIM108      COMMENT "Creating export file for ${target_name}")109    set_property(TARGET ${target_name} APPEND_STRING PROPERTY110                 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 build113    # compiler driver to defer to the specified export list.114    set(native_export_file "${export_file}")115    set_property(TARGET ${target_name} APPEND_STRING PROPERTY116                 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      VERBATIM132      COMMENT "Creating export file for ${target_name}")133    if (${LLVM_LINKER_IS_SOLARISLD})134      set_property(TARGET ${target_name} APPEND_STRING PROPERTY135                   LINK_FLAGS "  -Wl,-M,\"${CMAKE_CURRENT_BINARY_DIR}/${native_export_file}\"")136    else()137      set_property(TARGET ${target_name} APPEND_STRING PROPERTY138                   LINK_FLAGS "  -Wl,--version-script,\"${CMAKE_CURRENT_BINARY_DIR}/${native_export_file}\"")139    endif()140  elseif(WIN32 OR CYGWIN)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      VERBATIM148      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 interface152      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 linker155      set(export_file_linker_flag "-Wl,/DEF:${export_file_linker_flag}")156    elseif(MINGW OR CYGWIN)157      # ${export_file_linker_flag}, which is the plain file name, works as is158      # when passed to the compiler driver, which then passes it on to the159      # 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 PROPERTY165                 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, it182  # forces recompilation of the source file. The LINK_DEPENDS target183  # property only works for makefile-based generators.184  # FIXME: This is not safe because this will create the same target185  # ${native_export_file} in several different file:186  # - One where we emitted ${target_name}_exports187  # - One where we emitted the build command for the following object.188  # set_property(SOURCE ${first_source_file} APPEND PROPERTY189  #   OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${native_export_file})190 191  set_property(DIRECTORY APPEND192    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 14747197  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 stdout226    ERROR_VARIABLE stderr227    )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" OR235           "${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 "Solaris Link Editors" OR261           "${stdout}" MATCHES "Solaris Link Editors")262      set(LLVM_LINKER_DETECTED YES CACHE INTERNAL "")263      set(LLVM_LINKER_IS_SOLARISLD YES CACHE INTERNAL "")264      message(STATUS "Linker detection: Solaris ld")265    else()266      set(LLVM_LINKER_DETECTED NO CACHE INTERNAL "")267      message(STATUS "Linker detection: unknown")268    endif()269  endif()270 271  if("${CMAKE_SYSTEM_NAME}" MATCHES "Darwin")272    include(CheckLinkerFlag)273    # Linkers that support Darwin allow a setting to internalize all symbol exports,274    # aiding in reducing binary size and often is applicable for executables.275    check_linker_flag(C "-Wl,-no_exported_symbols" LLVM_LINKER_SUPPORTS_NO_EXPORTED_SYMBOLS)276 277    if (NOT LLVM_USE_LINKER)278      # Apple's linker complains about duplicate libraries, which CMake likes to do279      # to support ELF platforms. To silence that warning, we can use280      # -no_warn_duplicate_libraries, but only in versions of the linker that281      # support that flag.282      check_linker_flag(C "-Wl,-no_warn_duplicate_libraries" LLVM_LINKER_SUPPORTS_NO_WARN_DUPLICATE_LIBRARIES)283    else()284      set(LLVM_LINKER_SUPPORTS_NO_WARN_DUPLICATE_LIBRARIES OFF CACHE INTERNAL "")285    endif()286 287  else()288    set(LLVM_LINKER_SUPPORTS_NO_EXPORTED_SYMBOLS OFF CACHE INTERNAL "")289  endif()290endif()291 292function(add_link_opts target_name)293  include(CheckLinkerFlag)294  get_llvm_distribution(${target_name} in_distribution in_distribution_var)295  if(NOT in_distribution)296    # Don't LTO optimize targets that aren't part of any distribution.297    if (LLVM_ENABLE_LTO)298      # We may consider avoiding LTO altogether by using -fembed-bitcode299      # and teaching the linker to select machine code from .o files, see300      # https://lists.llvm.org/pipermail/llvm-dev/2021-April/149843.html301      if((UNIX OR MINGW) AND LINKER_IS_LLD)302        set_property(TARGET ${target_name} APPEND_STRING PROPERTY303                      LINK_FLAGS " -Wl,--lto-O0")304      elseif(LINKER_IS_LLD_LINK)305        set_property(TARGET ${target_name} APPEND_STRING PROPERTY306                      LINK_FLAGS " /opt:lldlto=0")307      elseif(APPLE AND NOT uppercase_LLVM_ENABLE_LTO STREQUAL "THIN")308        set_property(TARGET ${target_name} APPEND_STRING PROPERTY309                      LINK_FLAGS " -Wl,-mllvm,-O0")310      endif()311    endif()312  endif()313 314  # Don't use linker optimizations in debug builds since it slows down the315  # linker in a context where the optimizations are not important.316  if (NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG")317    if(NOT LLVM_NO_DEAD_STRIP)318      if("${CMAKE_SYSTEM_NAME}" MATCHES "Darwin")319        # ld64's implementation of -dead_strip breaks tools that use plugins.320        set_property(TARGET ${target_name} APPEND_STRING PROPERTY321                     LINK_FLAGS " -Wl,-dead_strip")322      elseif("${CMAKE_SYSTEM_NAME}" MATCHES "SunOS" AND LLVM_LINKER_IS_SOLARISLD)323        # Support for ld -z discard-unused=sections was only added in324        # Solaris 11.4.  GNU ld ignores it, but warns every time.325        check_linker_flag(CXX "-Wl,-z,discard-unused=sections" LINKER_SUPPORTS_Z_DISCARD_UNUSED)326        if (LINKER_SUPPORTS_Z_DISCARD_UNUSED)327          set_property(TARGET ${target_name} APPEND_STRING PROPERTY328                       LINK_FLAGS " -Wl,-z,discard-unused=sections")329        endif()330      elseif(NOT MSVC AND NOT CMAKE_SYSTEM_NAME MATCHES "AIX|OS390")331        # TODO Revisit this later on z/OS.332        set_property(TARGET ${target_name} APPEND_STRING PROPERTY333                     LINK_FLAGS " -Wl,--gc-sections")334      endif()335    else() #LLVM_NO_DEAD_STRIP336      if("${CMAKE_SYSTEM_NAME}" MATCHES "AIX")337        set_property(TARGET ${target_name} APPEND_STRING PROPERTY338                     LINK_FLAGS " -Wl,-bnogc")339      endif()340    endif()341  endif()342 343  if(LLVM_LINKER_SUPPORTS_NO_WARN_DUPLICATE_LIBRARIES)344    set_property(TARGET ${target_name} APPEND_STRING PROPERTY345                 LINK_FLAGS " -Wl,-no_warn_duplicate_libraries")346  endif()347 348  if(ARG_SUPPORT_PLUGINS AND "${CMAKE_SYSTEM_NAME}" MATCHES "AIX")349    set_property(TARGET ${target_name} APPEND_STRING PROPERTY350                 LINK_FLAGS " -Wl,-brtl")351  endif()352 353  # Check for existence of symbolic functions flag. Not supported354  # by the older BFD linker (such as on some OpenBSD archs), the355  # MinGW driver for LLD, and the Solaris native linker.356  check_linker_flag(CXX "-Wl,-Bsymbolic-functions"357                    LLVM_LINKER_SUPPORTS_B_SYMBOLIC_FUNCTIONS)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 platform370    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 the404# VERSIONINFO data to the project.  This embeds version resource information405# 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 int424#     Optional major version number (defaults to LLVM_VERSION_MAJOR)425#   VERSION_MINOR int426#     Optional minor version number (defaults to LLVM_VERSION_MINOR)427#   VERSION_PATCHLEVEL int428#     Optional patchlevel version number (defaults to LLVM_VERSION_PATCH)429#   VERSION_STRING430#     Optional version string (defaults to PACKAGE_VERSION)431#   PRODUCT_NAME432#     Optional product name string (defaults to "LLVM")433#   )434function(set_windows_version_resource_properties name resource_file)435  cmake_parse_arguments(ARG436    ""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_DEFINITIONS481               "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;STATIC493#     STATIC by default w/o BUILD_SHARED_LIBS.494#     SHARED by default w/  BUILD_SHARED_LIBS.495#   OBJECT496#     Also create an OBJECT library target. Default if STATIC && SHARED.497#   MODULE498#     Target ${name} might not be created on unsupported platforms.499#     Check with "if(TARGET ${name})".500#   DISABLE_LLVM_LINK_LLVM_DYLIB501#     Do not link this library to libLLVM, even if502#     LLVM_LINK_LLVM_DYLIB is enabled.503#   OUTPUT_NAME name504#     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_HEADERS512#     May specify header files for IDE generators.513#   SONAME514#     Should set SONAME link flags and create symlinks515#   NO_INSTALL_RPATH516#     Suppress default RPATH settings in shared libraries.517#   PLUGIN_TOOL518#     The tool (i.e. cmake target) that this plugin will link against519#   COMPONENT_LIB520#      This is used to specify that this is a component library of521#      LLVM which means that the source resides in llvm/lib/ and it is a522#      candidate for inclusion into libLLVM.so.523#   )524function(llvm_add_library name)525  cmake_parse_arguments(ARG526    "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 not546    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 objlib565  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_ALL569      ${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 might590    # result in generating header files.  Add a dependendency so that591    # the generated header is created before this object library.592    if(ARG_LINK_LIBS)593      cmake_parse_arguments(LINK_LIBS_ARG594        ""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 -lpthread601          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    # static617    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} STATIC623      ${output_name}624      OBJLIBS ${ALL_FILES} # objlib625      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 limit651  ## https://blog.llvm.org/2018/11/30-faster-windows-builds-with-clang-cl_14.html652  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 APIs667    # 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 AND669        (NOT (WIN32 OR CYGWIN) OR ((MINGW OR CYGWIN) AND CMAKE_CXX_COMPILER_ID MATCHES "Clang")) AND670        NOT ("${CMAKE_SYSTEM_NAME}" MATCHES "AIX") AND671        NOT DEFINED CMAKE_CXX_VISIBILITY_PRESET)672 673      set_target_properties(${name} PROPERTIES674                            C_VISIBILITY_PRESET hidden675                            CXX_VISIBILITY_PRESET hidden676                            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      PROPERTIES703      OUTPUT_NAME ${ARG_OUTPUT_NAME}704      )705  endif()706 707  if(ARG_MODULE)708    set_target_properties(${name} PROPERTIES709      PREFIX ""710      SUFFIX ${LLVM_PLUGIN_EXT}711      )712  endif()713 714  if(ARG_SHARED)715    if(MSVC)716      set_target_properties(${name} PROPERTIES717        PREFIX ""718        )719    endif()720 721    # Set SOVERSION on shared libraries that lack explicit SONAME722    # specifier, on *nix systems that are not Darwin.723    if(UNIX AND NOT APPLE AND NOT ARG_SONAME)724      set_target_properties(${name}725        PROPERTIES726        # 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 this734    # target. Doing so is actively harmful for the modules build because it735    # creates extra module variants, and not useful because we don't use these736    # 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 AND NOT CYGWIN)754        llvm_install_library_symlink(${api_name} ${library_name} SHARED755          COMPONENT ${name})756        llvm_install_library_symlink(${output_name} ${library_name} SHARED757          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_libs780       ${ARG_LINK_COMPONENTS}781       ${LLVM_LINK_COMPONENTS}782       )783    endif()784  else()785    # Components have not been defined explicitly in CMake, so add the786    # dependency information for this library through their name, and let787    # LLVMBuildResolveComponentsLink resolve the mapping.788    #789    # It would be nice to verify that we have the dependencies for this library790    # name, but using get_property(... SET) doesn't suffice to determine if a791    # 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 the795    # link step applied in LLVMBuildResolveComponentsLink uses the same796    # 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 will823  # often get an older timestamp than the last object that was added824  # or updated.  To fix this, we add a custom command to touch archive825  # after it's been built so that ninja won't rebuild it unnecessarily826  # the next time it's run.827  if(ARG_STATIC AND LLVM_TOUCH_STATIC_LIBRARIES)828    add_custom_command(TARGET ${name}829      POST_BUILD830      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}-stripped865                    DEPENDS ${file_dependencies}866                    COMMAND "${CMAKE_COMMAND}"867                            ${component_option}868                            ${prefix_option}869                            -DCMAKE_INSTALL_DO_STRIP=1870                            -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 any885# source attached but other components can add themselves to them. If the886# component supports is a Target and it supports JIT compilation, HAS_JIT must887# be passed. One can use ADD_TO_COMPONENT option from add_llvm_component_library888# 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 properties903# eventually set:904#   - LLVM_COMPONENT_NAME: the name of the component, which can be the name of905#     the associated library or the one specified through COMPONENT_NAME906#   - LLVM_LINK_COMPONENTS: a list of component this component depends on907#   - COMPONENT_HAS_JIT: (only for group component) whether this target group908#     supports JIT compilation909# Additionnaly, the ADD_TO_COMPONENT <component> option make it possible to add this910# component to the LLVM_LINK_COMPONENTS of <component>.911function(add_llvm_component_library name)912  cmake_parse_arguments(ARG913    ""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(ARG935    "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 are948  # never installed and are only exported as a target in the special build tree949  # 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" target957    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 objlib1008  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_ALL1012      ${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.in1030          ${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_BUILD1038        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(ARG1054    "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 this1104  # target. Doing so is actively harmful for the modules build because it1105  # creates extra module variants, and not useful because we don't use these1106  # 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 AND1114      NOT LLVM_ENABLE_EXPORTED_SYMBOLS_IN_EXECUTABLES AND1115      NOT ARG_EXPORT_SYMBOLS)1116    if(LLVM_LINKER_SUPPORTS_NO_EXPORTED_SYMBOLS)1117      set_property(TARGET ${name} APPEND_STRING PROPERTY1118        LINK_FLAGS " -Wl,-no_exported_symbols")1119    else()1120      message(FATAL_ERROR1121        "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 main1146    # executable must be linked with it in order to provide consistent1147    # 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 AND1166     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 belongs1181#   to. If set, the plugin will link statically by default it if the1182#   project was enabled.1183function(add_llvm_pass_plugin name)1184  cmake_parse_arguments(ARG1185    "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 a1192  # 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 going1200  # 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 an1208    # object library as of now1209    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 tools1234# registered with the ENABLE_PLUGINS option.1235#1236# if GEN_CONFIG option is set, also generate X Macro file for extension1237# handling. It provides a HANDLE_EXTENSION(extension_namespace, ExtensionProject)1238# call for each extension allowing client code to define1239# HANDLE_EXTENSION to have a specific code be run for each extension.1240#1241function(process_llvm_pass_plugins)1242  cmake_parse_arguments(ARG1243      "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 component1253  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 file1259  # for usage in third-party configuration.1260  if(ARG_GEN_CONFIG)1261 1262      ## Part 1: Extension header to be included whenever we need extension1263      #  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(WRITE1271          "${llvm_cmake_builddir}/LLVMConfigExtensions.cmake"1272          "set(LLVM_STATIC_EXTENSIONS ${LLVM_STATIC_EXTENSIONS})")1273      install(FILES1274          ${llvm_cmake_builddir}/LLVMConfigExtensions.cmake1275          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 change1286      execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different1287          "${ExtensionDef}.tmp"1288          "${ExtensionDef}")1289      file(REMOVE "${ExtensionDef}.tmp")1290 1291      ## Part 2: Extension header that captures each extension dependency, to be1292      #  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(WRITE1307          "${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 change1337      execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different1338          "${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 to1347    # export1348    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 the1351    # 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 the1355    # transitive link dependencies. Do this by starting with the set of direct1356    # 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          # If this is a ALIAS target, continue with its aliasee instead.1363          get_target_property(aliased_lib ${lib} ALIASED_TARGET)1364          if(aliased_lib)1365             set(new_libs ${lib_aliased_target})1366             list(APPEND newer_libs ${aliased_lib})1367             continue()1368          endif()1369 1370          get_target_property(lib_type ${lib} TYPE)1371          if("${lib_type}" STREQUAL "STATIC_LIBRARY")1372            list(APPEND static_libs ${lib})1373          else()1374            list(APPEND other_libs ${lib})1375          endif()1376          get_target_property(transitive_libs ${lib} INTERFACE_LINK_LIBRARIES)1377          foreach(transitive_lib ${transitive_libs})1378            if(TARGET ${transitive_lib} AND NOT ${transitive_lib} IN_LIST link_libs)1379              list(APPEND newer_libs ${transitive_lib})1380              list(APPEND link_libs ${transitive_lib})1381            endif()1382          endforeach(transitive_lib)1383        endif()1384      endforeach(lib)1385      set(new_libs ${newer_libs})1386      set(newer_libs "")1387    endwhile()1388    list(REMOVE_DUPLICATES static_libs)1389    if (MSVC)1390      set(mangling microsoft)1391    else()1392      set(mangling itanium)1393    endif()1394    get_host_tool_path(llvm-nm LLVM_NM llvm_nm_exe llvm_nm_target)1395    get_host_tool_path(llvm-readobj LLVM_READOBJ llvm_readobj_exe llvm_readobj_target)1396    add_custom_command(OUTPUT ${exported_symbol_file}1397                       COMMAND "${Python3_EXECUTABLE}"1398                         ${LLVM_MAIN_SRC_DIR}/utils/extract_symbols.py1399                         --mangling=${mangling} ${static_libs}1400                         -o ${exported_symbol_file}1401                         --nm=${llvm_nm_exe}1402                         --readobj=${llvm_readobj_exe}1403                       WORKING_DIRECTORY ${LLVM_LIBRARY_OUTPUT_INTDIR}1404                       DEPENDS ${LLVM_MAIN_SRC_DIR}/utils/extract_symbols.py1405                         ${static_libs} ${llvm_nm_target} ${llvm_readobj_target}1406                       VERBATIM1407                       COMMENT "Generating export list for ${target}")1408    add_llvm_symbol_exports( ${target} ${exported_symbol_file} )1409    # If something links against this executable then we want a1410    # transitive link against only the libraries whose symbols1411    # we aren't exporting.1412    set_target_properties(${target} PROPERTIES INTERFACE_LINK_LIBRARIES "${other_libs}")1413    # The default import library suffix that cmake uses for cygwin/mingw is1414    # ".dll.a", but for clang.exe that causes a collision with libclang.dll,1415    # where the import libraries of both get named libclang.dll.a. Use a suffix1416    # of ".exe.a" to avoid this.1417    if(CYGWIN OR MINGW)1418      set_target_properties(${target} PROPERTIES IMPORT_SUFFIX ".exe.a")1419    endif()1420  elseif(NOT (WIN32 OR CYGWIN))1421    # On Windows auto-exporting everything doesn't work because of the limit on1422    # the size of the exported symbol table, but on other platforms we can do1423    # it without any trouble.1424    set_target_properties(${target} PROPERTIES ENABLE_EXPORTS 1)1425    # CMake doesn't set CMAKE_EXE_EXPORTS_${lang}_FLAG on Solaris, so1426    # ENABLE_EXPORTS has no effect.  While Solaris ld defaults to -rdynamic1427    # behaviour, GNU ld needs it.1428    if (APPLE OR "${CMAKE_SYSTEM_NAME}" STREQUAL "SunOS")1429      set_property(TARGET ${target} APPEND_STRING PROPERTY1430        LINK_FLAGS " -rdynamic")1431    endif()1432  endif()1433endfunction()1434 1435# Export symbols if LLVM plugins are enabled.1436function(export_executable_symbols_for_plugins target)1437  if(LLVM_ENABLE_PLUGINS OR LLVM_EXPORT_SYMBOLS_FOR_PLUGINS)1438    export_executable_symbols(${target})1439  endif()1440endfunction()1441 1442if(NOT LLVM_TOOLCHAIN_TOOLS)1443  set (LLVM_TOOLCHAIN_TOOLS1444    llvm-ar1445    llvm-cov1446    llvm-cxxfilt1447    llvm-dlltool1448    llvm-dwp1449    llvm-ranlib1450    llvm-lib1451    llvm-mca1452    llvm-ml1453    llvm-ml641454    llvm-nm1455    llvm-objcopy1456    llvm-objdump1457    llvm-pdbutil1458    llvm-rc1459    llvm-readobj1460    llvm-size1461    llvm-strings1462    llvm-strip1463    llvm-profdata1464    llvm-profgen1465    llvm-symbolizer1466    # symlink version of some of above tools that are enabled by1467    # LLVM_INSTALL_BINUTILS_SYMLINKS.1468    addr2line1469    ar1470    c++filt1471    ranlib1472    nm1473    objcopy1474    objdump1475    readelf1476    size1477    strings1478    strip1479    )1480  # Build llvm-mt if libxml2 is enabled. Can be used by runtimes.1481  if (LLVM_ENABLE_LIBXML2)1482    list(APPEND LLVM_TOOLCHAIN_TOOLS llvm-mt)1483  endif()1484  if (LLVM_TOOL_LLVM_DRIVER_BUILD)1485    list(APPEND LLVM_TOOLCHAIN_TOOLS llvm-driver)1486  endif()1487endif()1488 1489macro(llvm_add_tool project name)1490  cmake_parse_arguments(ARG "DEPENDS;GENERATE_DRIVER" "" "" ${ARGN})1491  if( NOT LLVM_BUILD_TOOLS )1492    set(EXCLUDE_FROM_ALL ON)1493  endif()1494  if(ARG_GENERATE_DRIVER1495     AND LLVM_TOOL_LLVM_DRIVER_BUILD1496     AND (NOT LLVM_DISTRIBUTION_COMPONENTS OR ${name} IN_LIST LLVM_DISTRIBUTION_COMPONENTS)1497    )1498    generate_llvm_objects(${name} ${ARGN})1499    add_custom_target(${name} DEPENDS llvm-driver)1500  else()1501    add_llvm_executable(${name} ${ARGN})1502 1503    if ( ${name} IN_LIST LLVM_TOOLCHAIN_TOOLS OR NOT LLVM_INSTALL_TOOLCHAIN_ONLY)1504      if( LLVM_BUILD_TOOLS )1505        get_target_export_arg(${name} ${project} export_to_llvmexports)1506        install(TARGETS ${name}1507                ${export_to_llvmexports}1508                RUNTIME DESTINATION ${${project}_TOOLS_INSTALL_DIR}1509                COMPONENT ${name})1510        if (LLVM_ENABLE_PDB)1511          install(FILES $<TARGET_PDB_FILE:${name}> 1512                DESTINATION "${${project}_TOOLS_INSTALL_DIR}" COMPONENT ${name} 1513                OPTIONAL)1514        endif()1515 1516        if (NOT LLVM_ENABLE_IDE)1517          add_llvm_install_targets(install-${name}1518                                  DEPENDS ${name}1519                                  COMPONENT ${name})1520        endif()1521      endif()1522    endif()1523    if( LLVM_BUILD_TOOLS )1524      string(TOUPPER "${project}" project_upper)1525      set_property(GLOBAL APPEND PROPERTY ${project_upper}_EXPORTS ${name})1526    endif()1527  endif()1528  get_subproject_title(subproject_title)1529  set_target_properties(${name} PROPERTIES FOLDER "${subproject_title}/Tools")1530  set_target_properties(${name} PROPERTIES XCODE_GENERATE_SCHEME ON)1531endmacro(llvm_add_tool project name)1532 1533macro(add_llvm_tool name)1534  llvm_add_tool(LLVM ${ARGV})1535endmacro()1536 1537 1538macro(add_llvm_example name)1539  if( NOT LLVM_BUILD_EXAMPLES )1540    set(EXCLUDE_FROM_ALL ON)1541  endif()1542  add_llvm_executable(${name} EXPORT_SYMBOLS ${ARGN})1543  if( LLVM_BUILD_EXAMPLES )1544    install(TARGETS ${name} RUNTIME DESTINATION "${LLVM_EXAMPLES_INSTALL_DIR}")1545    if (LLVM_ENABLE_PDB)1546      install(FILES $<TARGET_PDB_FILE:${name}> 1547              DESTINATION "${LLVM_EXAMPLES_INSTALL_DIR}" COMPONENT ${name} 1548              OPTIONAL)1549    endif()1550  endif()1551  get_subproject_title(subproject_title)1552  set_target_properties(${name} PROPERTIES FOLDER "${subproject_title}/Examples")1553endmacro(add_llvm_example name)1554 1555macro(add_llvm_example_library name)1556  if( NOT LLVM_BUILD_EXAMPLES )1557    set(EXCLUDE_FROM_ALL ON)1558    add_llvm_library(${name} BUILDTREE_ONLY ${ARGN})1559  else()1560    add_llvm_library(${name} ${ARGN})1561  endif()1562 1563  get_subproject_title(subproject_title)1564  set_target_properties(${name} PROPERTIES FOLDER "${subproject_title}/Examples")1565endmacro(add_llvm_example_library name)1566 1567# This is a macro that is used to create targets for executables that are needed1568# for development, but that are not intended to be installed by default.1569macro(add_llvm_utility name)1570  if ( NOT LLVM_BUILD_UTILS )1571    set(EXCLUDE_FROM_ALL ON)1572  endif()1573 1574  add_llvm_executable(${name} DISABLE_LLVM_LINK_LLVM_DYLIB ${ARGN})1575  get_subproject_title(subproject_title)1576  set_target_properties(${name} PROPERTIES FOLDER "${subproject_title}/Utils")1577  if ( ${name} IN_LIST LLVM_TOOLCHAIN_UTILITIES OR NOT LLVM_INSTALL_TOOLCHAIN_ONLY)1578    if (LLVM_INSTALL_UTILS AND LLVM_BUILD_UTILS)1579      get_target_export_arg(${name} LLVM export_to_llvmexports)1580      install(TARGETS ${name}1581              ${export_to_llvmexports}1582              RUNTIME DESTINATION ${LLVM_UTILS_INSTALL_DIR}1583              COMPONENT ${name})1584      if (LLVM_ENABLE_PDB)1585        install(FILES $<TARGET_PDB_FILE:${name}> 1586                DESTINATION "${LLVM_UTILS_INSTALL_DIR}" COMPONENT ${name} 1587                OPTIONAL)1588      endif()1589 1590      if (NOT LLVM_ENABLE_IDE)1591        add_llvm_install_targets(install-${name}1592                                 DEPENDS ${name}1593                                 COMPONENT ${name})1594      endif()1595      set_property(GLOBAL APPEND PROPERTY LLVM_EXPORTS ${name})1596    elseif(LLVM_BUILD_UTILS)1597      set_property(GLOBAL APPEND PROPERTY LLVM_EXPORTS_BUILDTREE_ONLY ${name})1598    endif()1599  endif()1600endmacro(add_llvm_utility name)1601 1602macro(add_llvm_fuzzer name)1603  cmake_parse_arguments(ARG "" "DUMMY_MAIN" "" ${ARGN})1604  get_subproject_title(subproject_title)1605  if( LLVM_LIB_FUZZING_ENGINE )1606    set(LLVM_OPTIONAL_SOURCES ${ARG_DUMMY_MAIN})1607    add_llvm_executable(${name} ${ARG_UNPARSED_ARGUMENTS})1608    target_link_libraries(${name} PRIVATE ${LLVM_LIB_FUZZING_ENGINE})1609    set_target_properties(${name} PROPERTIES FOLDER "${subproject_title}/Fuzzers")1610  elseif( LLVM_USE_SANITIZE_COVERAGE )1611    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=fuzzer")1612    set(LLVM_OPTIONAL_SOURCES ${ARG_DUMMY_MAIN})1613    add_llvm_executable(${name} ${ARG_UNPARSED_ARGUMENTS})1614    set_target_properties(${name} PROPERTIES FOLDER "${subproject_title}/Fuzzers")1615  elseif( ARG_DUMMY_MAIN )1616    add_llvm_executable(${name} ${ARG_DUMMY_MAIN} ${ARG_UNPARSED_ARGUMENTS})1617    set_target_properties(${name} PROPERTIES FOLDER "${subproject_title}/Fuzzers")1618  endif()1619endmacro()1620 1621macro(add_llvm_target target_name)1622  include_directories(BEFORE1623    ${CMAKE_CURRENT_BINARY_DIR}1624    ${CMAKE_CURRENT_SOURCE_DIR})1625  add_llvm_component_library(LLVM${target_name} ${ARGN})1626  set( CURRENT_LLVM_TARGET LLVM${target_name} )1627endmacro(add_llvm_target)1628 1629function(canonicalize_tool_name name output)1630  string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" nameStrip ${name})1631  string(REPLACE "-" "_" nameUNDERSCORE ${nameStrip})1632  string(TOUPPER ${nameUNDERSCORE} nameUPPER)1633  set(${output} "${nameUPPER}" PARENT_SCOPE)1634endfunction(canonicalize_tool_name)1635 1636# Custom add_subdirectory wrapper1637# Takes in a project name (i.e. LLVM), the subdirectory name, and an optional1638# path if it differs from the name.1639function(add_llvm_subdirectory project type name)1640  set(add_llvm_external_dir "${ARGN}")1641  if("${add_llvm_external_dir}" STREQUAL "")1642    set(add_llvm_external_dir ${name})1643  endif()1644  canonicalize_tool_name(${name} nameUPPER)1645  set(canonical_full_name ${project}_${type}_${nameUPPER})1646  get_property(already_processed GLOBAL PROPERTY ${canonical_full_name}_PROCESSED)1647  if(already_processed)1648    return()1649  endif()1650  set_property(GLOBAL PROPERTY ${canonical_full_name}_PROCESSED YES)1651 1652  if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${add_llvm_external_dir}/CMakeLists.txt)1653    # Treat it as in-tree subproject.1654    option(${canonical_full_name}_BUILD1655           "Whether to build ${name} as part of ${project}" On)1656    mark_as_advanced(${project}_${type}_${name}_BUILD)1657    if(${canonical_full_name}_BUILD)1658      add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${add_llvm_external_dir} ${add_llvm_external_dir})1659    endif()1660  else()1661    set(LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR1662      "${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR}"1663      CACHE PATH "Path to ${name} source directory")1664    set(${canonical_full_name}_BUILD_DEFAULT ON)1665    if(NOT LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR OR NOT EXISTS ${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR})1666      set(${canonical_full_name}_BUILD_DEFAULT OFF)1667    endif()1668    if("${LLVM_EXTERNAL_${nameUPPER}_BUILD}" STREQUAL "OFF")1669      set(${canonical_full_name}_BUILD_DEFAULT OFF)1670    endif()1671    option(${canonical_full_name}_BUILD1672      "Whether to build ${name} as part of LLVM"1673      ${${canonical_full_name}_BUILD_DEFAULT})1674    if (${canonical_full_name}_BUILD)1675      if(EXISTS ${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR})1676        add_subdirectory(${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR} ${add_llvm_external_dir})1677      elseif(NOT "${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR}" STREQUAL "")1678        message(WARNING "Nonexistent directory for ${name}: ${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR}")1679      endif()1680    endif()1681  endif()1682endfunction()1683 1684# Add external project that may want to be built as part of llvm such as Clang,1685# lld, and Polly. This adds two options. One for the source directory of the1686# project, which defaults to ${CMAKE_CURRENT_SOURCE_DIR}/${name}. Another to1687# enable or disable building it with everything else.1688# Additional parameter can be specified as the name of directory.1689macro(add_llvm_external_project name)1690  add_llvm_subdirectory(LLVM TOOL ${name} ${ARGN})1691endmacro()1692 1693macro(add_llvm_tool_subdirectory name)1694  add_llvm_external_project(${name})1695endmacro(add_llvm_tool_subdirectory)1696 1697macro(add_custom_linker_flags name)1698  if (LLVM_${name}_LINKER_FLAGS)1699    message(DEBUG "Applying ${LLVM_${name}_LINKER_FLAGS} to ${name}")1700    target_link_options(${name} PRIVATE ${LLVM_${name}_LINKER_FLAGS})1701  endif()1702endmacro()1703 1704function(get_project_name_from_src_var var output)1705  string(REGEX MATCH "LLVM_EXTERNAL_(.*)_SOURCE_DIR"1706         MACHED_TOOL "${var}")1707  if(MACHED_TOOL)1708    set(${output} ${CMAKE_MATCH_1} PARENT_SCOPE)1709  else()1710    set(${output} PARENT_SCOPE)1711  endif()1712endfunction()1713 1714function(create_subdirectory_options project type)1715  file(GLOB sub-dirs "${CMAKE_CURRENT_SOURCE_DIR}/*")1716  foreach(dir ${sub-dirs})1717    if(IS_DIRECTORY "${dir}" AND EXISTS "${dir}/CMakeLists.txt")1718      canonicalize_tool_name(${dir} name)1719      option(${project}_${type}_${name}_BUILD1720           "Whether to build ${name} as part of ${project}" On)1721      mark_as_advanced(${project}_${type}_${name}_BUILD)1722    endif()1723  endforeach()1724endfunction(create_subdirectory_options)1725 1726function(create_llvm_tool_options)1727  create_subdirectory_options(LLVM TOOL)1728endfunction(create_llvm_tool_options)1729 1730function(llvm_add_implicit_projects project)1731  set(list_of_implicit_subdirs "")1732  file(GLOB sub-dirs "${CMAKE_CURRENT_SOURCE_DIR}/*")1733  foreach(dir ${sub-dirs})1734    if(IS_DIRECTORY "${dir}" AND EXISTS "${dir}/CMakeLists.txt")1735      canonicalize_tool_name(${dir} name)1736      # I don't like special casing things by order, but the llvm-driver ends up1737      # linking the object libraries from all the tools that opt-in, so adding1738      # it separately at the end is probably the simplest case.1739      if("${name}" STREQUAL "LLVM_DRIVER")1740        continue()1741      endif()1742      if (${project}_TOOL_${name}_BUILD)1743        get_filename_component(fn "${dir}" NAME)1744        list(APPEND list_of_implicit_subdirs "${fn}")1745      endif()1746    endif()1747  endforeach()1748 1749  foreach(external_proj ${list_of_implicit_subdirs})1750    add_llvm_subdirectory(${project} TOOL "${external_proj}" ${ARGN})1751  endforeach()1752endfunction(llvm_add_implicit_projects)1753 1754function(add_llvm_implicit_projects)1755  llvm_add_implicit_projects(LLVM)1756endfunction(add_llvm_implicit_projects)1757 1758function(set_unittest_link_flags target_name)1759  # The runtime benefits of LTO don't outweight the compile time costs for1760  # tests.1761  if(LLVM_ENABLE_LTO)1762    if((UNIX OR MINGW) AND LINKER_IS_LLD)1763      if(LLVM_ENABLE_FATLTO AND NOT APPLE)1764        # When using FatLTO, just use relocatable linking.1765        set_property(TARGET ${target_name} APPEND_STRING PROPERTY1766                      LINK_FLAGS " -Wl,--no-fat-lto-objects")1767      else()1768        set_property(TARGET ${target_name} APPEND_STRING PROPERTY1769                      LINK_FLAGS " -Wl,--lto-O0")1770      endif()1771    elseif(LINKER_IS_LLD_LINK)1772      set_property(TARGET ${target_name} APPEND_STRING PROPERTY1773                    LINK_FLAGS " /opt:lldlto=0")1774    elseif(APPLE AND NOT uppercase_LLVM_ENABLE_LTO STREQUAL "THIN")1775      set_property(TARGET ${target_name} APPEND_STRING PROPERTY1776                    LINK_FLAGS " -Wl,-mllvm,-O0")1777    endif()1778  endif()1779 1780  target_link_options(${target_name} PRIVATE "${LLVM_UNITTEST_LINK_FLAGS}")1781endfunction(set_unittest_link_flags)1782 1783# Generic support for adding a unittest.1784function(add_unittest test_suite test_name)1785  if( NOT LLVM_BUILD_TESTS )1786    set(EXCLUDE_FROM_ALL ON)1787  endif()1788 1789  if (SUPPORTS_VARIADIC_MACROS_FLAG)1790    list(APPEND LLVM_COMPILE_FLAGS "-Wno-variadic-macros")1791  endif()1792  # Some parts of gtest rely on this GNU extension, don't warn on it.1793  if(SUPPORTS_GNU_ZERO_VARIADIC_MACRO_ARGUMENTS_FLAG)1794    list(APPEND LLVM_COMPILE_FLAGS "-Wno-gnu-zero-variadic-macro-arguments")1795  endif()1796 1797  if (NOT DEFINED LLVM_REQUIRES_RTTI)1798    set(LLVM_REQUIRES_RTTI OFF)1799  endif()1800 1801  list(APPEND LLVM_LINK_COMPONENTS Support) # gtest needs it for raw_ostream1802  add_llvm_executable(${test_name} IGNORE_EXTERNALIZE_DEBUGINFO NO_INSTALL_RPATH ${ARGN})1803  get_subproject_title(subproject_title)1804  set_target_properties(${test_name} PROPERTIES FOLDER "${subproject_title}/Tests/Unit")1805 1806  set_unittest_link_flags(${test_name})1807 1808  set(outdir ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR})1809  set_output_directory(${test_name} BINARY_DIR ${outdir} LIBRARY_DIR ${outdir})1810  # libpthreads overrides some standard library symbols, so main1811  # executable must be linked with it in order to provide consistent1812  # API for all shared libaries loaded by this executable.1813  # default_gtest should be an alias to either llvm_gtest or runtimes_gtest.1814  # If it is not defined, fall back to llvm_gtest.1815  if(TARGET default_gtest)1816    target_link_libraries(${test_name} PRIVATE default_gtest_main default_gtest ${LLVM_PTHREAD_LIB})1817  else ()1818    target_link_libraries(${test_name} PRIVATE llvm_gtest_main llvm_gtest ${LLVM_PTHREAD_LIB})1819  endif ()1820 1821  add_dependencies(${test_suite} ${test_name})1822endfunction()1823 1824# Use for test binaries that call llvm::getInputFileDirectory(). Use of this1825# is discouraged.1826function(add_unittest_with_input_files test_suite test_name)1827  set(LLVM_UNITTEST_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})1828  configure_file(1829    ${LLVM_MAIN_SRC_DIR}/unittests/unittest.cfg.in1830    ${CMAKE_CURRENT_BINARY_DIR}/llvm.srcdir.txt)1831 1832  add_unittest(${test_suite} ${test_name} ${ARGN})1833endfunction()1834 1835# Generic support for adding a benchmark.1836function(add_benchmark benchmark_name)1837  if( NOT LLVM_BUILD_BENCHMARKS )1838    set(EXCLUDE_FROM_ALL ON)1839  endif()1840 1841  add_llvm_executable(${benchmark_name} IGNORE_EXTERNALIZE_DEBUGINFO NO_INSTALL_RPATH ${ARGN})1842  set(outdir ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR})1843  set_output_directory(${benchmark_name} BINARY_DIR ${outdir} LIBRARY_DIR ${outdir})1844  get_subproject_title(subproject_title)1845  set_property(TARGET ${benchmark_name} PROPERTY FOLDER "${subproject_title}/Benchmarks")1846  target_link_libraries(${benchmark_name} PRIVATE benchmark)1847endfunction()1848 1849# This function canonicalize the CMake variables passed by names1850# from CMake boolean to 0/1 suitable for passing into Python or C++,1851# in place.1852function(llvm_canonicalize_cmake_booleans)1853  foreach(var ${ARGN})1854    if(${var})1855      set(${var} 1 PARENT_SCOPE)1856    else()1857      set(${var} 0 PARENT_SCOPE)1858    endif()1859  endforeach()1860endfunction(llvm_canonicalize_cmake_booleans)1861 1862macro(set_llvm_build_mode)1863  # Configuration-time: See Unit/lit.site.cfg.in1864  if (CMAKE_CFG_INTDIR STREQUAL ".")1865    set(LLVM_BUILD_MODE ".")1866  else ()1867    set(LLVM_BUILD_MODE "%(build_mode)s")1868  endif ()1869endmacro()1870 1871# Takes a list of path names in pathlist and a base directory, and returns1872# a list of paths relative to the base directory in out_pathlist.1873# Paths that are on a different drive than the basedir (on Windows) or that1874# contain symlinks are returned absolute.1875# Use with LLVM_LIT_PATH_FUNCTION below.1876function(make_paths_relative out_pathlist basedir pathlist)1877  # Passing ARG_PATH_VALUES as-is to execute_process() makes cmake strip1878  # empty list entries. So escape the ;s in the list and do the splitting1879  # ourselves. cmake has no relpath function, so use Python for that.1880  string(REPLACE ";" "\\;" pathlist_escaped "${pathlist}")1881  execute_process(COMMAND "${Python3_EXECUTABLE}" "-c" "\n1882import os, sys\n1883base = sys.argv[1]1884def haslink(p):\n1885    if not p or p == os.path.dirname(p): return False\n1886    return os.path.islink(p) or haslink(os.path.dirname(p))\n1887def relpath(p):\n1888    if not p: return ''\n1889    if os.path.splitdrive(p)[0] != os.path.splitdrive(base)[0]: return p\n1890    if haslink(p) or haslink(base): return p\n1891    return os.path.relpath(p, base)\n1892if len(sys.argv) < 3: sys.exit(0)\n1893sys.stdout.write(';'.join(relpath(p) for p in sys.argv[2].split(';')))"1894    ${basedir}1895    ${pathlist_escaped}1896    OUTPUT_VARIABLE pathlist_relative1897    ERROR_VARIABLE error1898    RESULT_VARIABLE result)1899  if (NOT result EQUAL 0)1900    message(FATAL_ERROR "make_paths_relative() failed due to error '${result}', with stderr\n${error}")1901  endif()1902  set(${out_pathlist} "${pathlist_relative}" PARENT_SCOPE)1903endfunction()1904 1905# Converts a file that's relative to the current python file to an absolute1906# path. Since this uses __file__, it has to be emitted into python files that1907# use it and can't be in a lit module. Use with make_paths_relative().1908string(CONCAT LLVM_LIT_PATH_FUNCTION1909  "# Allow generated file to be relocatable.\n"1910  "import os\n"1911  "import platform\n"1912  "def path(p):\n"1913  "    if not p: return ''\n"1914  "    # Follows lit.util.abs_path_preserve_drive, which cannot be imported here.\n"1915  "    if platform.system() == 'Windows':\n"1916  "        return os.path.abspath(os.path.join(os.path.dirname(__file__), p))\n"1917  "    else:\n"1918  "        return os.path.realpath(os.path.join(os.path.dirname(__file__), p))\n"1919  )1920 1921# This function provides an automatic way to 'configure'-like generate a file1922# based on a set of common and custom variables, specifically targeting the1923# variables needed for the 'lit.site.cfg' files. This function bundles the1924# common variables that any Lit instance is likely to need, and custom1925# variables can be passed in.1926# The keyword PATHS is followed by a list of cmake variable names that are1927# mentioned as `path("@varname@")` in the lit.cfg.py.in file. Variables in that1928# list are treated as paths that are relative to the directory the generated1929# lit.cfg.py file is in, and the `path()` function converts the relative1930# path back to absolute form. This makes it possible to move a build directory1931# containing lit.cfg.py files from one machine to another.1932function(configure_lit_site_cfg site_in site_out)1933  cmake_parse_arguments(ARG "" "" "MAIN_CONFIG;PATHS" ${ARGN})1934 1935  if ("${ARG_MAIN_CONFIG}" STREQUAL "")1936    get_filename_component(INPUT_DIR ${site_in} DIRECTORY)1937    set(ARG_MAIN_CONFIG "${INPUT_DIR}/lit.cfg")1938  endif()1939 1940  foreach(c ${LLVM_TARGETS_TO_BUILD})1941    set(TARGETS_BUILT "${TARGETS_BUILT} ${c}")1942  endforeach(c)1943  set(TARGETS_TO_BUILD ${TARGETS_BUILT})1944 1945  set(SHLIBEXT "${LTDL_SHLIB_EXT}")1946 1947  set_llvm_build_mode()1948 1949  # For standalone builds of subprojects, these might not be the build tree but1950  # a provided binary tree.1951  set(LLVM_SOURCE_DIR ${LLVM_MAIN_SRC_DIR})1952  set(LLVM_BINARY_DIR ${LLVM_BINARY_DIR})1953  string(REPLACE "${CMAKE_CFG_INTDIR}" "${LLVM_BUILD_MODE}" LLVM_TOOLS_DIR "${LLVM_TOOLS_BINARY_DIR}")1954  string(REPLACE "${CMAKE_CFG_INTDIR}" "${LLVM_BUILD_MODE}" LLVM_LIBS_DIR  "${LLVM_LIBRARY_DIR}")1955  # Like LLVM_{TOOLS,LIBS}_DIR, but pointing at the build tree.1956  string(REPLACE "${CMAKE_CFG_INTDIR}" "${LLVM_BUILD_MODE}" CURRENT_TOOLS_DIR "${LLVM_RUNTIME_OUTPUT_INTDIR}")1957  string(REPLACE "${CMAKE_CFG_INTDIR}" "${LLVM_BUILD_MODE}" CURRENT_LIBS_DIR  "${LLVM_LIBRARY_OUTPUT_INTDIR}")1958  string(REPLACE "${CMAKE_CFG_INTDIR}" "${LLVM_BUILD_MODE}" SHLIBDIR "${LLVM_SHLIB_OUTPUT_INTDIR}")1959 1960  # FIXME: "ENABLE_SHARED" doesn't make sense, since it is used just for1961  # plugins. We may rename it.1962  if(LLVM_ENABLE_PLUGINS)1963    set(ENABLE_SHARED "1")1964  else()1965    set(ENABLE_SHARED "0")1966  endif()1967 1968  if(LLVM_ENABLE_ASSERTIONS)1969    set(ENABLE_ASSERTIONS "1")1970  else()1971    set(ENABLE_ASSERTIONS "0")1972  endif()1973 1974  set(HOST_OS ${CMAKE_SYSTEM_NAME})1975  set(HOST_ARCH ${CMAKE_SYSTEM_PROCESSOR})1976 1977  set(HOST_CC "${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1}")1978  set(HOST_CXX "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1}")1979  set(HOST_LDFLAGS "${CMAKE_EXE_LINKER_FLAGS}")1980 1981  string(CONCAT LIT_SITE_CFG_IN_HEADER1982    "# Autogenerated from ${site_in}\n# Do not edit!\n\n"1983    "${LLVM_LIT_PATH_FUNCTION}"1984    )1985 1986  # Override config_target_triple (and the env)1987  if(LLVM_TARGET_TRIPLE_ENV)1988    # This is expanded into the heading.1989    string(CONCAT LIT_SITE_CFG_IN_HEADER "${LIT_SITE_CFG_IN_HEADER}"1990      "import os\n"1991      "target_env = \"${LLVM_TARGET_TRIPLE_ENV}\"\n"1992      "config.target_triple = config.environment[target_env] = os.environ.get(target_env, \"${LLVM_TARGET_TRIPLE}\")\n"1993      )1994 1995    # This is expanded to; config.target_triple = ""+config.target_triple+""1996    set(LLVM_TARGET_TRIPLE "\"+config.target_triple+\"")1997  endif()1998 1999  if (ARG_PATHS)2000    # Walk ARG_PATHS and collect the current value of the variables in there.2001    # list(APPEND) ignores empty elements exactly if the list is empty,2002    # so start the list with a dummy element and drop it, to make sure that2003    # even empty values make it into the values list.2004    set(ARG_PATH_VALUES "dummy")2005    foreach(path ${ARG_PATHS})2006      list(APPEND ARG_PATH_VALUES "${${path}}")2007    endforeach()2008    list(REMOVE_AT ARG_PATH_VALUES 0)2009 2010    get_filename_component(OUTPUT_DIR ${site_out} DIRECTORY)2011    make_paths_relative(2012        ARG_PATH_VALUES_RELATIVE "${OUTPUT_DIR}" "${ARG_PATH_VALUES}")2013 2014    list(LENGTH ARG_PATHS len_paths)2015    list(LENGTH ARG_PATH_VALUES len_path_values)2016    list(LENGTH ARG_PATH_VALUES_RELATIVE len_path_value_rels)2017    if ((NOT ${len_paths} EQUAL ${len_path_values}) OR2018        (NOT ${len_paths} EQUAL ${len_path_value_rels}))2019      message(SEND_ERROR "PATHS lengths got confused")2020    endif()2021 2022    # Transform variables mentioned in ARG_PATHS to relative paths for2023    # the configure_file() call. Variables are copied to subscopeds by cmake,2024    # so this only modifies the local copy of the variables.2025    math(EXPR arg_path_limit "${len_paths} - 1")2026    foreach(i RANGE ${arg_path_limit})2027      list(GET ARG_PATHS ${i} val1)2028      list(GET ARG_PATH_VALUES_RELATIVE ${i} val2)2029      set(${val1} ${val2})2030    endforeach()2031  endif()2032 2033  configure_file(${site_in} ${site_out} @ONLY)2034 2035  if (EXISTS "${ARG_MAIN_CONFIG}")2036    # Remember main config / generated site config for llvm-lit.in.2037    get_property(LLVM_LIT_CONFIG_FILES GLOBAL PROPERTY LLVM_LIT_CONFIG_FILES)2038    list(APPEND LLVM_LIT_CONFIG_FILES "${ARG_MAIN_CONFIG}" "${site_out}")2039    set_property(GLOBAL PROPERTY LLVM_LIT_CONFIG_FILES ${LLVM_LIT_CONFIG_FILES})2040  endif()2041endfunction()2042 2043function(dump_all_cmake_variables)2044  get_cmake_property(_variableNames VARIABLES)2045  foreach (_variableName ${_variableNames})2046    message(STATUS "${_variableName}=${${_variableName}}")2047  endforeach()2048endfunction()2049 2050function(get_llvm_lit_path base_dir file_name)2051  cmake_parse_arguments(ARG "ALLOW_EXTERNAL" "" "" ${ARGN})2052 2053  if (ARG_ALLOW_EXTERNAL)2054    set (LLVM_EXTERNAL_LIT "" CACHE STRING "Command used to spawn lit")2055    if ("${LLVM_EXTERNAL_LIT}" STREQUAL "")2056      set(LLVM_EXTERNAL_LIT "${LLVM_DEFAULT_EXTERNAL_LIT}")2057    endif()2058 2059    if (NOT "${LLVM_EXTERNAL_LIT}" STREQUAL "")2060      if (EXISTS ${LLVM_EXTERNAL_LIT})2061        get_filename_component(LIT_FILE_NAME ${LLVM_EXTERNAL_LIT} NAME)2062        get_filename_component(LIT_BASE_DIR ${LLVM_EXTERNAL_LIT} DIRECTORY)2063        set(${file_name} ${LIT_FILE_NAME} PARENT_SCOPE)2064        set(${base_dir} ${LIT_BASE_DIR} PARENT_SCOPE)2065        return()2066      elseif (NOT DEFINED CACHE{LLVM_EXTERNAL_LIT_MISSING_WARNED_ONCE})2067        message(WARNING "LLVM_EXTERNAL_LIT set to ${LLVM_EXTERNAL_LIT}, but the path does not exist.")2068        set(LLVM_EXTERNAL_LIT_MISSING_WARNED_ONCE YES CACHE INTERNAL "")2069      endif()2070    endif()2071  endif()2072 2073  set(lit_file_name "llvm-lit")2074  if (CMAKE_HOST_WIN32 AND NOT CYGWIN)2075    # llvm-lit needs suffix.py for multiprocess to find a main module.2076    set(lit_file_name "${lit_file_name}.py")2077  endif ()2078  set(${file_name} ${lit_file_name} PARENT_SCOPE)2079 2080  get_property(LLVM_LIT_BASE_DIR GLOBAL PROPERTY LLVM_LIT_BASE_DIR)2081  if (NOT "${LLVM_LIT_BASE_DIR}" STREQUAL "")2082    set(${base_dir} ${LLVM_LIT_BASE_DIR} PARENT_SCOPE)2083  endif()2084 2085  # Allow individual projects to provide an override2086  if (NOT "${LLVM_LIT_OUTPUT_DIR}" STREQUAL "")2087    set(LLVM_LIT_BASE_DIR ${LLVM_LIT_OUTPUT_DIR})2088  elseif(NOT "${LLVM_RUNTIME_OUTPUT_INTDIR}" STREQUAL "")2089    set(LLVM_LIT_BASE_DIR ${LLVM_RUNTIME_OUTPUT_INTDIR})2090  else()2091    set(LLVM_LIT_BASE_DIR "")2092  endif()2093 2094  # Cache this so we don't have to do it again and have subsequent calls2095  # potentially disagree on the value.2096  set_property(GLOBAL PROPERTY LLVM_LIT_BASE_DIR ${LLVM_LIT_BASE_DIR})2097  set(${base_dir} ${LLVM_LIT_BASE_DIR} PARENT_SCOPE)2098endfunction()2099 2100# A raw function to create a lit target. This is used to implement the testuite2101# management functions.2102function(add_lit_target target comment)2103  cmake_parse_arguments(ARG "" "" "PARAMS;DEPENDS;ARGS" ${ARGN})2104  set(LIT_ARGS "${ARG_ARGS} ${LLVM_LIT_ARGS}")2105  separate_arguments(LIT_ARGS)2106  if (NOT CMAKE_CFG_INTDIR STREQUAL ".")2107    list(APPEND LIT_ARGS --param build_mode=${CMAKE_CFG_INTDIR})2108  endif ()2109 2110  # Get the path to the lit to *run* tests with.  This can be overriden by2111  # the user by specifying -DLLVM_EXTERNAL_LIT=<path-to-lit.py>2112  get_llvm_lit_path(2113    lit_base_dir2114    lit_file_name2115    ALLOW_EXTERNAL2116    )2117 2118  set(LIT_COMMAND "${Python3_EXECUTABLE};${lit_base_dir}/${lit_file_name}")2119  list(APPEND LIT_COMMAND ${LIT_ARGS})2120  foreach(param ${ARG_PARAMS})2121    list(APPEND LIT_COMMAND --param ${param})2122  endforeach()2123  if (ARG_UNPARSED_ARGUMENTS)2124    add_custom_target(${target}2125      COMMAND ${LIT_COMMAND} ${ARG_UNPARSED_ARGUMENTS}2126      COMMENT "${comment}"2127      USES_TERMINAL2128      )2129  else()2130    add_custom_target(${target}2131      COMMAND ${CMAKE_COMMAND} -E echo "${target} does nothing, no tools built.")2132    message(STATUS "${target} does nothing.")2133  endif()2134  get_subproject_title(subproject_title)2135  set_target_properties(${target} PROPERTIES FOLDER "${subproject_title}/Tests")2136 2137  if (ARG_DEPENDS)2138    add_dependencies(${target} ${ARG_DEPENDS})2139  endif()2140 2141  # Tests should be excluded from "Build Solution".2142  set_target_properties(${target} PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD ON)2143  set_target_properties(${target} PROPERTIES XCODE_GENERATE_SCHEME ON)2144endfunction()2145 2146# Convert a target name like check-clang to a variable name like CLANG.2147function(umbrella_lit_testsuite_var target outvar)2148  if (NOT target MATCHES "^check-")2149    message(FATAL_ERROR "umbrella lit suites must be check-*, not '${target}'")2150  endif()2151  string(SUBSTRING "${target}" 6 -1 var)2152  string(REPLACE "-" "_" var ${var})2153  string(TOUPPER "${var}" var)2154  set(${outvar} "${var}" PARENT_SCOPE)2155endfunction()2156 2157# Start recording all lit test suites for a combined 'check-foo' target.2158# The recording continues until umbrella_lit_testsuite_end() creates the target.2159function(umbrella_lit_testsuite_begin target)2160  umbrella_lit_testsuite_var(${target} name)2161  set_property(GLOBAL APPEND PROPERTY LLVM_LIT_UMBRELLAS ${name})2162endfunction()2163 2164# Create a combined 'check-foo' target for a set of related test suites.2165# It runs all suites added since the matching umbrella_lit_testsuite_end() call.2166# Tests marked EXCLUDE_FROM_CHECK_ALL are not gathered.2167function(umbrella_lit_testsuite_end target)2168  umbrella_lit_testsuite_var(${target} name)2169 2170  get_property(testsuites GLOBAL PROPERTY LLVM_${name}_LIT_TESTSUITES)2171  get_property(params GLOBAL PROPERTY LLVM_${name}_LIT_PARAMS)2172  get_property(depends GLOBAL PROPERTY LLVM_${name}_LIT_DEPENDS)2173  get_property(extra_args GLOBAL PROPERTY LLVM_${name}_LIT_EXTRA_ARGS)2174  # Additional test targets are not gathered, but may be set externally.2175  get_property(additional_test_targets2176               GLOBAL PROPERTY LLVM_${name}_ADDITIONAL_TEST_TARGETS)2177 2178  string(TOLOWER ${name} name)2179  add_lit_target(${target}2180    "Running ${name} regression tests"2181    ${testsuites}2182    PARAMS ${params}2183    DEPENDS ${depends} ${additional_test_targets}2184    ARGS ${extra_args}2185    )2186endfunction()2187 2188# A function to add a set of lit test suites to be driven through 'check-*' targets.2189function(add_lit_testsuite target comment)2190  cmake_parse_arguments(ARG "EXCLUDE_FROM_CHECK_ALL" "" "PARAMS;DEPENDS;ARGS" ${ARGN})2191 2192  # EXCLUDE_FROM_ALL excludes the test ${target} out of check-all.2193  if(NOT ARG_EXCLUDE_FROM_CHECK_ALL)2194    get_property(gather_names GLOBAL PROPERTY LLVM_LIT_UMBRELLAS)2195    foreach(name ${gather_names})2196    # Register the testsuites, params and depends for the umbrella check rule.2197      set_property(GLOBAL APPEND PROPERTY LLVM_${name}_LIT_TESTSUITES ${ARG_UNPARSED_ARGUMENTS})2198      set_property(GLOBAL APPEND PROPERTY LLVM_${name}_LIT_PARAMS ${ARG_PARAMS})2199      set_property(GLOBAL APPEND PROPERTY LLVM_${name}_LIT_DEPENDS ${ARG_DEPENDS})2200      set_property(GLOBAL APPEND PROPERTY LLVM_${name}_LIT_EXTRA_ARGS ${ARG_ARGS})2201    endforeach()2202  endif()2203 2204  # Produce a specific suffixed check rule.2205  add_lit_target(${target} ${comment}2206    ${ARG_UNPARSED_ARGUMENTS}2207    PARAMS ${ARG_PARAMS}2208    DEPENDS ${ARG_DEPENDS}2209    ARGS ${ARG_ARGS}2210    )2211endfunction()2212 2213function(add_lit_testsuites project directory)2214  if (NOT LLVM_ENABLE_IDE)2215    cmake_parse_arguments(ARG2216      "EXCLUDE_FROM_CHECK_ALL"2217      "FOLDER;BINARY_DIR"2218      "PARAMS;DEPENDS;ARGS;SKIP"2219      ${ARGN}2220      )2221 2222    if (NOT ARG_FOLDER)2223      get_subproject_title(subproject_title)2224      set(ARG_FOLDER "${subproject_title}/Tests/LIT Testsuites")2225    endif()2226 2227    # Search recursively for test directories by assuming anything not2228    # in a directory called Inputs contains tests.2229    file(GLOB_RECURSE to_process LIST_DIRECTORIES true ${directory}/*)2230    foreach(lit_suite ${to_process})2231      if(NOT IS_DIRECTORY ${lit_suite})2232        continue()2233      endif()2234      string(FIND ${lit_suite} Inputs is_inputs)2235      string(FIND ${lit_suite} Output is_output)2236      if (NOT (is_inputs EQUAL -1 AND is_output EQUAL -1))2237        continue()2238      endif()2239 2240      # Create a check- target for the directory.2241      string(REPLACE "${directory}/" "" name_slash ${lit_suite})2242      set(_should_skip FALSE)2243      foreach(skip IN LISTS ARG_SKIP)2244        if(name_slash MATCHES "${skip}")2245          set(_should_skip TRUE)2246          break()2247        endif()2248      endforeach()2249      if (_should_skip)2250        continue()2251      endif()2252      if (name_slash)2253        set(filter ${name_slash})2254        string(REPLACE "/" "-" name_slash ${name_slash})2255        string(REPLACE "\\" "-" name_dashes ${name_slash})2256        string(TOLOWER "${project}-${name_dashes}" name_var)2257        set(lit_args ${lit_suite})2258        if (ARG_BINARY_DIR)2259          set(lit_args ${ARG_BINARY_DIR} --filter=${filter})2260        endif()2261        add_lit_target("check-${name_var}" "Running lit suite ${lit_suite}"2262          ${lit_args}2263          ${EXCLUDE_FROM_CHECK_ALL}2264          PARAMS ${ARG_PARAMS}2265          DEPENDS ${ARG_DEPENDS}2266          ARGS ${ARG_ARGS}2267        )2268        set_target_properties(check-${name_var} PROPERTIES FOLDER ${ARG_FOLDER})2269      endif()2270    endforeach()2271  endif()2272endfunction()2273 2274function(llvm_install_library_symlink name dest type)2275  cmake_parse_arguments(ARG "FULL_DEST" "COMPONENT" "" ${ARGN})2276  foreach(path ${CMAKE_MODULE_PATH})2277    if(EXISTS ${path}/LLVMInstallSymlink.cmake)2278      set(INSTALL_SYMLINK ${path}/LLVMInstallSymlink.cmake)2279      break()2280    endif()2281  endforeach()2282 2283  set(component ${ARG_COMPONENT})2284  if(NOT component)2285    set(component ${name})2286  endif()2287 2288  set(full_name ${CMAKE_${type}_LIBRARY_PREFIX}${name}${CMAKE_${type}_LIBRARY_SUFFIX})2289  if (ARG_FULL_DEST)2290    set(full_dest ${dest})2291  else()2292    set(full_dest ${CMAKE_${type}_LIBRARY_PREFIX}${dest}${CMAKE_${type}_LIBRARY_SUFFIX})2293  endif()2294 2295  if(LLVM_USE_SYMLINKS)2296    set(LLVM_LINK_OR_COPY create_symlink)2297  else()2298    set(LLVM_LINK_OR_COPY copy)2299  endif()2300 2301  set(output_dir lib${LLVM_LIBDIR_SUFFIX})2302  if((WIN32 OR CYGWIN) AND "${type}" STREQUAL "SHARED")2303    set(output_dir "${CMAKE_INSTALL_BINDIR}")2304  endif()2305 2306  install(SCRIPT ${INSTALL_SYMLINK}2307          CODE "install_symlink(\"${full_name}\" \"${full_dest}\" \"${output_dir}\" \"${LLVM_LINK_OR_COPY}\")"2308          COMPONENT ${component})2309 2310endfunction()2311 2312function(llvm_install_symlink project name dest)2313  get_property(LLVM_DRIVER_TOOLS GLOBAL PROPERTY LLVM_DRIVER_TOOLS)2314  if(LLVM_TOOL_LLVM_DRIVER_BUILD2315     AND ${dest} IN_LIST LLVM_DRIVER_TOOLS2316     AND (NOT LLVM_DISTRIBUTION_COMPONENTS OR ${dest} IN_LIST LLVM_DISTRIBUTION_COMPONENTS)2317    )2318    return()2319  endif()2320  cmake_parse_arguments(ARG "ALWAYS_GENERATE" "COMPONENT" "" ${ARGN})2321  foreach(path ${CMAKE_MODULE_PATH})2322    if(EXISTS ${path}/LLVMInstallSymlink.cmake)2323      set(INSTALL_SYMLINK ${path}/LLVMInstallSymlink.cmake)2324      break()2325    endif()2326  endforeach()2327 2328  if(ARG_COMPONENT)2329    set(component ${ARG_COMPONENT})2330  else()2331    if(ARG_ALWAYS_GENERATE)2332      set(component ${dest})2333    else()2334      set(component ${name})2335    endif()2336  endif()2337 2338  set(full_name ${name}${CMAKE_EXECUTABLE_SUFFIX})2339  set(full_dest ${dest}${CMAKE_EXECUTABLE_SUFFIX})2340  if (${dest} STREQUAL "llvm-driver")2341    set(full_dest llvm${CMAKE_EXECUTABLE_SUFFIX})2342  endif()2343 2344  if(LLVM_USE_SYMLINKS)2345    set(LLVM_LINK_OR_COPY create_symlink)2346  else()2347    set(LLVM_LINK_OR_COPY copy)2348  endif()2349 2350  set(output_dir "${${project}_TOOLS_INSTALL_DIR}")2351 2352  install(SCRIPT ${INSTALL_SYMLINK}2353          CODE "install_symlink(\"${full_name}\" \"${full_dest}\" \"${output_dir}\" \"${LLVM_LINK_OR_COPY}\")"2354          COMPONENT ${component})2355 2356  if (NOT LLVM_ENABLE_IDE AND NOT ARG_ALWAYS_GENERATE)2357    add_llvm_install_targets(install-${name}2358                             DEPENDS ${name} ${dest}2359                             COMPONENT ${component}2360                             SYMLINK ${dest})2361  endif()2362endfunction()2363 2364function(llvm_add_tool_symlink project link_name target)2365  cmake_parse_arguments(ARG "ALWAYS_GENERATE" "OUTPUT_DIR" "" ${ARGN})2366 2367  get_property(LLVM_DRIVER_TOOLS GLOBAL PROPERTY LLVM_DRIVER_TOOLS)2368 2369  if (${target} IN_LIST LLVM_DRIVER_TOOLS)2370    set_property(GLOBAL APPEND PROPERTY LLVM_DRIVER_TOOL_ALIASES_${target} ${link_name})2371  endif()2372  set(dest_binary "$<TARGET_FILE:${target}>")2373 2374  # This got a bit gross... For multi-configuration generators the target2375  # properties return the resolved value of the string, not the build system2376  # expression. To reconstruct the platform-agnostic path we have to do some2377  # magic. First we grab one of the types, and a type-specific path. Then from2378  # the type-specific path we find the last occurrence of the type in the path,2379  # and replace it with CMAKE_CFG_INTDIR. This allows the build step to be type2380  # agnostic again.2381  if(NOT ARG_OUTPUT_DIR)2382    # If you're not overriding the OUTPUT_DIR, we can make the link relative in2383    # the same directory.2384    if(LLVM_USE_SYMLINKS)2385      set(dest_binary "$<TARGET_FILE_NAME:${target}>")2386    endif()2387    if(CMAKE_CONFIGURATION_TYPES)2388      list(GET CMAKE_CONFIGURATION_TYPES 0 first_type)2389      string(TOUPPER ${first_type} first_type_upper)2390      set(first_type_suffix _${first_type_upper})2391    endif()2392    get_target_property(target_type ${target} TYPE)2393    if(${target_type} STREQUAL "STATIC_LIBRARY")2394      get_target_property(ARG_OUTPUT_DIR ${target} ARCHIVE_OUTPUT_DIRECTORY${first_type_suffix})2395    elseif(UNIX AND ${target_type} STREQUAL "SHARED_LIBRARY")2396      get_target_property(ARG_OUTPUT_DIR ${target} LIBRARY_OUTPUT_DIRECTORY${first_type_suffix})2397    else()2398      get_target_property(ARG_OUTPUT_DIR ${target} RUNTIME_OUTPUT_DIRECTORY${first_type_suffix})2399    endif()2400    if(CMAKE_CONFIGURATION_TYPES)2401      string(FIND "${ARG_OUTPUT_DIR}" "/${first_type}/" type_start REVERSE)2402      string(SUBSTRING "${ARG_OUTPUT_DIR}" 0 ${type_start} path_prefix)2403      string(SUBSTRING "${ARG_OUTPUT_DIR}" ${type_start} -1 path_suffix)2404      string(REPLACE "/${first_type}/" "/${CMAKE_CFG_INTDIR}/"2405             path_suffix ${path_suffix})2406      set(ARG_OUTPUT_DIR ${path_prefix}${path_suffix})2407    endif()2408  endif()2409 2410  if(LLVM_USE_SYMLINKS)2411    set(LLVM_LINK_OR_COPY create_symlink)2412  else()2413    set(LLVM_LINK_OR_COPY copy)2414  endif()2415 2416  set(output_path "${ARG_OUTPUT_DIR}/${link_name}${CMAKE_EXECUTABLE_SUFFIX}")2417 2418  set(target_name ${link_name})2419  if(TARGET ${link_name})2420    set(target_name ${link_name}-link)2421  endif()2422 2423 2424  if(ARG_ALWAYS_GENERATE)2425    set_property(DIRECTORY APPEND PROPERTY2426      ADDITIONAL_MAKE_CLEAN_FILES ${dest_binary})2427    add_custom_command(TARGET ${target} POST_BUILD2428      COMMAND ${CMAKE_COMMAND} -E ${LLVM_LINK_OR_COPY} "${dest_binary}" "${output_path}")2429  else()2430    add_custom_command(OUTPUT ${output_path}2431                     COMMAND ${CMAKE_COMMAND} -E ${LLVM_LINK_OR_COPY} "${dest_binary}" "${output_path}"2432                     DEPENDS ${target})2433 2434    # TODO: Make use of generator expressions below once CMake 3.19 or higher is the minimum supported version.2435    set(should_build_all)2436    get_target_property(target_excluded_from_all ${target} EXCLUDE_FROM_ALL)2437    if (NOT target_excluded_from_all)2438      set(should_build_all ALL)2439    endif()2440    add_custom_target(${target_name} ${should_build_all} DEPENDS ${target} ${output_path})2441    get_subproject_title(subproject_title)2442    set_target_properties(${target_name} PROPERTIES FOLDER "${subproject_title}/Tools")2443 2444    # Make sure both the link and target are toolchain tools2445    if (${link_name} IN_LIST LLVM_TOOLCHAIN_TOOLS AND ${target} IN_LIST LLVM_TOOLCHAIN_TOOLS)2446      set(TOOL_IS_TOOLCHAIN ON)2447    endif()2448 2449    if ((TOOL_IS_TOOLCHAIN OR NOT LLVM_INSTALL_TOOLCHAIN_ONLY) AND LLVM_BUILD_TOOLS)2450      llvm_install_symlink("${project}" ${link_name} ${target})2451    endif()2452  endif()2453endfunction()2454 2455function(add_llvm_tool_symlink link_name target)2456  llvm_add_tool_symlink(LLVM ${ARGV})2457endfunction()2458 2459function(llvm_externalize_debuginfo name)2460  if(NOT LLVM_EXTERNALIZE_DEBUGINFO)2461    return()2462  endif()2463 2464  if(NOT LLVM_EXTERNALIZE_DEBUGINFO_SKIP_STRIP)2465    if(APPLE)2466      if(NOT CMAKE_STRIP)2467        set(CMAKE_STRIP xcrun strip)2468      endif()2469      set(strip_command COMMAND ${CMAKE_STRIP} -S -x $<TARGET_FILE:${name}>)2470    else()2471      set(strip_command COMMAND ${CMAKE_STRIP} -g -x $<TARGET_FILE:${name}>)2472    endif()2473  endif()2474 2475  if(APPLE)2476    if(LLVM_EXTERNALIZE_DEBUGINFO_EXTENSION)2477      set(file_ext ${LLVM_EXTERNALIZE_DEBUGINFO_EXTENSION})2478    else()2479      set(file_ext dSYM)2480    endif()2481 2482    set(output_name "$<TARGET_FILE_NAME:${name}>.${file_ext}")2483 2484    if(LLVM_EXTERNALIZE_DEBUGINFO_OUTPUT_DIR)2485      set(output_path "-o=${LLVM_EXTERNALIZE_DEBUGINFO_OUTPUT_DIR}/${output_name}")2486    else()2487      set(output_path "-o=${output_name}")2488    endif()2489 2490    if(CMAKE_CXX_FLAGS MATCHES "-flto"2491      OR CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE} MATCHES "-flto")2492 2493      set(lto_object ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${name}-lto.o)2494      set_property(TARGET ${name} APPEND_STRING PROPERTY2495        LINK_FLAGS " -Wl,-object_path_lto,${lto_object}")2496    endif()2497    if(NOT CMAKE_DSYMUTIL)2498      set(CMAKE_DSYMUTIL xcrun dsymutil)2499    endif()2500    add_custom_command(TARGET ${name} POST_BUILD2501      COMMAND ${CMAKE_DSYMUTIL} ${output_path} $<TARGET_FILE:${name}>2502      ${strip_command}2503      )2504  else()2505    add_custom_command(TARGET ${name} POST_BUILD2506      COMMAND ${CMAKE_OBJCOPY} --only-keep-debug $<TARGET_FILE:${name}> $<TARGET_FILE:${name}>.debug2507      ${strip_command} -R .gnu_debuglink2508      COMMAND ${CMAKE_OBJCOPY} --add-gnu-debuglink=$<TARGET_FILE:${name}>.debug $<TARGET_FILE:${name}>2509      )2510  endif()2511endfunction()2512 2513# Usage: llvm_codesign(name [FORCE] [ENTITLEMENTS file] [BUNDLE_PATH path])2514function(llvm_codesign name)2515  cmake_parse_arguments(ARG "FORCE" "ENTITLEMENTS;BUNDLE_PATH" "" ${ARGN})2516 2517  if(NOT LLVM_CODESIGNING_IDENTITY)2518    return()2519  endif()2520 2521  if(CMAKE_GENERATOR STREQUAL "Xcode")2522    set_target_properties(${name} PROPERTIES2523      XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY ${LLVM_CODESIGNING_IDENTITY}2524    )2525    if(DEFINED ARG_ENTITLEMENTS)2526      set_target_properties(${name} PROPERTIES2527        XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS ${ARG_ENTITLEMENTS}2528      )2529    endif()2530  elseif(APPLE AND CMAKE_HOST_SYSTEM_NAME MATCHES Darwin)2531    if(NOT CMAKE_CODESIGN)2532      set(CMAKE_CODESIGN xcrun codesign)2533    endif()2534    if(NOT CMAKE_CODESIGN_ALLOCATE)2535      execute_process(2536        COMMAND xcrun -f codesign_allocate2537        OUTPUT_STRIP_TRAILING_WHITESPACE2538        OUTPUT_VARIABLE CMAKE_CODESIGN_ALLOCATE2539      )2540    endif()2541    if(DEFINED ARG_ENTITLEMENTS)2542      set(pass_entitlements --entitlements ${ARG_ENTITLEMENTS})2543    endif()2544 2545    if (NOT ARG_BUNDLE_PATH)2546      set(ARG_BUNDLE_PATH $<TARGET_FILE:${name}>)2547    endif()2548 2549    # ld64 now always codesigns the binaries it creates. Apply the force arg2550    # unconditionally so that we can - for example - add entitlements to the2551    # targets that need it.2552    set(force_flag "-f")2553 2554    add_custom_command(2555      TARGET ${name} POST_BUILD2556      COMMAND ${CMAKE_COMMAND} -E2557              env CODESIGN_ALLOCATE=${CMAKE_CODESIGN_ALLOCATE}2558              ${CMAKE_CODESIGN} -s ${LLVM_CODESIGNING_IDENTITY}2559              ${pass_entitlements} ${force_flag} ${ARG_BUNDLE_PATH}2560    )2561  endif()2562endfunction()2563 2564function(llvm_setup_rpath name)2565  if(CMAKE_INSTALL_RPATH)2566    return()2567  endif()2568 2569  if(LLVM_INSTALL_PREFIX AND NOT (LLVM_INSTALL_PREFIX STREQUAL CMAKE_INSTALL_PREFIX))2570    set(extra_libdir ${LLVM_LIBRARY_DIR})2571  elseif(LLVM_BUILD_LIBRARY_DIR)2572    set(extra_libdir ${LLVM_LIBRARY_DIR})2573  endif()2574 2575  if (APPLE)2576    set(_install_name_dir INSTALL_NAME_DIR "@rpath")2577    set(_install_rpath "@loader_path/../lib${LLVM_LIBDIR_SUFFIX}" ${extra_libdir})2578  elseif("${CMAKE_SYSTEM_NAME}" MATCHES "AIX" AND BUILD_SHARED_LIBS)2579    # $ORIGIN is not interpreted at link time by aix ld.2580    # Since BUILD_SHARED_LIBS is only recommended for use by developers,2581    # hardcode the rpath to build/install lib dir first in this mode.2582    # FIXME: update this when there is better solution.2583    set(_install_rpath "${LLVM_LIBRARY_OUTPUT_INTDIR}" "${CMAKE_INSTALL_PREFIX}/lib${LLVM_LIBDIR_SUFFIX}" ${extra_libdir})2584  elseif(UNIX)2585    set(_build_rpath "\$ORIGIN/../lib${LLVM_LIBDIR_SUFFIX}" ${extra_libdir})2586    set(_install_rpath "\$ORIGIN/../lib${LLVM_LIBDIR_SUFFIX}")2587    if("${CMAKE_SYSTEM_NAME}" MATCHES "(FreeBSD|DragonFly)")2588      set_property(TARGET ${name} APPEND_STRING PROPERTY2589                   LINK_FLAGS " -Wl,-z,origin ")2590    endif()2591    if(LLVM_LINKER_IS_GNULD AND NOT ${LLVM_LIBRARY_OUTPUT_INTDIR} STREQUAL "")2592      # $ORIGIN is not interpreted at link time by ld.bfd2593      set_property(TARGET ${name} APPEND_STRING PROPERTY2594                   LINK_FLAGS " -Wl,-rpath-link,${LLVM_LIBRARY_OUTPUT_INTDIR} ")2595    endif()2596  else()2597    return()2598  endif()2599 2600  # Enable BUILD_WITH_INSTALL_RPATH unless CMAKE_BUILD_RPATH is set and not2601  # building for macOS or AIX, as those platforms seemingly require it.2602  # On AIX, the tool chain doesn't support modifying rpaths/libpaths for XCOFF2603  # on install at the moment, so BUILD_WITH_INSTALL_RPATH is required.2604  if("${CMAKE_BUILD_RPATH}" STREQUAL "")2605    if("${CMAKE_SYSTEM_NAME}" MATCHES "Darwin|AIX")2606      set_property(TARGET ${name} PROPERTY BUILD_WITH_INSTALL_RPATH ON)2607    else()2608      set_property(TARGET ${name} APPEND PROPERTY BUILD_RPATH "${_build_rpath}")2609    endif()2610  endif()2611 2612  set_target_properties(${name} PROPERTIES2613                        INSTALL_RPATH "${_install_rpath}"2614                        ${_install_name_dir})2615endfunction()2616 2617function(setup_dependency_debugging name)2618  if(NOT LLVM_DEPENDENCY_DEBUGGING)2619    return()2620  endif()2621 2622  if("intrinsics_gen" IN_LIST ARGN)2623    return()2624  endif()2625 2626  set(deny_attributes_inc "(deny file* (literal \"${LLVM_BINARY_DIR}/include/llvm/IR/Attributes.inc\"))")2627  set(deny_intrinsics_inc "(deny file* (literal \"${LLVM_BINARY_DIR}/include/llvm/IR/Intrinsics.inc\"))")2628 2629  set(sandbox_command "sandbox-exec -p '(version 1) (allow default) ${deny_attributes_inc} ${deny_intrinsics_inc}'")2630  set_target_properties(${name} PROPERTIES RULE_LAUNCH_COMPILE ${sandbox_command})2631endfunction()2632 2633# If the sources at the given `path` are under version control, set `out_var`2634# to the the path of a file which will be modified when the VCS revision2635# changes, attempting to create that file if it does not exist; if no such2636# file exists and one cannot be created, instead set `out_var` to the2637# empty string.2638#2639# If the sources are not under version control, do not define `out_var`.2640function(find_first_existing_vc_file path out_var)2641  if(NOT EXISTS "${path}")2642    return()2643  endif()2644  find_package(Git)2645  if(GIT_FOUND)2646    execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --git-dir2647      WORKING_DIRECTORY ${path}2648      RESULT_VARIABLE git_result2649      OUTPUT_VARIABLE git_output2650      ERROR_QUIET)2651    if(git_result EQUAL 0)2652      string(STRIP "${git_output}" git_output)2653      get_filename_component(git_dir ${git_output} ABSOLUTE BASE_DIR ${path})2654      # Some branchless cases (e.g. 'repo') may not yet have .git/logs/HEAD2655      if (NOT EXISTS "${git_dir}/logs/HEAD")2656        execute_process(COMMAND ${CMAKE_COMMAND} -E touch HEAD2657          WORKING_DIRECTORY "${git_dir}/logs"2658          RESULT_VARIABLE touch_head_result2659          ERROR_QUIET)2660        if (NOT touch_head_result EQUAL 0)2661          set(${out_var} "" PARENT_SCOPE)2662          return()2663        endif()2664      endif()2665      set(${out_var} "${git_dir}/logs/HEAD" PARENT_SCOPE)2666    endif()2667  endif()2668endfunction()2669 2670function(get_host_tool_path tool_name setting_name exe_var_name target_var_name)2671  set(${setting_name}_DEFAULT "")2672 2673  if(LLVM_NATIVE_TOOL_DIR)2674    if(EXISTS "${LLVM_NATIVE_TOOL_DIR}/${tool_name}${LLVM_HOST_EXECUTABLE_SUFFIX}")2675      set(${setting_name}_DEFAULT "${LLVM_NATIVE_TOOL_DIR}/${tool_name}${LLVM_HOST_EXECUTABLE_SUFFIX}")2676    endif()2677  endif()2678 2679  set(${setting_name} "${${setting_name}_DEFAULT}" CACHE2680    STRING "Host ${tool_name} executable. Saves building if cross-compiling.")2681 2682  if(${setting_name})2683    set(exe_name ${${setting_name}})2684    set(target_name "")2685  elseif(LLVM_USE_HOST_TOOLS)2686    get_native_tool_path(${tool_name} exe_name)2687    set(target_name host_${tool_name})2688  else()2689    set(exe_name $<TARGET_FILE:${tool_name}>)2690    set(target_name ${tool_name})2691  endif()2692  # Force setting the cache variable because they are only used for being2693  # global in scope. Using regular variables would require careful audit of the2694  # code with several parent scope set commands.2695  set(${exe_var_name} "${exe_name}" CACHE STRING "" FORCE)2696  set(${target_var_name} "${target_name}" CACHE STRING "" FORCE)2697endfunction()2698 2699function(setup_host_tool tool_name setting_name exe_var_name target_var_name)2700  get_host_tool_path(${tool_name} ${setting_name} ${exe_var_name} ${target_var_name})2701  # Set up a native tool build if necessary2702  if(LLVM_USE_HOST_TOOLS AND NOT ${setting_name})2703    build_native_tool(${tool_name} exe_name DEPENDS ${tool_name})2704    add_custom_target(${${target_var_name}} DEPENDS ${exe_name})2705    get_subproject_title(subproject_title)2706    set_target_properties(${${target_var_name}} PROPERTIES FOLDER "${subproject_title}/Native")2707  endif()2708endfunction()2709