xref: /netbsd-src/external/apache2/llvm/dist/llvm/cmake/modules/AddLLVM.cmake (revision 82d56013d7b633d116a93943de88e08335357a7c)
1*82d56013Sjoerginclude(LLVMDistributionSupport)
27330f729Sjoerginclude(LLVMProcessSources)
37330f729Sjoerginclude(LLVM-Config)
47330f729Sjoerginclude(DetermineGCCCompatible)
57330f729Sjoerg
67330f729Sjoergfunction(llvm_update_compile_flags name)
77330f729Sjoerg  get_property(sources TARGET ${name} PROPERTY SOURCES)
87330f729Sjoerg  if("${sources}" MATCHES "\\.c(;|$)")
97330f729Sjoerg    set(update_src_props ON)
107330f729Sjoerg  endif()
117330f729Sjoerg
127330f729Sjoerg  list(APPEND LLVM_COMPILE_CFLAGS " ${LLVM_COMPILE_FLAGS}")
137330f729Sjoerg
147330f729Sjoerg  # LLVM_REQUIRES_EH is an internal flag that individual targets can use to
157330f729Sjoerg  # force EH
167330f729Sjoerg  if(LLVM_REQUIRES_EH OR LLVM_ENABLE_EH)
177330f729Sjoerg    if(NOT (LLVM_REQUIRES_RTTI OR LLVM_ENABLE_RTTI))
187330f729Sjoerg      message(AUTHOR_WARNING "Exception handling requires RTTI. Enabling RTTI for ${name}")
197330f729Sjoerg      set(LLVM_REQUIRES_RTTI ON)
207330f729Sjoerg    endif()
217330f729Sjoerg    if(MSVC)
227330f729Sjoerg      list(APPEND LLVM_COMPILE_FLAGS "/EHsc")
237330f729Sjoerg    endif()
247330f729Sjoerg  else()
257330f729Sjoerg    if(LLVM_COMPILER_IS_GCC_COMPATIBLE)
267330f729Sjoerg      list(APPEND LLVM_COMPILE_FLAGS "-fno-exceptions")
277330f729Sjoerg      if(NOT LLVM_ENABLE_UNWIND_TABLES)
287330f729Sjoerg        list(APPEND LLVM_COMPILE_FLAGS "-fno-unwind-tables")
297330f729Sjoerg        list(APPEND LLVM_COMPILE_FLAGS "-fno-asynchronous-unwind-tables")
307330f729Sjoerg      endif()
317330f729Sjoerg    elseif(MSVC)
327330f729Sjoerg      list(APPEND LLVM_COMPILE_DEFINITIONS _HAS_EXCEPTIONS=0)
337330f729Sjoerg      list(APPEND LLVM_COMPILE_FLAGS "/EHs-c-")
347330f729Sjoerg    elseif (CMAKE_CXX_COMPILER_ID MATCHES "XL")
357330f729Sjoerg      list(APPEND LLVM_COMPILE_FLAGS "-qnoeh")
367330f729Sjoerg    endif()
377330f729Sjoerg  endif()
387330f729Sjoerg
397330f729Sjoerg  # LLVM_REQUIRES_RTTI is an internal flag that individual
407330f729Sjoerg  # targets can use to force RTTI
417330f729Sjoerg  set(LLVM_CONFIG_HAS_RTTI YES CACHE INTERNAL "")
427330f729Sjoerg  if(NOT (LLVM_REQUIRES_RTTI OR LLVM_ENABLE_RTTI))
437330f729Sjoerg    set(LLVM_CONFIG_HAS_RTTI NO CACHE INTERNAL "")
447330f729Sjoerg    list(APPEND LLVM_COMPILE_DEFINITIONS GTEST_HAS_RTTI=0)
457330f729Sjoerg    if (LLVM_COMPILER_IS_GCC_COMPATIBLE)
467330f729Sjoerg      list(APPEND LLVM_COMPILE_FLAGS "-fno-rtti")
477330f729Sjoerg    elseif (MSVC)
487330f729Sjoerg      list(APPEND LLVM_COMPILE_FLAGS "/GR-")
497330f729Sjoerg    elseif (CMAKE_CXX_COMPILER_ID MATCHES "XL")
507330f729Sjoerg      list(APPEND LLVM_COMPILE_FLAGS "-qnortti")
517330f729Sjoerg    endif ()
527330f729Sjoerg  elseif(MSVC)
537330f729Sjoerg    list(APPEND LLVM_COMPILE_FLAGS "/GR")
547330f729Sjoerg  endif()
557330f729Sjoerg
567330f729Sjoerg  # Assume that;
577330f729Sjoerg  #   - LLVM_COMPILE_FLAGS is list.
587330f729Sjoerg  #   - PROPERTY COMPILE_FLAGS is string.
597330f729Sjoerg  string(REPLACE ";" " " target_compile_flags " ${LLVM_COMPILE_FLAGS}")
607330f729Sjoerg  string(REPLACE ";" " " target_compile_cflags " ${LLVM_COMPILE_CFLAGS}")
617330f729Sjoerg
627330f729Sjoerg  if(update_src_props)
637330f729Sjoerg    foreach(fn ${sources})
647330f729Sjoerg      get_filename_component(suf ${fn} EXT)
657330f729Sjoerg      if("${suf}" STREQUAL ".cpp")
667330f729Sjoerg        set_property(SOURCE ${fn} APPEND_STRING PROPERTY
677330f729Sjoerg          COMPILE_FLAGS "${target_compile_flags}")
687330f729Sjoerg      endif()
697330f729Sjoerg      if("${suf}" STREQUAL ".c")
707330f729Sjoerg        set_property(SOURCE ${fn} APPEND_STRING PROPERTY
717330f729Sjoerg          COMPILE_FLAGS "${target_compile_cflags}")
727330f729Sjoerg      endif()
737330f729Sjoerg    endforeach()
747330f729Sjoerg  else()
757330f729Sjoerg    # Update target props, since all sources are C++.
767330f729Sjoerg    set_property(TARGET ${name} APPEND_STRING PROPERTY
777330f729Sjoerg      COMPILE_FLAGS "${target_compile_flags}")
787330f729Sjoerg  endif()
797330f729Sjoerg
807330f729Sjoerg  set_property(TARGET ${name} APPEND PROPERTY COMPILE_DEFINITIONS ${LLVM_COMPILE_DEFINITIONS})
817330f729Sjoergendfunction()
827330f729Sjoerg
837330f729Sjoergfunction(add_llvm_symbol_exports target_name export_file)
847330f729Sjoerg  if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
857330f729Sjoerg    set(native_export_file "${target_name}.exports")
867330f729Sjoerg    add_custom_command(OUTPUT ${native_export_file}
877330f729Sjoerg      COMMAND sed -e "s/^/_/" < ${export_file} > ${native_export_file}
887330f729Sjoerg      DEPENDS ${export_file}
897330f729Sjoerg      VERBATIM
907330f729Sjoerg      COMMENT "Creating export file for ${target_name}")
917330f729Sjoerg    set_property(TARGET ${target_name} APPEND_STRING PROPERTY
927330f729Sjoerg                 LINK_FLAGS " -Wl,-exported_symbols_list,\"${CMAKE_CURRENT_BINARY_DIR}/${native_export_file}\"")
937330f729Sjoerg  elseif(${CMAKE_SYSTEM_NAME} MATCHES "AIX")
94*82d56013Sjoerg    # FIXME: `-Wl,-bE:` bypasses whatever handling there is in the build
95*82d56013Sjoerg    # compiler driver to defer to the specified export list.
96*82d56013Sjoerg    set(native_export_file "${export_file}")
977330f729Sjoerg    set_property(TARGET ${target_name} APPEND_STRING PROPERTY
987330f729Sjoerg                 LINK_FLAGS " -Wl,-bE:${export_file}")
997330f729Sjoerg  elseif(LLVM_HAVE_LINK_VERSION_SCRIPT)
1007330f729Sjoerg    # Gold and BFD ld require a version script rather than a plain list.
1017330f729Sjoerg    set(native_export_file "${target_name}.exports")
1027330f729Sjoerg    # FIXME: Don't write the "local:" line on OpenBSD.
1037330f729Sjoerg    # in the export file, also add a linker script to version LLVM symbols (form: LLVM_N.M)
1047330f729Sjoerg    add_custom_command(OUTPUT ${native_export_file}
1057330f729Sjoerg      COMMAND echo "LLVM_${LLVM_VERSION_MAJOR} {" > ${native_export_file}
1067330f729Sjoerg      COMMAND grep -q "[[:alnum:]]" ${export_file} && echo "  global:" >> ${native_export_file} || :
1077330f729Sjoerg      COMMAND sed -e "s/$/;/" -e "s/^/    /" < ${export_file} >> ${native_export_file}
1087330f729Sjoerg      COMMAND echo "  local: *;" >> ${native_export_file}
1097330f729Sjoerg      COMMAND echo "};" >> ${native_export_file}
1107330f729Sjoerg      DEPENDS ${export_file}
1117330f729Sjoerg      VERBATIM
1127330f729Sjoerg      COMMENT "Creating export file for ${target_name}")
1137330f729Sjoerg    if (${LLVM_LINKER_IS_SOLARISLD})
1147330f729Sjoerg      set_property(TARGET ${target_name} APPEND_STRING PROPERTY
1157330f729Sjoerg                   LINK_FLAGS "  -Wl,-M,\"${CMAKE_CURRENT_BINARY_DIR}/${native_export_file}\"")
1167330f729Sjoerg    else()
1177330f729Sjoerg      set_property(TARGET ${target_name} APPEND_STRING PROPERTY
1187330f729Sjoerg                   LINK_FLAGS "  -Wl,--version-script,\"${CMAKE_CURRENT_BINARY_DIR}/${native_export_file}\"")
1197330f729Sjoerg    endif()
1207330f729Sjoerg  else()
1217330f729Sjoerg    set(native_export_file "${target_name}.def")
1227330f729Sjoerg
1237330f729Sjoerg    add_custom_command(OUTPUT ${native_export_file}
124*82d56013Sjoerg      COMMAND "${Python3_EXECUTABLE}" -c "import sys;print(''.join(['EXPORTS\\n']+sys.stdin.readlines(),))"
1257330f729Sjoerg        < ${export_file} > ${native_export_file}
1267330f729Sjoerg      DEPENDS ${export_file}
1277330f729Sjoerg      VERBATIM
1287330f729Sjoerg      COMMENT "Creating export file for ${target_name}")
1297330f729Sjoerg    set(export_file_linker_flag "${CMAKE_CURRENT_BINARY_DIR}/${native_export_file}")
1307330f729Sjoerg    if(MSVC)
1317330f729Sjoerg      set(export_file_linker_flag "/DEF:\"${export_file_linker_flag}\"")
1327330f729Sjoerg    endif()
1337330f729Sjoerg    set_property(TARGET ${target_name} APPEND_STRING PROPERTY
1347330f729Sjoerg                 LINK_FLAGS " ${export_file_linker_flag}")
1357330f729Sjoerg  endif()
1367330f729Sjoerg
1377330f729Sjoerg  add_custom_target(${target_name}_exports DEPENDS ${native_export_file})
1387330f729Sjoerg  set_target_properties(${target_name}_exports PROPERTIES FOLDER "Misc")
1397330f729Sjoerg
1407330f729Sjoerg  get_property(srcs TARGET ${target_name} PROPERTY SOURCES)
1417330f729Sjoerg  foreach(src ${srcs})
1427330f729Sjoerg    get_filename_component(extension ${src} EXT)
1437330f729Sjoerg    if(extension STREQUAL ".cpp")
1447330f729Sjoerg      set(first_source_file ${src})
1457330f729Sjoerg      break()
1467330f729Sjoerg    endif()
1477330f729Sjoerg  endforeach()
1487330f729Sjoerg
1497330f729Sjoerg  # Force re-linking when the exports file changes. Actually, it
1507330f729Sjoerg  # forces recompilation of the source file. The LINK_DEPENDS target
1517330f729Sjoerg  # property only works for makefile-based generators.
1527330f729Sjoerg  # FIXME: This is not safe because this will create the same target
1537330f729Sjoerg  # ${native_export_file} in several different file:
1547330f729Sjoerg  # - One where we emitted ${target_name}_exports
1557330f729Sjoerg  # - One where we emitted the build command for the following object.
1567330f729Sjoerg  # set_property(SOURCE ${first_source_file} APPEND PROPERTY
1577330f729Sjoerg  #   OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${native_export_file})
1587330f729Sjoerg
1597330f729Sjoerg  set_property(DIRECTORY APPEND
1607330f729Sjoerg    PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${native_export_file})
1617330f729Sjoerg
1627330f729Sjoerg  add_dependencies(${target_name} ${target_name}_exports)
1637330f729Sjoerg
1647330f729Sjoerg  # Add dependency to *_exports later -- CMake issue 14747
1657330f729Sjoerg  list(APPEND LLVM_COMMON_DEPENDS ${target_name}_exports)
1667330f729Sjoerg  set(LLVM_COMMON_DEPENDS ${LLVM_COMMON_DEPENDS} PARENT_SCOPE)
1677330f729Sjoergendfunction(add_llvm_symbol_exports)
1687330f729Sjoerg
169*82d56013Sjoergif (NOT DEFINED LLVM_LINKER_DETECTED)
1707330f729Sjoerg  if(APPLE)
1717330f729Sjoerg    execute_process(
1727330f729Sjoerg      COMMAND "${CMAKE_LINKER}" -v
1737330f729Sjoerg      ERROR_VARIABLE stderr
1747330f729Sjoerg      )
1757330f729Sjoerg    if("${stderr}" MATCHES "PROJECT:ld64")
176*82d56013Sjoerg      set(LLVM_LINKER_DETECTED YES CACHE INTERNAL "")
177*82d56013Sjoerg      set(LLVM_LINKER_IS_LD64 YES CACHE INTERNAL "")
1787330f729Sjoerg      message(STATUS "Linker detection: ld64")
1797330f729Sjoerg    else()
180*82d56013Sjoerg      set(LLVM_LINKER_DETECTED NO CACHE INTERNAL "")
1817330f729Sjoerg      message(STATUS "Linker detection: unknown")
1827330f729Sjoerg    endif()
1837330f729Sjoerg  elseif(NOT WIN32)
1847330f729Sjoerg    # Detect what linker we have here
1857330f729Sjoerg    if( LLVM_USE_LINKER )
1867330f729Sjoerg      set(command ${CMAKE_C_COMPILER} -fuse-ld=${LLVM_USE_LINKER} -Wl,--version)
1877330f729Sjoerg    else()
1887330f729Sjoerg      separate_arguments(flags UNIX_COMMAND "${CMAKE_EXE_LINKER_FLAGS}")
1897330f729Sjoerg      set(command ${CMAKE_C_COMPILER} ${flags} -Wl,--version)
1907330f729Sjoerg    endif()
1917330f729Sjoerg    execute_process(
1927330f729Sjoerg      COMMAND ${command}
1937330f729Sjoerg      OUTPUT_VARIABLE stdout
1947330f729Sjoerg      ERROR_VARIABLE stderr
1957330f729Sjoerg      )
1967330f729Sjoerg    if("${stdout}" MATCHES "GNU gold")
197*82d56013Sjoerg      set(LLVM_LINKER_DETECTED YES CACHE INTERNAL "")
198*82d56013Sjoerg      set(LLVM_LINKER_IS_GOLD YES CACHE INTERNAL "")
1997330f729Sjoerg      message(STATUS "Linker detection: GNU Gold")
2007330f729Sjoerg    elseif("${stdout}" MATCHES "^LLD")
201*82d56013Sjoerg      set(LLVM_LINKER_DETECTED YES CACHE INTERNAL "")
202*82d56013Sjoerg      set(LLVM_LINKER_IS_LLD YES CACHE INTERNAL "")
2037330f729Sjoerg      message(STATUS "Linker detection: LLD")
2047330f729Sjoerg    elseif("${stdout}" MATCHES "GNU ld")
205*82d56013Sjoerg      set(LLVM_LINKER_DETECTED YES CACHE INTERNAL "")
206*82d56013Sjoerg      set(LLVM_LINKER_IS_GNULD YES CACHE INTERNAL "")
2077330f729Sjoerg      message(STATUS "Linker detection: GNU ld")
2087330f729Sjoerg    elseif("${stderr}" MATCHES "Solaris Link Editors" OR
2097330f729Sjoerg           "${stdout}" MATCHES "Solaris Link Editors")
210*82d56013Sjoerg      set(LLVM_LINKER_DETECTED YES CACHE INTERNAL "")
211*82d56013Sjoerg      set(LLVM_LINKER_IS_SOLARISLD YES CACHE INTERNAL "")
2127330f729Sjoerg      message(STATUS "Linker detection: Solaris ld")
2137330f729Sjoerg    else()
214*82d56013Sjoerg      set(LLVM_LINKER_DETECTED NO CACHE INTERNAL "")
2157330f729Sjoerg      message(STATUS "Linker detection: unknown")
2167330f729Sjoerg    endif()
2177330f729Sjoerg  endif()
218*82d56013Sjoergendif()
2197330f729Sjoerg
2207330f729Sjoergfunction(add_link_opts target_name)
221*82d56013Sjoerg  get_llvm_distribution(${target_name} in_distribution in_distribution_var)
222*82d56013Sjoerg  if(NOT in_distribution)
223*82d56013Sjoerg    # Don't LTO optimize targets that aren't part of any distribution.
224*82d56013Sjoerg    if (LLVM_ENABLE_LTO)
225*82d56013Sjoerg      # We may consider avoiding LTO altogether by using -fembed-bitcode
226*82d56013Sjoerg      # and teaching the linker to select machine code from .o files, see
227*82d56013Sjoerg      # https://lists.llvm.org/pipermail/llvm-dev/2021-April/149843.html
228*82d56013Sjoerg      if((UNIX OR MINGW) AND LLVM_USE_LINKER STREQUAL "lld")
229*82d56013Sjoerg        set_property(TARGET ${target_name} APPEND_STRING PROPERTY
230*82d56013Sjoerg                      LINK_FLAGS " -Wl,--lto-O0")
231*82d56013Sjoerg      elseif(LINKER_IS_LLD_LINK)
232*82d56013Sjoerg        set_property(TARGET ${target_name} APPEND_STRING PROPERTY
233*82d56013Sjoerg                      LINK_FLAGS " /opt:lldlto=0")
234*82d56013Sjoerg      endif()
235*82d56013Sjoerg    endif()
236*82d56013Sjoerg  endif()
237*82d56013Sjoerg
2387330f729Sjoerg  # Don't use linker optimizations in debug builds since it slows down the
2397330f729Sjoerg  # linker in a context where the optimizations are not important.
2407330f729Sjoerg  if (NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG")
2417330f729Sjoerg
2427330f729Sjoerg    # Pass -O3 to the linker. This enabled different optimizations on different
2437330f729Sjoerg    # linkers.
244*82d56013Sjoerg    if(NOT (CMAKE_SYSTEM_NAME MATCHES "Darwin|SunOS|AIX|OS390" OR WIN32) AND in_distribution)
2457330f729Sjoerg      set_property(TARGET ${target_name} APPEND_STRING PROPERTY
2467330f729Sjoerg                   LINK_FLAGS " -Wl,-O3")
2477330f729Sjoerg    endif()
2487330f729Sjoerg
249*82d56013Sjoerg    if(NOT LLVM_NO_DEAD_STRIP)
2507330f729Sjoerg      if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
2517330f729Sjoerg        # ld64's implementation of -dead_strip breaks tools that use plugins.
2527330f729Sjoerg        set_property(TARGET ${target_name} APPEND_STRING PROPERTY
2537330f729Sjoerg                     LINK_FLAGS " -Wl,-dead_strip")
2547330f729Sjoerg      elseif(${CMAKE_SYSTEM_NAME} MATCHES "SunOS")
255*82d56013Sjoerg        # Support for ld -z discard-unused=sections was only added in
256*82d56013Sjoerg        # Solaris 11.4.
257*82d56013Sjoerg        include(LLVMCheckLinkerFlag)
258*82d56013Sjoerg        llvm_check_linker_flag(CXX "-Wl,-z,discard-unused=sections" LINKER_SUPPORTS_Z_DISCARD_UNUSED)
259*82d56013Sjoerg        if (LINKER_SUPPORTS_Z_DISCARD_UNUSED)
2607330f729Sjoerg          set_property(TARGET ${target_name} APPEND_STRING PROPERTY
261*82d56013Sjoerg                       LINK_FLAGS " -Wl,-z,discard-unused=sections")
262*82d56013Sjoerg        endif()
263*82d56013Sjoerg      elseif(NOT MSVC AND NOT CMAKE_SYSTEM_NAME MATCHES "OpenBSD|AIX|OS390")
264*82d56013Sjoerg        # TODO Revisit this later on z/OS.
2657330f729Sjoerg        set_property(TARGET ${target_name} APPEND_STRING PROPERTY
2667330f729Sjoerg                     LINK_FLAGS " -Wl,--gc-sections")
2677330f729Sjoerg      endif()
268*82d56013Sjoerg    else() #LLVM_NO_DEAD_STRIP
2697330f729Sjoerg      if(${CMAKE_SYSTEM_NAME} MATCHES "AIX")
2707330f729Sjoerg        set_property(TARGET ${target_name} APPEND_STRING PROPERTY
2717330f729Sjoerg                     LINK_FLAGS " -Wl,-bnogc")
2727330f729Sjoerg      endif()
2737330f729Sjoerg    endif()
2747330f729Sjoerg  endif()
275*82d56013Sjoerg
276*82d56013Sjoerg  if(ARG_SUPPORT_PLUGINS AND ${CMAKE_SYSTEM_NAME} MATCHES "AIX")
277*82d56013Sjoerg    set_property(TARGET ${target_name} APPEND_STRING PROPERTY
278*82d56013Sjoerg                 LINK_FLAGS " -Wl,-brtl")
279*82d56013Sjoerg  endif()
2807330f729Sjoergendfunction(add_link_opts)
2817330f729Sjoerg
2827330f729Sjoerg# Set each output directory according to ${CMAKE_CONFIGURATION_TYPES}.
2837330f729Sjoerg# Note: Don't set variables CMAKE_*_OUTPUT_DIRECTORY any more,
2847330f729Sjoerg# or a certain builder, for eaxample, msbuild.exe, would be confused.
2857330f729Sjoergfunction(set_output_directory target)
2867330f729Sjoerg  cmake_parse_arguments(ARG "" "BINARY_DIR;LIBRARY_DIR" "" ${ARGN})
2877330f729Sjoerg
2887330f729Sjoerg  # module_dir -- corresponding to LIBRARY_OUTPUT_DIRECTORY.
2897330f729Sjoerg  # It affects output of add_library(MODULE).
2907330f729Sjoerg  if(WIN32 OR CYGWIN)
2917330f729Sjoerg    # DLL platform
2927330f729Sjoerg    set(module_dir ${ARG_BINARY_DIR})
2937330f729Sjoerg  else()
2947330f729Sjoerg    set(module_dir ${ARG_LIBRARY_DIR})
2957330f729Sjoerg  endif()
2967330f729Sjoerg  if(NOT "${CMAKE_CFG_INTDIR}" STREQUAL ".")
2977330f729Sjoerg    foreach(build_mode ${CMAKE_CONFIGURATION_TYPES})
2987330f729Sjoerg      string(TOUPPER "${build_mode}" CONFIG_SUFFIX)
2997330f729Sjoerg      if(ARG_BINARY_DIR)
3007330f729Sjoerg        string(REPLACE ${CMAKE_CFG_INTDIR} ${build_mode} bi ${ARG_BINARY_DIR})
3017330f729Sjoerg        set_target_properties(${target} PROPERTIES "RUNTIME_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${bi})
3027330f729Sjoerg      endif()
3037330f729Sjoerg      if(ARG_LIBRARY_DIR)
3047330f729Sjoerg        string(REPLACE ${CMAKE_CFG_INTDIR} ${build_mode} li ${ARG_LIBRARY_DIR})
3057330f729Sjoerg        set_target_properties(${target} PROPERTIES "ARCHIVE_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${li})
3067330f729Sjoerg      endif()
3077330f729Sjoerg      if(module_dir)
3087330f729Sjoerg        string(REPLACE ${CMAKE_CFG_INTDIR} ${build_mode} mi ${module_dir})
3097330f729Sjoerg        set_target_properties(${target} PROPERTIES "LIBRARY_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${mi})
3107330f729Sjoerg      endif()
3117330f729Sjoerg    endforeach()
3127330f729Sjoerg  else()
3137330f729Sjoerg    if(ARG_BINARY_DIR)
3147330f729Sjoerg      set_target_properties(${target} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${ARG_BINARY_DIR})
3157330f729Sjoerg    endif()
3167330f729Sjoerg    if(ARG_LIBRARY_DIR)
3177330f729Sjoerg      set_target_properties(${target} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${ARG_LIBRARY_DIR})
3187330f729Sjoerg    endif()
3197330f729Sjoerg    if(module_dir)
3207330f729Sjoerg      set_target_properties(${target} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${module_dir})
3217330f729Sjoerg    endif()
3227330f729Sjoerg  endif()
3237330f729Sjoergendfunction()
3247330f729Sjoerg
3257330f729Sjoerg# If on Windows and building with MSVC, add the resource script containing the
3267330f729Sjoerg# VERSIONINFO data to the project.  This embeds version resource information
3277330f729Sjoerg# into the output .exe or .dll.
3287330f729Sjoerg# TODO: Enable for MinGW Windows builds too.
3297330f729Sjoerg#
3307330f729Sjoergfunction(add_windows_version_resource_file OUT_VAR)
3317330f729Sjoerg  set(sources ${ARGN})
3327330f729Sjoerg  if (MSVC AND CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
3337330f729Sjoerg    set(resource_file ${LLVM_SOURCE_DIR}/resources/windows_version_resource.rc)
3347330f729Sjoerg    if(EXISTS ${resource_file})
3357330f729Sjoerg      set(sources ${sources} ${resource_file})
3367330f729Sjoerg      source_group("Resource Files" ${resource_file})
3377330f729Sjoerg      set(windows_resource_file ${resource_file} PARENT_SCOPE)
3387330f729Sjoerg    endif()
3397330f729Sjoerg  endif(MSVC AND CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
3407330f729Sjoerg
3417330f729Sjoerg  set(${OUT_VAR} ${sources} PARENT_SCOPE)
3427330f729Sjoergendfunction(add_windows_version_resource_file)
3437330f729Sjoerg
3447330f729Sjoerg# set_windows_version_resource_properties(name resource_file...
3457330f729Sjoerg#   VERSION_MAJOR int
3467330f729Sjoerg#     Optional major version number (defaults to LLVM_VERSION_MAJOR)
3477330f729Sjoerg#   VERSION_MINOR int
3487330f729Sjoerg#     Optional minor version number (defaults to LLVM_VERSION_MINOR)
3497330f729Sjoerg#   VERSION_PATCHLEVEL int
3507330f729Sjoerg#     Optional patchlevel version number (defaults to LLVM_VERSION_PATCH)
3517330f729Sjoerg#   VERSION_STRING
3527330f729Sjoerg#     Optional version string (defaults to PACKAGE_VERSION)
3537330f729Sjoerg#   PRODUCT_NAME
3547330f729Sjoerg#     Optional product name string (defaults to "LLVM")
3557330f729Sjoerg#   )
3567330f729Sjoergfunction(set_windows_version_resource_properties name resource_file)
3577330f729Sjoerg  cmake_parse_arguments(ARG
3587330f729Sjoerg    ""
3597330f729Sjoerg    "VERSION_MAJOR;VERSION_MINOR;VERSION_PATCHLEVEL;VERSION_STRING;PRODUCT_NAME"
3607330f729Sjoerg    ""
3617330f729Sjoerg    ${ARGN})
3627330f729Sjoerg
3637330f729Sjoerg  if (NOT DEFINED ARG_VERSION_MAJOR)
3647330f729Sjoerg    set(ARG_VERSION_MAJOR ${LLVM_VERSION_MAJOR})
3657330f729Sjoerg  endif()
3667330f729Sjoerg
3677330f729Sjoerg  if (NOT DEFINED ARG_VERSION_MINOR)
3687330f729Sjoerg    set(ARG_VERSION_MINOR ${LLVM_VERSION_MINOR})
3697330f729Sjoerg  endif()
3707330f729Sjoerg
3717330f729Sjoerg  if (NOT DEFINED ARG_VERSION_PATCHLEVEL)
3727330f729Sjoerg    set(ARG_VERSION_PATCHLEVEL ${LLVM_VERSION_PATCH})
3737330f729Sjoerg  endif()
3747330f729Sjoerg
3757330f729Sjoerg  if (NOT DEFINED ARG_VERSION_STRING)
3767330f729Sjoerg    set(ARG_VERSION_STRING ${PACKAGE_VERSION})
3777330f729Sjoerg  endif()
3787330f729Sjoerg
3797330f729Sjoerg  if (NOT DEFINED ARG_PRODUCT_NAME)
3807330f729Sjoerg    set(ARG_PRODUCT_NAME "LLVM")
3817330f729Sjoerg  endif()
3827330f729Sjoerg
3837330f729Sjoerg  set_property(SOURCE ${resource_file}
3847330f729Sjoerg               PROPERTY COMPILE_FLAGS /nologo)
3857330f729Sjoerg  set_property(SOURCE ${resource_file}
3867330f729Sjoerg               PROPERTY COMPILE_DEFINITIONS
3877330f729Sjoerg               "RC_VERSION_FIELD_1=${ARG_VERSION_MAJOR}"
3887330f729Sjoerg               "RC_VERSION_FIELD_2=${ARG_VERSION_MINOR}"
3897330f729Sjoerg               "RC_VERSION_FIELD_3=${ARG_VERSION_PATCHLEVEL}"
3907330f729Sjoerg               "RC_VERSION_FIELD_4=0"
3917330f729Sjoerg               "RC_FILE_VERSION=\"${ARG_VERSION_STRING}\""
3927330f729Sjoerg               "RC_INTERNAL_NAME=\"${name}\""
3937330f729Sjoerg               "RC_PRODUCT_NAME=\"${ARG_PRODUCT_NAME}\""
3947330f729Sjoerg               "RC_PRODUCT_VERSION=\"${ARG_VERSION_STRING}\"")
3957330f729Sjoergendfunction(set_windows_version_resource_properties)
3967330f729Sjoerg
3977330f729Sjoerg# llvm_add_library(name sources...
3987330f729Sjoerg#   SHARED;STATIC
3997330f729Sjoerg#     STATIC by default w/o BUILD_SHARED_LIBS.
4007330f729Sjoerg#     SHARED by default w/  BUILD_SHARED_LIBS.
4017330f729Sjoerg#   OBJECT
4027330f729Sjoerg#     Also create an OBJECT library target. Default if STATIC && SHARED.
4037330f729Sjoerg#   MODULE
4047330f729Sjoerg#     Target ${name} might not be created on unsupported platforms.
4057330f729Sjoerg#     Check with "if(TARGET ${name})".
4067330f729Sjoerg#   DISABLE_LLVM_LINK_LLVM_DYLIB
4077330f729Sjoerg#     Do not link this library to libLLVM, even if
4087330f729Sjoerg#     LLVM_LINK_LLVM_DYLIB is enabled.
4097330f729Sjoerg#   OUTPUT_NAME name
4107330f729Sjoerg#     Corresponds to OUTPUT_NAME in target properties.
4117330f729Sjoerg#   DEPENDS targets...
4127330f729Sjoerg#     Same semantics as add_dependencies().
4137330f729Sjoerg#   LINK_COMPONENTS components...
4147330f729Sjoerg#     Same as the variable LLVM_LINK_COMPONENTS.
4157330f729Sjoerg#   LINK_LIBS lib_targets...
4167330f729Sjoerg#     Same semantics as target_link_libraries().
4177330f729Sjoerg#   ADDITIONAL_HEADERS
4187330f729Sjoerg#     May specify header files for IDE generators.
4197330f729Sjoerg#   SONAME
4207330f729Sjoerg#     Should set SONAME link flags and create symlinks
4217330f729Sjoerg#   NO_INSTALL_RPATH
4227330f729Sjoerg#     Suppress default RPATH settings in shared libraries.
4237330f729Sjoerg#   PLUGIN_TOOL
4247330f729Sjoerg#     The tool (i.e. cmake target) that this plugin will link against
425*82d56013Sjoerg#   COMPONENT_LIB
426*82d56013Sjoerg#      This is used to specify that this is a component library of
427*82d56013Sjoerg#      LLVM which means that the source resides in llvm/lib/ and it is a
428*82d56013Sjoerg#      candidate for inclusion into libLLVM.so.
4297330f729Sjoerg#   )
4307330f729Sjoergfunction(llvm_add_library name)
4317330f729Sjoerg  cmake_parse_arguments(ARG
432*82d56013Sjoerg    "MODULE;SHARED;STATIC;OBJECT;DISABLE_LLVM_LINK_LLVM_DYLIB;SONAME;NO_INSTALL_RPATH;COMPONENT_LIB"
4337330f729Sjoerg    "OUTPUT_NAME;PLUGIN_TOOL;ENTITLEMENTS;BUNDLE_PATH"
4347330f729Sjoerg    "ADDITIONAL_HEADERS;DEPENDS;LINK_COMPONENTS;LINK_LIBS;OBJLIBS"
4357330f729Sjoerg    ${ARGN})
4367330f729Sjoerg  list(APPEND LLVM_COMMON_DEPENDS ${ARG_DEPENDS})
4377330f729Sjoerg  if(ARG_ADDITIONAL_HEADERS)
4387330f729Sjoerg    # Pass through ADDITIONAL_HEADERS.
4397330f729Sjoerg    set(ARG_ADDITIONAL_HEADERS ADDITIONAL_HEADERS ${ARG_ADDITIONAL_HEADERS})
4407330f729Sjoerg  endif()
4417330f729Sjoerg  if(ARG_OBJLIBS)
4427330f729Sjoerg    set(ALL_FILES ${ARG_OBJLIBS})
4437330f729Sjoerg  else()
4447330f729Sjoerg    llvm_process_sources(ALL_FILES ${ARG_UNPARSED_ARGUMENTS} ${ARG_ADDITIONAL_HEADERS})
4457330f729Sjoerg  endif()
4467330f729Sjoerg
4477330f729Sjoerg  if(ARG_MODULE)
4487330f729Sjoerg    if(ARG_SHARED OR ARG_STATIC)
4497330f729Sjoerg      message(WARNING "MODULE with SHARED|STATIC doesn't make sense.")
4507330f729Sjoerg    endif()
4517330f729Sjoerg    # Plugins that link against a tool are allowed even when plugins in general are not
4527330f729Sjoerg    if(NOT LLVM_ENABLE_PLUGINS AND NOT (ARG_PLUGIN_TOOL AND LLVM_EXPORT_SYMBOLS_FOR_PLUGINS))
4537330f729Sjoerg      message(STATUS "${name} ignored -- Loadable modules not supported on this platform.")
4547330f729Sjoerg      return()
4557330f729Sjoerg    endif()
4567330f729Sjoerg  else()
4577330f729Sjoerg    if(ARG_PLUGIN_TOOL)
4587330f729Sjoerg      message(WARNING "PLUGIN_TOOL without MODULE doesn't make sense.")
4597330f729Sjoerg    endif()
4607330f729Sjoerg    if(BUILD_SHARED_LIBS AND NOT ARG_STATIC)
4617330f729Sjoerg      set(ARG_SHARED TRUE)
4627330f729Sjoerg    endif()
4637330f729Sjoerg    if(NOT ARG_SHARED)
4647330f729Sjoerg      set(ARG_STATIC TRUE)
4657330f729Sjoerg    endif()
4667330f729Sjoerg  endif()
4677330f729Sjoerg
4687330f729Sjoerg  # Generate objlib
4697330f729Sjoerg  if((ARG_SHARED AND ARG_STATIC) OR ARG_OBJECT)
4707330f729Sjoerg    # Generate an obj library for both targets.
4717330f729Sjoerg    set(obj_name "obj.${name}")
4727330f729Sjoerg    add_library(${obj_name} OBJECT EXCLUDE_FROM_ALL
4737330f729Sjoerg      ${ALL_FILES}
4747330f729Sjoerg      )
4757330f729Sjoerg    llvm_update_compile_flags(${obj_name})
4767330f729Sjoerg    if(CMAKE_GENERATOR STREQUAL "Xcode")
4777330f729Sjoerg      set(DUMMY_FILE ${CMAKE_CURRENT_BINARY_DIR}/Dummy.c)
4787330f729Sjoerg      file(WRITE ${DUMMY_FILE} "// This file intentionally empty\n")
4797330f729Sjoerg      set_property(SOURCE ${DUMMY_FILE} APPEND_STRING PROPERTY COMPILE_FLAGS "-Wno-empty-translation-unit")
4807330f729Sjoerg    endif()
4817330f729Sjoerg    set(ALL_FILES "$<TARGET_OBJECTS:${obj_name}>" ${DUMMY_FILE})
4827330f729Sjoerg
4837330f729Sjoerg    # Do add_dependencies(obj) later due to CMake issue 14747.
4847330f729Sjoerg    list(APPEND objlibs ${obj_name})
4857330f729Sjoerg
4867330f729Sjoerg    set_target_properties(${obj_name} PROPERTIES FOLDER "Object Libraries")
4877330f729Sjoerg    if(ARG_DEPENDS)
4887330f729Sjoerg      add_dependencies(${obj_name} ${ARG_DEPENDS})
4897330f729Sjoerg    endif()
490*82d56013Sjoerg    # Treat link libraries like PUBLIC dependencies.  LINK_LIBS might
491*82d56013Sjoerg    # result in generating header files.  Add a dependendency so that
492*82d56013Sjoerg    # the generated header is created before this object library.
493*82d56013Sjoerg    if(ARG_LINK_LIBS)
494*82d56013Sjoerg      cmake_parse_arguments(LINK_LIBS_ARG
495*82d56013Sjoerg        ""
496*82d56013Sjoerg        ""
497*82d56013Sjoerg        "PUBLIC;PRIVATE"
498*82d56013Sjoerg        ${ARG_LINK_LIBS})
499*82d56013Sjoerg      foreach(link_lib ${LINK_LIBS_ARG_PUBLIC})
500*82d56013Sjoerg        if(LLVM_PTHREAD_LIB)
501*82d56013Sjoerg          # Can't specify a dependence on -lpthread
502*82d56013Sjoerg          if(NOT ${link_lib} STREQUAL ${LLVM_PTHREAD_LIB})
503*82d56013Sjoerg            add_dependencies(${obj_name} ${link_lib})
504*82d56013Sjoerg          endif()
505*82d56013Sjoerg        else()
506*82d56013Sjoerg          add_dependencies(${obj_name} ${link_lib})
507*82d56013Sjoerg        endif()
508*82d56013Sjoerg      endforeach()
509*82d56013Sjoerg    endif()
5107330f729Sjoerg  endif()
5117330f729Sjoerg
5127330f729Sjoerg  if(ARG_SHARED AND ARG_STATIC)
5137330f729Sjoerg    # static
5147330f729Sjoerg    set(name_static "${name}_static")
5157330f729Sjoerg    if(ARG_OUTPUT_NAME)
5167330f729Sjoerg      set(output_name OUTPUT_NAME "${ARG_OUTPUT_NAME}")
5177330f729Sjoerg    endif()
5187330f729Sjoerg    # DEPENDS has been appended to LLVM_COMMON_LIBS.
5197330f729Sjoerg    llvm_add_library(${name_static} STATIC
5207330f729Sjoerg      ${output_name}
5217330f729Sjoerg      OBJLIBS ${ALL_FILES} # objlib
5227330f729Sjoerg      LINK_LIBS ${ARG_LINK_LIBS}
5237330f729Sjoerg      LINK_COMPONENTS ${ARG_LINK_COMPONENTS}
5247330f729Sjoerg      )
5257330f729Sjoerg    # FIXME: Add name_static to anywhere in TARGET ${name}'s PROPERTY.
5267330f729Sjoerg    set(ARG_STATIC)
5277330f729Sjoerg  endif()
5287330f729Sjoerg
5297330f729Sjoerg  if(ARG_MODULE)
5307330f729Sjoerg    add_library(${name} MODULE ${ALL_FILES})
5317330f729Sjoerg  elseif(ARG_SHARED)
5327330f729Sjoerg    add_windows_version_resource_file(ALL_FILES ${ALL_FILES})
5337330f729Sjoerg    add_library(${name} SHARED ${ALL_FILES})
5347330f729Sjoerg  else()
5357330f729Sjoerg    add_library(${name} STATIC ${ALL_FILES})
5367330f729Sjoerg  endif()
5377330f729Sjoerg
538*82d56013Sjoerg  if(ARG_COMPONENT_LIB)
539*82d56013Sjoerg    set_target_properties(${name} PROPERTIES LLVM_COMPONENT TRUE)
540*82d56013Sjoerg    set_property(GLOBAL APPEND PROPERTY LLVM_COMPONENT_LIBS ${name})
541*82d56013Sjoerg  endif()
542*82d56013Sjoerg
5437330f729Sjoerg  if(NOT ARG_NO_INSTALL_RPATH)
5447330f729Sjoerg    if(ARG_MODULE OR ARG_SHARED)
5457330f729Sjoerg      llvm_setup_rpath(${name})
5467330f729Sjoerg    endif()
5477330f729Sjoerg  endif()
5487330f729Sjoerg
5497330f729Sjoerg  setup_dependency_debugging(${name} ${LLVM_COMMON_DEPENDS})
5507330f729Sjoerg
5517330f729Sjoerg  if(DEFINED windows_resource_file)
5527330f729Sjoerg    set_windows_version_resource_properties(${name} ${windows_resource_file})
5537330f729Sjoerg    set(windows_resource_file ${windows_resource_file} PARENT_SCOPE)
5547330f729Sjoerg  endif()
5557330f729Sjoerg
5567330f729Sjoerg  set_output_directory(${name} BINARY_DIR ${LLVM_RUNTIME_OUTPUT_INTDIR} LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR})
5577330f729Sjoerg  # $<TARGET_OBJECTS> doesn't require compile flags.
5587330f729Sjoerg  if(NOT obj_name)
5597330f729Sjoerg    llvm_update_compile_flags(${name})
5607330f729Sjoerg  endif()
5617330f729Sjoerg  add_link_opts( ${name} )
5627330f729Sjoerg  if(ARG_OUTPUT_NAME)
5637330f729Sjoerg    set_target_properties(${name}
5647330f729Sjoerg      PROPERTIES
5657330f729Sjoerg      OUTPUT_NAME ${ARG_OUTPUT_NAME}
5667330f729Sjoerg      )
5677330f729Sjoerg  endif()
5687330f729Sjoerg
5697330f729Sjoerg  if(ARG_MODULE)
5707330f729Sjoerg    set_target_properties(${name} PROPERTIES
5717330f729Sjoerg      PREFIX ""
5727330f729Sjoerg      SUFFIX ${LLVM_PLUGIN_EXT}
5737330f729Sjoerg      )
5747330f729Sjoerg  endif()
5757330f729Sjoerg
5767330f729Sjoerg  if(ARG_SHARED)
577*82d56013Sjoerg    if(MSVC)
5787330f729Sjoerg      set_target_properties(${name} PROPERTIES
5797330f729Sjoerg        PREFIX ""
5807330f729Sjoerg        )
5817330f729Sjoerg    endif()
5827330f729Sjoerg
5837330f729Sjoerg    # Set SOVERSION on shared libraries that lack explicit SONAME
5847330f729Sjoerg    # specifier, on *nix systems that are not Darwin.
5857330f729Sjoerg    if(UNIX AND NOT APPLE AND NOT ARG_SONAME)
5867330f729Sjoerg      set_target_properties(${name}
5877330f729Sjoerg        PROPERTIES
5887330f729Sjoerg        # Since 4.0.0, the ABI version is indicated by the major version
5897330f729Sjoerg        SOVERSION ${LLVM_VERSION_MAJOR}${LLVM_VERSION_SUFFIX}
5907330f729Sjoerg        VERSION ${LLVM_VERSION_MAJOR}${LLVM_VERSION_SUFFIX})
5917330f729Sjoerg    endif()
5927330f729Sjoerg  endif()
5937330f729Sjoerg
5947330f729Sjoerg  if(ARG_MODULE OR ARG_SHARED)
5957330f729Sjoerg    # Do not add -Dname_EXPORTS to the command-line when building files in this
5967330f729Sjoerg    # target. Doing so is actively harmful for the modules build because it
5977330f729Sjoerg    # creates extra module variants, and not useful because we don't use these
5987330f729Sjoerg    # macros.
5997330f729Sjoerg    set_target_properties( ${name} PROPERTIES DEFINE_SYMBOL "" )
6007330f729Sjoerg
6017330f729Sjoerg    if (LLVM_EXPORTED_SYMBOL_FILE)
6027330f729Sjoerg      add_llvm_symbol_exports( ${name} ${LLVM_EXPORTED_SYMBOL_FILE} )
6037330f729Sjoerg    endif()
6047330f729Sjoerg  endif()
6057330f729Sjoerg
6067330f729Sjoerg  if(ARG_SHARED AND UNIX)
6077330f729Sjoerg    if(NOT APPLE AND ARG_SONAME)
6087330f729Sjoerg      get_target_property(output_name ${name} OUTPUT_NAME)
6097330f729Sjoerg      if(${output_name} STREQUAL "output_name-NOTFOUND")
6107330f729Sjoerg        set(output_name ${name})
6117330f729Sjoerg      endif()
6127330f729Sjoerg      set(library_name ${output_name}-${LLVM_VERSION_MAJOR}${LLVM_VERSION_SUFFIX})
6137330f729Sjoerg      set(api_name ${output_name}-${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}${LLVM_VERSION_SUFFIX})
6147330f729Sjoerg      set_target_properties(${name} PROPERTIES OUTPUT_NAME ${library_name})
6157330f729Sjoerg      llvm_install_library_symlink(${api_name} ${library_name} SHARED
616*82d56013Sjoerg        COMPONENT ${name})
6177330f729Sjoerg      llvm_install_library_symlink(${output_name} ${library_name} SHARED
618*82d56013Sjoerg        COMPONENT ${name})
6197330f729Sjoerg    endif()
6207330f729Sjoerg  endif()
6217330f729Sjoerg
622*82d56013Sjoerg  if(ARG_STATIC)
623*82d56013Sjoerg    set(libtype PUBLIC)
624*82d56013Sjoerg  else()
625*82d56013Sjoerg    # We can use PRIVATE since SO knows its dependent libs.
626*82d56013Sjoerg    set(libtype PRIVATE)
627*82d56013Sjoerg  endif()
628*82d56013Sjoerg
6297330f729Sjoerg  if(ARG_MODULE AND LLVM_EXPORT_SYMBOLS_FOR_PLUGINS AND ARG_PLUGIN_TOOL AND (WIN32 OR CYGWIN))
6307330f729Sjoerg    # On DLL platforms symbols are imported from the tool by linking against it.
6317330f729Sjoerg    set(llvm_libs ${ARG_PLUGIN_TOOL})
632*82d56013Sjoerg  elseif (NOT ARG_COMPONENT_LIB)
6337330f729Sjoerg    if (LLVM_LINK_LLVM_DYLIB AND NOT ARG_DISABLE_LLVM_LINK_LLVM_DYLIB)
6347330f729Sjoerg      set(llvm_libs LLVM)
6357330f729Sjoerg    else()
6367330f729Sjoerg      llvm_map_components_to_libnames(llvm_libs
6377330f729Sjoerg       ${ARG_LINK_COMPONENTS}
6387330f729Sjoerg       ${LLVM_LINK_COMPONENTS}
6397330f729Sjoerg       )
6407330f729Sjoerg    endif()
6417330f729Sjoerg  else()
6427330f729Sjoerg    # Components have not been defined explicitly in CMake, so add the
643*82d56013Sjoerg    # dependency information for this library through their name, and let
644*82d56013Sjoerg    # LLVMBuildResolveComponentsLink resolve the mapping.
6457330f729Sjoerg    #
6467330f729Sjoerg    # It would be nice to verify that we have the dependencies for this library
6477330f729Sjoerg    # name, but using get_property(... SET) doesn't suffice to determine if a
6487330f729Sjoerg    # property has been set to an empty value.
649*82d56013Sjoerg    set_property(TARGET ${name} PROPERTY LLVM_LINK_COMPONENTS ${ARG_LINK_COMPONENTS} ${LLVM_LINK_COMPONENTS})
6507330f729Sjoerg
651*82d56013Sjoerg    # These two properties are internal properties only used to make sure the
652*82d56013Sjoerg    # link step applied in LLVMBuildResolveComponentsLink uses the same
653*82d56013Sjoerg    # properties as the target_link_libraries call below.
654*82d56013Sjoerg    set_property(TARGET ${name} PROPERTY LLVM_LINK_LIBS ${ARG_LINK_LIBS})
655*82d56013Sjoerg    set_property(TARGET ${name} PROPERTY LLVM_LIBTYPE ${libtype})
6567330f729Sjoerg  endif()
6577330f729Sjoerg
6587330f729Sjoerg  target_link_libraries(${name} ${libtype}
6597330f729Sjoerg      ${ARG_LINK_LIBS}
6607330f729Sjoerg      ${lib_deps}
6617330f729Sjoerg      ${llvm_libs}
6627330f729Sjoerg      )
6637330f729Sjoerg
6647330f729Sjoerg  if(LLVM_COMMON_DEPENDS)
6657330f729Sjoerg    add_dependencies(${name} ${LLVM_COMMON_DEPENDS})
6667330f729Sjoerg    # Add dependencies also to objlibs.
6677330f729Sjoerg    # CMake issue 14747 --  add_dependencies() might be ignored to objlib's user.
6687330f729Sjoerg    foreach(objlib ${objlibs})
6697330f729Sjoerg      add_dependencies(${objlib} ${LLVM_COMMON_DEPENDS})
6707330f729Sjoerg    endforeach()
6717330f729Sjoerg  endif()
6727330f729Sjoerg
6737330f729Sjoerg  if(ARG_SHARED OR ARG_MODULE)
6747330f729Sjoerg    llvm_externalize_debuginfo(${name})
6757330f729Sjoerg    llvm_codesign(${name} ENTITLEMENTS ${ARG_ENTITLEMENTS} BUNDLE_PATH ${ARG_BUNDLE_PATH})
6767330f729Sjoerg  endif()
6777330f729Sjoerg  # clang and newer versions of ninja use high-resolutions timestamps,
6787330f729Sjoerg  # but older versions of libtool on Darwin don't, so the archive will
6797330f729Sjoerg  # often get an older timestamp than the last object that was added
6807330f729Sjoerg  # or updated.  To fix this, we add a custom command to touch archive
6817330f729Sjoerg  # after it's been built so that ninja won't rebuild it unnecessarily
6827330f729Sjoerg  # the next time it's run.
6837330f729Sjoerg  if(ARG_STATIC AND LLVM_TOUCH_STATIC_LIBRARIES)
6847330f729Sjoerg    add_custom_command(TARGET ${name}
6857330f729Sjoerg      POST_BUILD
6867330f729Sjoerg      COMMAND touch ${LLVM_LIBRARY_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}${name}${CMAKE_STATIC_LIBRARY_SUFFIX}
6877330f729Sjoerg      )
6887330f729Sjoerg  endif()
6897330f729Sjoergendfunction()
6907330f729Sjoerg
6917330f729Sjoergfunction(add_llvm_install_targets target)
692*82d56013Sjoerg  cmake_parse_arguments(ARG "" "COMPONENT;PREFIX;SYMLINK" "DEPENDS" ${ARGN})
6937330f729Sjoerg  if(ARG_COMPONENT)
6947330f729Sjoerg    set(component_option -DCMAKE_INSTALL_COMPONENT="${ARG_COMPONENT}")
6957330f729Sjoerg  endif()
6967330f729Sjoerg  if(ARG_PREFIX)
6977330f729Sjoerg    set(prefix_option -DCMAKE_INSTALL_PREFIX="${ARG_PREFIX}")
6987330f729Sjoerg  endif()
6997330f729Sjoerg
7007330f729Sjoerg  set(file_dependencies)
7017330f729Sjoerg  set(target_dependencies)
7027330f729Sjoerg  foreach(dependency ${ARG_DEPENDS})
7037330f729Sjoerg    if(TARGET ${dependency})
7047330f729Sjoerg      list(APPEND target_dependencies ${dependency})
7057330f729Sjoerg    else()
7067330f729Sjoerg      list(APPEND file_dependencies ${dependency})
7077330f729Sjoerg    endif()
7087330f729Sjoerg  endforeach()
7097330f729Sjoerg
7107330f729Sjoerg  add_custom_target(${target}
7117330f729Sjoerg                    DEPENDS ${file_dependencies}
7127330f729Sjoerg                    COMMAND "${CMAKE_COMMAND}"
7137330f729Sjoerg                            ${component_option}
7147330f729Sjoerg                            ${prefix_option}
7157330f729Sjoerg                            -P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
7167330f729Sjoerg                    USES_TERMINAL)
7177330f729Sjoerg  add_custom_target(${target}-stripped
7187330f729Sjoerg                    DEPENDS ${file_dependencies}
7197330f729Sjoerg                    COMMAND "${CMAKE_COMMAND}"
7207330f729Sjoerg                            ${component_option}
7217330f729Sjoerg                            ${prefix_option}
7227330f729Sjoerg                            -DCMAKE_INSTALL_DO_STRIP=1
7237330f729Sjoerg                            -P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
7247330f729Sjoerg                    USES_TERMINAL)
7257330f729Sjoerg  if(target_dependencies)
7267330f729Sjoerg    add_dependencies(${target} ${target_dependencies})
7277330f729Sjoerg    add_dependencies(${target}-stripped ${target_dependencies})
7287330f729Sjoerg  endif()
729*82d56013Sjoerg
730*82d56013Sjoerg  if(ARG_SYMLINK)
731*82d56013Sjoerg    add_dependencies(${target} install-${ARG_SYMLINK})
732*82d56013Sjoerg    add_dependencies(${target}-stripped install-${ARG_SYMLINK}-stripped)
733*82d56013Sjoerg  endif()
734*82d56013Sjoergendfunction()
735*82d56013Sjoerg
736*82d56013Sjoerg# Define special targets that behave like a component group. They don't have any
737*82d56013Sjoerg# source attached but other components can add themselves to them. If the
738*82d56013Sjoerg# component supports is a Target and it supports JIT compilation, HAS_JIT must
739*82d56013Sjoerg# be passed. One can use ADD_TO_COMPONENT option from add_llvm_component_library
740*82d56013Sjoerg# to link extra component into an existing group.
741*82d56013Sjoergfunction(add_llvm_component_group name)
742*82d56013Sjoerg  cmake_parse_arguments(ARG "HAS_JIT" "" "LINK_COMPONENTS" ${ARGN})
743*82d56013Sjoerg  add_custom_target(${name})
744*82d56013Sjoerg  if(ARG_HAS_JIT)
745*82d56013Sjoerg    set_property(TARGET ${name} PROPERTY COMPONENT_HAS_JIT ON)
746*82d56013Sjoerg  endif()
747*82d56013Sjoerg  if(ARG_LINK_COMPONENTS)
748*82d56013Sjoerg    set_property(TARGET ${name} PROPERTY LLVM_LINK_COMPONENTS ${ARG_LINK_COMPONENTS})
749*82d56013Sjoerg  endif()
750*82d56013Sjoergendfunction()
751*82d56013Sjoerg
752*82d56013Sjoerg# An LLVM component is a cmake target with the following cmake properties
753*82d56013Sjoerg# eventually set:
754*82d56013Sjoerg#   - LLVM_COMPONENT_NAME: the name of the component, which can be the name of
755*82d56013Sjoerg#     the associated library or the one specified through COMPONENT_NAME
756*82d56013Sjoerg#   - LLVM_LINK_COMPONENTS: a list of component this component depends on
757*82d56013Sjoerg#   - COMPONENT_HAS_JIT: (only for group component) whether this target group
758*82d56013Sjoerg#     supports JIT compilation
759*82d56013Sjoerg# Additionnaly, the ADD_TO_COMPONENT <component> option make it possible to add this
760*82d56013Sjoerg# component to the LLVM_LINK_COMPONENTS of <component>.
761*82d56013Sjoergfunction(add_llvm_component_library name)
762*82d56013Sjoerg  cmake_parse_arguments(ARG
763*82d56013Sjoerg    ""
764*82d56013Sjoerg    "COMPONENT_NAME;ADD_TO_COMPONENT"
765*82d56013Sjoerg    ""
766*82d56013Sjoerg    ${ARGN})
767*82d56013Sjoerg  add_llvm_library(${name} COMPONENT_LIB ${ARG_UNPARSED_ARGUMENTS})
768*82d56013Sjoerg  string(REGEX REPLACE "^LLVM" "" component_name ${name})
769*82d56013Sjoerg  set_property(TARGET ${name} PROPERTY LLVM_COMPONENT_NAME ${component_name})
770*82d56013Sjoerg
771*82d56013Sjoerg  if(ARG_COMPONENT_NAME)
772*82d56013Sjoerg    set_property(GLOBAL PROPERTY LLVM_COMPONENT_NAME_${ARG_COMPONENT_NAME} ${component_name})
773*82d56013Sjoerg  endif()
774*82d56013Sjoerg
775*82d56013Sjoerg  if(ARG_ADD_TO_COMPONENT)
776*82d56013Sjoerg    set_property(TARGET ${ARG_ADD_TO_COMPONENT} APPEND PROPERTY LLVM_LINK_COMPONENTS ${component_name})
777*82d56013Sjoerg  endif()
778*82d56013Sjoerg
7797330f729Sjoergendfunction()
7807330f729Sjoerg
7817330f729Sjoergmacro(add_llvm_library name)
7827330f729Sjoerg  cmake_parse_arguments(ARG
7837330f729Sjoerg    "SHARED;BUILDTREE_ONLY;MODULE;INSTALL_WITH_TOOLCHAIN"
7847330f729Sjoerg    ""
7857330f729Sjoerg    ""
7867330f729Sjoerg    ${ARGN})
7877330f729Sjoerg  if(ARG_MODULE)
7887330f729Sjoerg    llvm_add_library(${name} MODULE ${ARG_UNPARSED_ARGUMENTS})
7897330f729Sjoerg  elseif( BUILD_SHARED_LIBS OR ARG_SHARED )
7907330f729Sjoerg    llvm_add_library(${name} SHARED ${ARG_UNPARSED_ARGUMENTS})
7917330f729Sjoerg  else()
7927330f729Sjoerg    llvm_add_library(${name} ${ARG_UNPARSED_ARGUMENTS})
7937330f729Sjoerg  endif()
7947330f729Sjoerg
7957330f729Sjoerg  # Libraries that are meant to only be exposed via the build tree only are
7967330f729Sjoerg  # never installed and are only exported as a target in the special build tree
7977330f729Sjoerg  # config file.
7987330f729Sjoerg  if (NOT ARG_BUILDTREE_ONLY AND NOT ARG_MODULE)
7997330f729Sjoerg    set_property( GLOBAL APPEND PROPERTY LLVM_LIBS ${name} )
8007330f729Sjoerg    set(in_llvm_libs YES)
8017330f729Sjoerg  endif()
8027330f729Sjoerg
8037330f729Sjoerg  if (ARG_MODULE AND NOT TARGET ${name})
8047330f729Sjoerg    # Add empty "phony" target
8057330f729Sjoerg    add_custom_target(${name})
8067330f729Sjoerg  elseif( EXCLUDE_FROM_ALL )
8077330f729Sjoerg    set_target_properties( ${name} PROPERTIES EXCLUDE_FROM_ALL ON)
8087330f729Sjoerg  elseif(ARG_BUILDTREE_ONLY)
8097330f729Sjoerg    set_property(GLOBAL APPEND PROPERTY LLVM_EXPORTS_BUILDTREE_ONLY ${name})
8107330f729Sjoerg  else()
8117330f729Sjoerg    if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY OR ARG_INSTALL_WITH_TOOLCHAIN)
812*82d56013Sjoerg      if(in_llvm_libs)
813*82d56013Sjoerg        set(umbrella UMBRELLA llvm-libraries)
814*82d56013Sjoerg      else()
815*82d56013Sjoerg        set(umbrella)
8167330f729Sjoerg      endif()
8177330f729Sjoerg
818*82d56013Sjoerg      get_target_export_arg(${name} LLVM export_to_llvmexports ${umbrella})
8197330f729Sjoerg      install(TARGETS ${name}
8207330f729Sjoerg              ${export_to_llvmexports}
8217330f729Sjoerg              LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX} COMPONENT ${name}
8227330f729Sjoerg              ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX} COMPONENT ${name}
8237330f729Sjoerg              RUNTIME DESTINATION bin COMPONENT ${name})
8247330f729Sjoerg
8257330f729Sjoerg      if (NOT LLVM_ENABLE_IDE)
8267330f729Sjoerg        add_llvm_install_targets(install-${name}
8277330f729Sjoerg                                 DEPENDS ${name}
8287330f729Sjoerg                                 COMPONENT ${name})
8297330f729Sjoerg      endif()
8307330f729Sjoerg    endif()
8317330f729Sjoerg    set_property(GLOBAL APPEND PROPERTY LLVM_EXPORTS ${name})
8327330f729Sjoerg  endif()
8337330f729Sjoerg  if (ARG_MODULE)
8347330f729Sjoerg    set_target_properties(${name} PROPERTIES FOLDER "Loadable modules")
8357330f729Sjoerg  else()
8367330f729Sjoerg    set_target_properties(${name} PROPERTIES FOLDER "Libraries")
8377330f729Sjoerg  endif()
8387330f729Sjoergendmacro(add_llvm_library name)
8397330f729Sjoerg
8407330f729Sjoergmacro(add_llvm_executable name)
8417330f729Sjoerg  cmake_parse_arguments(ARG
842*82d56013Sjoerg    "DISABLE_LLVM_LINK_LLVM_DYLIB;IGNORE_EXTERNALIZE_DEBUGINFO;NO_INSTALL_RPATH;SUPPORT_PLUGINS"
8437330f729Sjoerg    "ENTITLEMENTS;BUNDLE_PATH"
8447330f729Sjoerg    "DEPENDS"
8457330f729Sjoerg    ${ARGN})
8467330f729Sjoerg
8477330f729Sjoerg  llvm_process_sources( ALL_FILES ${ARG_UNPARSED_ARGUMENTS} )
8487330f729Sjoerg
8497330f729Sjoerg  list(APPEND LLVM_COMMON_DEPENDS ${ARG_DEPENDS})
8507330f729Sjoerg
8517330f729Sjoerg  # Generate objlib
8527330f729Sjoerg  if(LLVM_ENABLE_OBJLIB)
8537330f729Sjoerg    # Generate an obj library for both targets.
8547330f729Sjoerg    set(obj_name "obj.${name}")
8557330f729Sjoerg    add_library(${obj_name} OBJECT EXCLUDE_FROM_ALL
8567330f729Sjoerg      ${ALL_FILES}
8577330f729Sjoerg      )
8587330f729Sjoerg    llvm_update_compile_flags(${obj_name})
8597330f729Sjoerg    set(ALL_FILES "$<TARGET_OBJECTS:${obj_name}>")
8607330f729Sjoerg
8617330f729Sjoerg    set_target_properties(${obj_name} PROPERTIES FOLDER "Object Libraries")
8627330f729Sjoerg  endif()
8637330f729Sjoerg
8647330f729Sjoerg  add_windows_version_resource_file(ALL_FILES ${ALL_FILES})
8657330f729Sjoerg
8667330f729Sjoerg  if(XCODE)
8677330f729Sjoerg    # Note: the dummy.cpp source file provides no definitions. However,
8687330f729Sjoerg    # it forces Xcode to properly link the static library.
8697330f729Sjoerg    list(APPEND ALL_FILES "${LLVM_MAIN_SRC_DIR}/cmake/dummy.cpp")
8707330f729Sjoerg  endif()
8717330f729Sjoerg
8727330f729Sjoerg  if( EXCLUDE_FROM_ALL )
8737330f729Sjoerg    add_executable(${name} EXCLUDE_FROM_ALL ${ALL_FILES})
8747330f729Sjoerg  else()
8757330f729Sjoerg    add_executable(${name} ${ALL_FILES})
8767330f729Sjoerg  endif()
8777330f729Sjoerg
8787330f729Sjoerg  setup_dependency_debugging(${name} ${LLVM_COMMON_DEPENDS})
8797330f729Sjoerg
8807330f729Sjoerg  if(NOT ARG_NO_INSTALL_RPATH)
8817330f729Sjoerg    llvm_setup_rpath(${name})
882*82d56013Sjoerg  elseif(NOT "${LLVM_LOCAL_RPATH}" STREQUAL "")
883*82d56013Sjoerg    # Enable BUILD_WITH_INSTALL_RPATH unless CMAKE_BUILD_RPATH is set.
884*82d56013Sjoerg    if("${CMAKE_BUILD_RPATH}" STREQUAL "")
885*82d56013Sjoerg      set_property(TARGET ${name} PROPERTY BUILD_WITH_INSTALL_RPATH ON)
886*82d56013Sjoerg    endif()
887*82d56013Sjoerg
888*82d56013Sjoerg    set_property(TARGET ${name} PROPERTY INSTALL_RPATH "${LLVM_LOCAL_RPATH}")
8897330f729Sjoerg  endif()
8907330f729Sjoerg
8917330f729Sjoerg  if(DEFINED windows_resource_file)
8927330f729Sjoerg    set_windows_version_resource_properties(${name} ${windows_resource_file})
8937330f729Sjoerg  endif()
8947330f729Sjoerg
8957330f729Sjoerg  # $<TARGET_OBJECTS> doesn't require compile flags.
8967330f729Sjoerg  if(NOT LLVM_ENABLE_OBJLIB)
8977330f729Sjoerg    llvm_update_compile_flags(${name})
8987330f729Sjoerg  endif()
899*82d56013Sjoerg
900*82d56013Sjoerg  if (ARG_SUPPORT_PLUGINS AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "AIX")
901*82d56013Sjoerg    set(LLVM_NO_DEAD_STRIP On)
902*82d56013Sjoerg  endif()
903*82d56013Sjoerg
9047330f729Sjoerg  add_link_opts( ${name} )
9057330f729Sjoerg
9067330f729Sjoerg  # Do not add -Dname_EXPORTS to the command-line when building files in this
9077330f729Sjoerg  # target. Doing so is actively harmful for the modules build because it
9087330f729Sjoerg  # creates extra module variants, and not useful because we don't use these
9097330f729Sjoerg  # macros.
9107330f729Sjoerg  set_target_properties( ${name} PROPERTIES DEFINE_SYMBOL "" )
9117330f729Sjoerg
9127330f729Sjoerg  if (LLVM_EXPORTED_SYMBOL_FILE)
9137330f729Sjoerg    add_llvm_symbol_exports( ${name} ${LLVM_EXPORTED_SYMBOL_FILE} )
9147330f729Sjoerg  endif(LLVM_EXPORTED_SYMBOL_FILE)
9157330f729Sjoerg
9167330f729Sjoerg  if (LLVM_LINK_LLVM_DYLIB AND NOT ARG_DISABLE_LLVM_LINK_LLVM_DYLIB)
9177330f729Sjoerg    set(USE_SHARED USE_SHARED)
9187330f729Sjoerg  endif()
9197330f729Sjoerg
9207330f729Sjoerg  set(EXCLUDE_FROM_ALL OFF)
9217330f729Sjoerg  set_output_directory(${name} BINARY_DIR ${LLVM_RUNTIME_OUTPUT_INTDIR} LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR})
9227330f729Sjoerg  llvm_config( ${name} ${USE_SHARED} ${LLVM_LINK_COMPONENTS} )
9237330f729Sjoerg  if( LLVM_COMMON_DEPENDS )
9247330f729Sjoerg    add_dependencies( ${name} ${LLVM_COMMON_DEPENDS} )
9257330f729Sjoerg  endif( LLVM_COMMON_DEPENDS )
9267330f729Sjoerg
9277330f729Sjoerg  if(NOT ARG_IGNORE_EXTERNALIZE_DEBUGINFO)
9287330f729Sjoerg    llvm_externalize_debuginfo(${name})
9297330f729Sjoerg  endif()
9307330f729Sjoerg  if (LLVM_PTHREAD_LIB)
9317330f729Sjoerg    # libpthreads overrides some standard library symbols, so main
9327330f729Sjoerg    # executable must be linked with it in order to provide consistent
9337330f729Sjoerg    # API for all shared libaries loaded by this executable.
9347330f729Sjoerg    target_link_libraries(${name} PRIVATE ${LLVM_PTHREAD_LIB})
9357330f729Sjoerg  endif()
9367330f729Sjoerg
9377330f729Sjoerg  llvm_codesign(${name} ENTITLEMENTS ${ARG_ENTITLEMENTS} BUNDLE_PATH ${ARG_BUNDLE_PATH})
9387330f729Sjoergendmacro(add_llvm_executable name)
9397330f729Sjoerg
940*82d56013Sjoerg# add_llvm_pass_plugin(name [NO_MODULE] ...)
941*82d56013Sjoerg#   Add ${name} as an llvm plugin.
942*82d56013Sjoerg#   If option LLVM_${name_upper}_LINK_INTO_TOOLS is set to ON, the plugin is registered statically.
943*82d56013Sjoerg#   Otherwise a pluggable shared library is registered.
944*82d56013Sjoerg#
945*82d56013Sjoerg#   If NO_MODULE is specified, when option LLVM_${name_upper}_LINK_INTO_TOOLS is set to OFF,
946*82d56013Sjoerg#   only an object library is built, and no module is built. This is specific to the Polly use case.
947*82d56013Sjoerg#
948*82d56013Sjoerg#   The SUBPROJECT argument contains the LLVM project the plugin belongs
949*82d56013Sjoerg#   to. If set, the plugin will link statically by default it if the
950*82d56013Sjoerg#   project was enabled.
951*82d56013Sjoergfunction(add_llvm_pass_plugin name)
952*82d56013Sjoerg  cmake_parse_arguments(ARG
953*82d56013Sjoerg    "NO_MODULE" "SUBPROJECT" ""
954*82d56013Sjoerg    ${ARGN})
955*82d56013Sjoerg
956*82d56013Sjoerg  string(TOUPPER ${name} name_upper)
957*82d56013Sjoerg
958*82d56013Sjoerg  # Enable the plugin by default if it was explicitly enabled by the user.
959*82d56013Sjoerg  # Note: If was set to "all", LLVM's CMakeLists.txt replaces it with a
960*82d56013Sjoerg  # list of all projects, counting as explicitly enabled.
961*82d56013Sjoerg  set(link_into_tools_default OFF)
962*82d56013Sjoerg  if (ARG_SUBPROJECT AND LLVM_TOOL_${name_upper}_BUILD)
963*82d56013Sjoerg    set(link_into_tools_default ON)
964*82d56013Sjoerg  endif()
965*82d56013Sjoerg  option(LLVM_${name_upper}_LINK_INTO_TOOLS "Statically link ${name} into tools (if available)" ${link_into_tools_default})
966*82d56013Sjoerg
967*82d56013Sjoerg  # If we statically link the plugin, don't use llvm dylib because we're going
968*82d56013Sjoerg  # to be part of it.
969*82d56013Sjoerg  if(LLVM_${name_upper}_LINK_INTO_TOOLS)
970*82d56013Sjoerg      list(APPEND ARG_UNPARSED_ARGUMENTS DISABLE_LLVM_LINK_LLVM_DYLIB)
971*82d56013Sjoerg  endif()
972*82d56013Sjoerg
973*82d56013Sjoerg  if(LLVM_${name_upper}_LINK_INTO_TOOLS)
974*82d56013Sjoerg    list(REMOVE_ITEM ARG_UNPARSED_ARGUMENTS BUILDTREE_ONLY)
975*82d56013Sjoerg    # process_llvm_pass_plugins takes care of the actual linking, just create an
976*82d56013Sjoerg    # object library as of now
977*82d56013Sjoerg    add_llvm_library(${name} OBJECT ${ARG_UNPARSED_ARGUMENTS})
978*82d56013Sjoerg    target_compile_definitions(${name} PRIVATE LLVM_${name_upper}_LINK_INTO_TOOLS)
979*82d56013Sjoerg    set_property(TARGET ${name} APPEND PROPERTY COMPILE_DEFINITIONS LLVM_LINK_INTO_TOOLS)
980*82d56013Sjoerg    if (TARGET intrinsics_gen)
981*82d56013Sjoerg      add_dependencies(obj.${name} intrinsics_gen)
982*82d56013Sjoerg    endif()
983*82d56013Sjoerg    if (TARGET omp_gen)
984*82d56013Sjoerg      add_dependencies(obj.${name} omp_gen)
985*82d56013Sjoerg    endif()
986*82d56013Sjoerg    if (TARGET acc_gen)
987*82d56013Sjoerg      add_dependencies(obj.${name} acc_gen)
988*82d56013Sjoerg    endif()
989*82d56013Sjoerg    set_property(GLOBAL APPEND PROPERTY LLVM_STATIC_EXTENSIONS ${name})
990*82d56013Sjoerg  elseif(NOT ARG_NO_MODULE)
991*82d56013Sjoerg    add_llvm_library(${name} MODULE ${ARG_UNPARSED_ARGUMENTS})
992*82d56013Sjoerg  else()
993*82d56013Sjoerg    add_llvm_library(${name} OBJECT ${ARG_UNPARSED_ARGUMENTS})
994*82d56013Sjoerg  endif()
995*82d56013Sjoerg  message(STATUS "Registering ${name} as a pass plugin (static build: ${LLVM_${name_upper}_LINK_INTO_TOOLS})")
996*82d56013Sjoerg
997*82d56013Sjoergendfunction(add_llvm_pass_plugin)
998*82d56013Sjoerg
999*82d56013Sjoerg# process_llvm_pass_plugins([GEN_CONFIG])
1000*82d56013Sjoerg#
1001*82d56013Sjoerg# Correctly set lib dependencies between plugins and tools, based on tools
1002*82d56013Sjoerg# registered with the ENABLE_PLUGINS option.
1003*82d56013Sjoerg#
1004*82d56013Sjoerg# if GEN_CONFIG option is set, also generate X Macro file for extension
1005*82d56013Sjoerg# handling. It provides a HANDLE_EXTENSION(extension_namespace, ExtensionProject)
1006*82d56013Sjoerg# call for each extension allowing client code to define
1007*82d56013Sjoerg# HANDLE_EXTENSION to have a specific code be run for each extension.
1008*82d56013Sjoerg#
1009*82d56013Sjoergfunction(process_llvm_pass_plugins)
1010*82d56013Sjoerg  cmake_parse_arguments(ARG
1011*82d56013Sjoerg      "GEN_CONFIG" "" ""
1012*82d56013Sjoerg    ${ARGN})
1013*82d56013Sjoerg
1014*82d56013Sjoerg  if(ARG_GEN_CONFIG)
1015*82d56013Sjoerg      get_property(LLVM_STATIC_EXTENSIONS GLOBAL PROPERTY LLVM_STATIC_EXTENSIONS)
1016*82d56013Sjoerg  else()
1017*82d56013Sjoerg      include(LLVMConfigExtensions)
1018*82d56013Sjoerg  endif()
1019*82d56013Sjoerg
1020*82d56013Sjoerg  # Add static plugins to the Extension component
1021*82d56013Sjoerg  foreach(llvm_extension ${LLVM_STATIC_EXTENSIONS})
1022*82d56013Sjoerg      set_property(TARGET LLVMExtensions APPEND PROPERTY LINK_LIBRARIES ${llvm_extension})
1023*82d56013Sjoerg      set_property(TARGET LLVMExtensions APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${llvm_extension})
1024*82d56013Sjoerg  endforeach()
1025*82d56013Sjoerg
1026*82d56013Sjoerg  # Eventually generate the extension headers, and store config to a cmake file
1027*82d56013Sjoerg  # for usage in third-party configuration.
1028*82d56013Sjoerg  if(ARG_GEN_CONFIG)
1029*82d56013Sjoerg
1030*82d56013Sjoerg      ## Part 1: Extension header to be included whenever we need extension
1031*82d56013Sjoerg      #  processing.
1032*82d56013Sjoerg      set(LLVM_INSTALL_PACKAGE_DIR lib${LLVM_LIBDIR_SUFFIX}/cmake/llvm)
1033*82d56013Sjoerg      set(llvm_cmake_builddir "${LLVM_BINARY_DIR}/${LLVM_INSTALL_PACKAGE_DIR}")
1034*82d56013Sjoerg      file(WRITE
1035*82d56013Sjoerg          "${llvm_cmake_builddir}/LLVMConfigExtensions.cmake"
1036*82d56013Sjoerg          "set(LLVM_STATIC_EXTENSIONS ${LLVM_STATIC_EXTENSIONS})")
1037*82d56013Sjoerg      install(FILES
1038*82d56013Sjoerg          ${llvm_cmake_builddir}/LLVMConfigExtensions.cmake
1039*82d56013Sjoerg          DESTINATION ${LLVM_INSTALL_PACKAGE_DIR}
1040*82d56013Sjoerg          COMPONENT cmake-exports)
1041*82d56013Sjoerg
1042*82d56013Sjoerg      set(ExtensionDef "${LLVM_BINARY_DIR}/include/llvm/Support/Extension.def")
1043*82d56013Sjoerg      file(WRITE "${ExtensionDef}.tmp" "//extension handlers\n")
1044*82d56013Sjoerg      foreach(llvm_extension ${LLVM_STATIC_EXTENSIONS})
1045*82d56013Sjoerg          file(APPEND "${ExtensionDef}.tmp" "HANDLE_EXTENSION(${llvm_extension})\n")
1046*82d56013Sjoerg      endforeach()
1047*82d56013Sjoerg      file(APPEND "${ExtensionDef}.tmp" "#undef HANDLE_EXTENSION\n")
1048*82d56013Sjoerg
1049*82d56013Sjoerg      # only replace if there's an actual change
1050*82d56013Sjoerg      execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
1051*82d56013Sjoerg          "${ExtensionDef}.tmp"
1052*82d56013Sjoerg          "${ExtensionDef}")
1053*82d56013Sjoerg      file(REMOVE "${ExtensionDef}.tmp")
1054*82d56013Sjoerg
1055*82d56013Sjoerg      ## Part 2: Extension header that captures each extension dependency, to be
1056*82d56013Sjoerg      #  used by llvm-config.
1057*82d56013Sjoerg      set(ExtensionDeps "${LLVM_BINARY_DIR}/tools/llvm-config/ExtensionDependencies.inc")
1058*82d56013Sjoerg
1059*82d56013Sjoerg      # Max needed to correctly size the required library array.
1060*82d56013Sjoerg      set(llvm_plugin_max_deps_length 0)
1061*82d56013Sjoerg      foreach(llvm_extension ${LLVM_STATIC_EXTENSIONS})
1062*82d56013Sjoerg        get_property(llvm_plugin_deps TARGET ${llvm_extension} PROPERTY LINK_LIBRARIES)
1063*82d56013Sjoerg        list(LENGTH llvm_plugin_deps llvm_plugin_deps_length)
1064*82d56013Sjoerg        if(llvm_plugin_deps_length GREATER llvm_plugin_max_deps_length)
1065*82d56013Sjoerg            set(llvm_plugin_max_deps_length ${llvm_plugin_deps_length})
1066*82d56013Sjoerg        endif()
1067*82d56013Sjoerg      endforeach()
1068*82d56013Sjoerg
1069*82d56013Sjoerg      list(LENGTH LLVM_STATIC_EXTENSIONS llvm_static_extension_count)
1070*82d56013Sjoerg      file(WRITE
1071*82d56013Sjoerg          "${ExtensionDeps}.tmp"
1072*82d56013Sjoerg          "#include <array>\n\
1073*82d56013Sjoerg           struct ExtensionDescriptor {\n\
1074*82d56013Sjoerg              const char* Name;\n\
1075*82d56013Sjoerg              const char* RequiredLibraries[1 + 1 + ${llvm_plugin_max_deps_length}];\n\
1076*82d56013Sjoerg           };\n\
1077*82d56013Sjoerg           std::array<ExtensionDescriptor, ${llvm_static_extension_count}> AvailableExtensions{\n")
1078*82d56013Sjoerg
1079*82d56013Sjoerg      foreach(llvm_extension ${LLVM_STATIC_EXTENSIONS})
1080*82d56013Sjoerg        get_property(llvm_plugin_deps TARGET ${llvm_extension} PROPERTY LINK_LIBRARIES)
1081*82d56013Sjoerg
1082*82d56013Sjoerg        file(APPEND "${ExtensionDeps}.tmp" "ExtensionDescriptor{\"${llvm_extension}\", {")
1083*82d56013Sjoerg        foreach(llvm_plugin_dep ${llvm_plugin_deps})
1084*82d56013Sjoerg            # Turn library dependency back to component name, if possible.
1085*82d56013Sjoerg            # That way llvm-config can avoid redundant dependencies.
1086*82d56013Sjoerg            STRING(REGEX REPLACE "^-l" ""  plugin_dep_name ${llvm_plugin_dep})
1087*82d56013Sjoerg            STRING(REGEX MATCH "^LLVM" is_llvm_library ${plugin_dep_name})
1088*82d56013Sjoerg            if(is_llvm_library)
1089*82d56013Sjoerg                STRING(REGEX REPLACE "^LLVM" ""  plugin_dep_name ${plugin_dep_name})
1090*82d56013Sjoerg                STRING(TOLOWER ${plugin_dep_name} plugin_dep_name)
1091*82d56013Sjoerg            endif()
1092*82d56013Sjoerg            file(APPEND "${ExtensionDeps}.tmp" "\"${plugin_dep_name}\", ")
1093*82d56013Sjoerg        endforeach()
1094*82d56013Sjoerg
1095*82d56013Sjoerg        # Self + mandatory trailing null, because the number of RequiredLibraries differs between extensions.
1096*82d56013Sjoerg        file(APPEND "${ExtensionDeps}.tmp" \"${llvm_extension}\", "nullptr}},\n")
1097*82d56013Sjoerg      endforeach()
1098*82d56013Sjoerg      file(APPEND "${ExtensionDeps}.tmp" "};\n")
1099*82d56013Sjoerg
1100*82d56013Sjoerg      # only replace if there's an actual change
1101*82d56013Sjoerg      execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
1102*82d56013Sjoerg          "${ExtensionDeps}.tmp"
1103*82d56013Sjoerg          "${ExtensionDeps}")
1104*82d56013Sjoerg      file(REMOVE "${ExtensionDeps}.tmp")
1105*82d56013Sjoerg  endif()
1106*82d56013Sjoergendfunction()
1107*82d56013Sjoerg
11087330f729Sjoergfunction(export_executable_symbols target)
11097330f729Sjoerg  if (LLVM_EXPORTED_SYMBOL_FILE)
11107330f729Sjoerg    # The symbol file should contain the symbols we want the executable to
11117330f729Sjoerg    # export
11127330f729Sjoerg    set_target_properties(${target} PROPERTIES ENABLE_EXPORTS 1)
11137330f729Sjoerg  elseif (LLVM_EXPORT_SYMBOLS_FOR_PLUGINS)
11147330f729Sjoerg    # Extract the symbols to export from the static libraries that the
11157330f729Sjoerg    # executable links against.
11167330f729Sjoerg    set_target_properties(${target} PROPERTIES ENABLE_EXPORTS 1)
11177330f729Sjoerg    set(exported_symbol_file ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${target}.symbols)
11187330f729Sjoerg    # We need to consider not just the direct link dependencies, but also the
11197330f729Sjoerg    # transitive link dependencies. Do this by starting with the set of direct
11207330f729Sjoerg    # dependencies, then the dependencies of those dependencies, and so on.
11217330f729Sjoerg    get_target_property(new_libs ${target} LINK_LIBRARIES)
11227330f729Sjoerg    set(link_libs ${new_libs})
11237330f729Sjoerg    while(NOT "${new_libs}" STREQUAL "")
11247330f729Sjoerg      foreach(lib ${new_libs})
11257330f729Sjoerg        if(TARGET ${lib})
11267330f729Sjoerg          get_target_property(lib_type ${lib} TYPE)
11277330f729Sjoerg          if("${lib_type}" STREQUAL "STATIC_LIBRARY")
11287330f729Sjoerg            list(APPEND static_libs ${lib})
11297330f729Sjoerg          else()
11307330f729Sjoerg            list(APPEND other_libs ${lib})
11317330f729Sjoerg          endif()
11327330f729Sjoerg          get_target_property(transitive_libs ${lib} INTERFACE_LINK_LIBRARIES)
11337330f729Sjoerg          foreach(transitive_lib ${transitive_libs})
11347330f729Sjoerg            list(FIND link_libs ${transitive_lib} idx)
11357330f729Sjoerg            if(TARGET ${transitive_lib} AND idx EQUAL -1)
11367330f729Sjoerg              list(APPEND newer_libs ${transitive_lib})
11377330f729Sjoerg              list(APPEND link_libs ${transitive_lib})
11387330f729Sjoerg            endif()
11397330f729Sjoerg          endforeach(transitive_lib)
11407330f729Sjoerg        endif()
11417330f729Sjoerg      endforeach(lib)
11427330f729Sjoerg      set(new_libs ${newer_libs})
11437330f729Sjoerg      set(newer_libs "")
11447330f729Sjoerg    endwhile()
1145*82d56013Sjoerg    list(REMOVE_DUPLICATES static_libs)
11467330f729Sjoerg    if (MSVC)
11477330f729Sjoerg      set(mangling microsoft)
11487330f729Sjoerg    else()
11497330f729Sjoerg      set(mangling itanium)
11507330f729Sjoerg    endif()
11517330f729Sjoerg    add_custom_command(OUTPUT ${exported_symbol_file}
1152*82d56013Sjoerg                       COMMAND "${Python3_EXECUTABLE}" ${LLVM_MAIN_SRC_DIR}/utils/extract_symbols.py --mangling=${mangling} ${static_libs} -o ${exported_symbol_file}
11537330f729Sjoerg                       WORKING_DIRECTORY ${LLVM_LIBRARY_OUTPUT_INTDIR}
11547330f729Sjoerg                       DEPENDS ${LLVM_MAIN_SRC_DIR}/utils/extract_symbols.py ${static_libs}
11557330f729Sjoerg                       VERBATIM
11567330f729Sjoerg                       COMMENT "Generating export list for ${target}")
11577330f729Sjoerg    add_llvm_symbol_exports( ${target} ${exported_symbol_file} )
11587330f729Sjoerg    # If something links against this executable then we want a
11597330f729Sjoerg    # transitive link against only the libraries whose symbols
11607330f729Sjoerg    # we aren't exporting.
11617330f729Sjoerg    set_target_properties(${target} PROPERTIES INTERFACE_LINK_LIBRARIES "${other_libs}")
11627330f729Sjoerg    # The default import library suffix that cmake uses for cygwin/mingw is
11637330f729Sjoerg    # ".dll.a", but for clang.exe that causes a collision with libclang.dll,
11647330f729Sjoerg    # where the import libraries of both get named libclang.dll.a. Use a suffix
11657330f729Sjoerg    # of ".exe.a" to avoid this.
11667330f729Sjoerg    if(CYGWIN OR MINGW)
11677330f729Sjoerg      set_target_properties(${target} PROPERTIES IMPORT_SUFFIX ".exe.a")
11687330f729Sjoerg    endif()
11697330f729Sjoerg  elseif(NOT (WIN32 OR CYGWIN))
11707330f729Sjoerg    # On Windows auto-exporting everything doesn't work because of the limit on
11717330f729Sjoerg    # the size of the exported symbol table, but on other platforms we can do
11727330f729Sjoerg    # it without any trouble.
11737330f729Sjoerg    set_target_properties(${target} PROPERTIES ENABLE_EXPORTS 1)
11747330f729Sjoerg    if (APPLE)
11757330f729Sjoerg      set_property(TARGET ${target} APPEND_STRING PROPERTY
11767330f729Sjoerg        LINK_FLAGS " -rdynamic")
11777330f729Sjoerg    endif()
11787330f729Sjoerg  endif()
11797330f729Sjoergendfunction()
11807330f729Sjoerg
1181*82d56013Sjoerg# Export symbols if LLVM plugins are enabled.
1182*82d56013Sjoergfunction(export_executable_symbols_for_plugins target)
1183*82d56013Sjoerg  if(LLVM_ENABLE_PLUGINS OR LLVM_EXPORT_SYMBOLS_FOR_PLUGINS)
1184*82d56013Sjoerg    export_executable_symbols(${target})
1185*82d56013Sjoerg  endif()
1186*82d56013Sjoergendfunction()
1187*82d56013Sjoerg
11887330f729Sjoergif(NOT LLVM_TOOLCHAIN_TOOLS)
11897330f729Sjoerg  set (LLVM_TOOLCHAIN_TOOLS
11907330f729Sjoerg    llvm-ar
1191*82d56013Sjoerg    llvm-cov
1192*82d56013Sjoerg    llvm-cxxfilt
11937330f729Sjoerg    llvm-ranlib
11947330f729Sjoerg    llvm-lib
11957330f729Sjoerg    llvm-nm
11967330f729Sjoerg    llvm-objcopy
11977330f729Sjoerg    llvm-objdump
11987330f729Sjoerg    llvm-rc
1199*82d56013Sjoerg    llvm-size
1200*82d56013Sjoerg    llvm-strings
1201*82d56013Sjoerg    llvm-strip
12027330f729Sjoerg    llvm-profdata
12037330f729Sjoerg    llvm-symbolizer
1204*82d56013Sjoerg    # symlink version of some of above tools that are enabled by
1205*82d56013Sjoerg    # LLVM_INSTALL_BINUTILS_SYMLINKS.
1206*82d56013Sjoerg    addr2line
1207*82d56013Sjoerg    ar
1208*82d56013Sjoerg    c++filt
1209*82d56013Sjoerg    ranlib
1210*82d56013Sjoerg    nm
1211*82d56013Sjoerg    objcopy
1212*82d56013Sjoerg    objdump
1213*82d56013Sjoerg    size
1214*82d56013Sjoerg    strings
1215*82d56013Sjoerg    strip
12167330f729Sjoerg    )
12177330f729Sjoergendif()
12187330f729Sjoerg
12197330f729Sjoergmacro(add_llvm_tool name)
12207330f729Sjoerg  if( NOT LLVM_BUILD_TOOLS )
12217330f729Sjoerg    set(EXCLUDE_FROM_ALL ON)
12227330f729Sjoerg  endif()
12237330f729Sjoerg  add_llvm_executable(${name} ${ARGN})
12247330f729Sjoerg
12257330f729Sjoerg  if ( ${name} IN_LIST LLVM_TOOLCHAIN_TOOLS OR NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
12267330f729Sjoerg    if( LLVM_BUILD_TOOLS )
1227*82d56013Sjoerg      get_target_export_arg(${name} LLVM export_to_llvmexports)
12287330f729Sjoerg      install(TARGETS ${name}
12297330f729Sjoerg              ${export_to_llvmexports}
12307330f729Sjoerg              RUNTIME DESTINATION ${LLVM_TOOLS_INSTALL_DIR}
12317330f729Sjoerg              COMPONENT ${name})
12327330f729Sjoerg
12337330f729Sjoerg      if (NOT LLVM_ENABLE_IDE)
12347330f729Sjoerg        add_llvm_install_targets(install-${name}
12357330f729Sjoerg                                 DEPENDS ${name}
12367330f729Sjoerg                                 COMPONENT ${name})
12377330f729Sjoerg      endif()
12387330f729Sjoerg    endif()
12397330f729Sjoerg  endif()
12407330f729Sjoerg  if( LLVM_BUILD_TOOLS )
12417330f729Sjoerg    set_property(GLOBAL APPEND PROPERTY LLVM_EXPORTS ${name})
12427330f729Sjoerg  endif()
12437330f729Sjoerg  set_target_properties(${name} PROPERTIES FOLDER "Tools")
12447330f729Sjoergendmacro(add_llvm_tool name)
12457330f729Sjoerg
12467330f729Sjoerg
12477330f729Sjoergmacro(add_llvm_example name)
12487330f729Sjoerg  if( NOT LLVM_BUILD_EXAMPLES )
12497330f729Sjoerg    set(EXCLUDE_FROM_ALL ON)
12507330f729Sjoerg  endif()
12517330f729Sjoerg  add_llvm_executable(${name} ${ARGN})
12527330f729Sjoerg  if( LLVM_BUILD_EXAMPLES )
12537330f729Sjoerg    install(TARGETS ${name} RUNTIME DESTINATION examples)
12547330f729Sjoerg  endif()
12557330f729Sjoerg  set_target_properties(${name} PROPERTIES FOLDER "Examples")
12567330f729Sjoergendmacro(add_llvm_example name)
12577330f729Sjoerg
1258*82d56013Sjoergmacro(add_llvm_example_library name)
1259*82d56013Sjoerg  if( NOT LLVM_BUILD_EXAMPLES )
1260*82d56013Sjoerg    set(EXCLUDE_FROM_ALL ON)
1261*82d56013Sjoerg    add_llvm_library(${name} BUILDTREE_ONLY ${ARGN})
1262*82d56013Sjoerg  else()
1263*82d56013Sjoerg    add_llvm_library(${name} ${ARGN})
1264*82d56013Sjoerg  endif()
1265*82d56013Sjoerg
1266*82d56013Sjoerg  set_target_properties(${name} PROPERTIES FOLDER "Examples")
1267*82d56013Sjoergendmacro(add_llvm_example_library name)
1268*82d56013Sjoerg
12697330f729Sjoerg# This is a macro that is used to create targets for executables that are needed
12707330f729Sjoerg# for development, but that are not intended to be installed by default.
12717330f729Sjoergmacro(add_llvm_utility name)
12727330f729Sjoerg  if ( NOT LLVM_BUILD_UTILS )
12737330f729Sjoerg    set(EXCLUDE_FROM_ALL ON)
12747330f729Sjoerg  endif()
12757330f729Sjoerg
12767330f729Sjoerg  add_llvm_executable(${name} DISABLE_LLVM_LINK_LLVM_DYLIB ${ARGN})
12777330f729Sjoerg  set_target_properties(${name} PROPERTIES FOLDER "Utils")
1278*82d56013Sjoerg  if ( ${name} IN_LIST LLVM_TOOLCHAIN_UTILITIES OR NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
12797330f729Sjoerg    if (LLVM_INSTALL_UTILS AND LLVM_BUILD_UTILS)
1280*82d56013Sjoerg      get_target_export_arg(${name} LLVM export_to_llvmexports)
12817330f729Sjoerg      install(TARGETS ${name}
12827330f729Sjoerg              ${export_to_llvmexports}
12837330f729Sjoerg              RUNTIME DESTINATION ${LLVM_UTILS_INSTALL_DIR}
12847330f729Sjoerg              COMPONENT ${name})
12857330f729Sjoerg
12867330f729Sjoerg      if (NOT LLVM_ENABLE_IDE)
12877330f729Sjoerg        add_llvm_install_targets(install-${name}
12887330f729Sjoerg                                 DEPENDS ${name}
12897330f729Sjoerg                                 COMPONENT ${name})
12907330f729Sjoerg      endif()
12917330f729Sjoerg      set_property(GLOBAL APPEND PROPERTY LLVM_EXPORTS ${name})
12927330f729Sjoerg    elseif(LLVM_BUILD_UTILS)
12937330f729Sjoerg      set_property(GLOBAL APPEND PROPERTY LLVM_EXPORTS_BUILDTREE_ONLY ${name})
12947330f729Sjoerg    endif()
12957330f729Sjoerg  endif()
12967330f729Sjoergendmacro(add_llvm_utility name)
12977330f729Sjoerg
12987330f729Sjoergmacro(add_llvm_fuzzer name)
12997330f729Sjoerg  cmake_parse_arguments(ARG "" "DUMMY_MAIN" "" ${ARGN})
13007330f729Sjoerg  if( LLVM_LIB_FUZZING_ENGINE )
13017330f729Sjoerg    set(LLVM_OPTIONAL_SOURCES ${ARG_DUMMY_MAIN})
13027330f729Sjoerg    add_llvm_executable(${name} ${ARG_UNPARSED_ARGUMENTS})
13037330f729Sjoerg    target_link_libraries(${name} PRIVATE ${LLVM_LIB_FUZZING_ENGINE})
13047330f729Sjoerg    set_target_properties(${name} PROPERTIES FOLDER "Fuzzers")
13057330f729Sjoerg  elseif( LLVM_USE_SANITIZE_COVERAGE )
13067330f729Sjoerg    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=fuzzer")
13077330f729Sjoerg    set(LLVM_OPTIONAL_SOURCES ${ARG_DUMMY_MAIN})
13087330f729Sjoerg    add_llvm_executable(${name} ${ARG_UNPARSED_ARGUMENTS})
13097330f729Sjoerg    set_target_properties(${name} PROPERTIES FOLDER "Fuzzers")
13107330f729Sjoerg  elseif( ARG_DUMMY_MAIN )
13117330f729Sjoerg    add_llvm_executable(${name} ${ARG_DUMMY_MAIN} ${ARG_UNPARSED_ARGUMENTS})
13127330f729Sjoerg    set_target_properties(${name} PROPERTIES FOLDER "Fuzzers")
13137330f729Sjoerg  endif()
13147330f729Sjoergendmacro()
13157330f729Sjoerg
13167330f729Sjoergmacro(add_llvm_target target_name)
13177330f729Sjoerg  include_directories(BEFORE
13187330f729Sjoerg    ${CMAKE_CURRENT_BINARY_DIR}
13197330f729Sjoerg    ${CMAKE_CURRENT_SOURCE_DIR})
1320*82d56013Sjoerg  add_llvm_component_library(LLVM${target_name} ${ARGN})
13217330f729Sjoerg  set( CURRENT_LLVM_TARGET LLVM${target_name} )
13227330f729Sjoergendmacro(add_llvm_target)
13237330f729Sjoerg
13247330f729Sjoergfunction(canonicalize_tool_name name output)
13257330f729Sjoerg  string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" nameStrip ${name})
13267330f729Sjoerg  string(REPLACE "-" "_" nameUNDERSCORE ${nameStrip})
13277330f729Sjoerg  string(TOUPPER ${nameUNDERSCORE} nameUPPER)
13287330f729Sjoerg  set(${output} "${nameUPPER}" PARENT_SCOPE)
13297330f729Sjoergendfunction(canonicalize_tool_name)
13307330f729Sjoerg
13317330f729Sjoerg# Custom add_subdirectory wrapper
13327330f729Sjoerg# Takes in a project name (i.e. LLVM), the subdirectory name, and an optional
13337330f729Sjoerg# path if it differs from the name.
13347330f729Sjoergfunction(add_llvm_subdirectory project type name)
13357330f729Sjoerg  set(add_llvm_external_dir "${ARGN}")
13367330f729Sjoerg  if("${add_llvm_external_dir}" STREQUAL "")
13377330f729Sjoerg    set(add_llvm_external_dir ${name})
13387330f729Sjoerg  endif()
13397330f729Sjoerg  canonicalize_tool_name(${name} nameUPPER)
13407330f729Sjoerg  set(canonical_full_name ${project}_${type}_${nameUPPER})
13417330f729Sjoerg  get_property(already_processed GLOBAL PROPERTY ${canonical_full_name}_PROCESSED)
13427330f729Sjoerg  if(already_processed)
13437330f729Sjoerg    return()
13447330f729Sjoerg  endif()
13457330f729Sjoerg  set_property(GLOBAL PROPERTY ${canonical_full_name}_PROCESSED YES)
13467330f729Sjoerg
13477330f729Sjoerg  if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${add_llvm_external_dir}/CMakeLists.txt)
13487330f729Sjoerg    # Treat it as in-tree subproject.
13497330f729Sjoerg    option(${canonical_full_name}_BUILD
13507330f729Sjoerg           "Whether to build ${name} as part of ${project}" On)
13517330f729Sjoerg    mark_as_advanced(${project}_${type}_${name}_BUILD)
13527330f729Sjoerg    if(${canonical_full_name}_BUILD)
13537330f729Sjoerg      add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${add_llvm_external_dir} ${add_llvm_external_dir})
13547330f729Sjoerg    endif()
13557330f729Sjoerg  else()
13567330f729Sjoerg    set(LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR
13577330f729Sjoerg      "${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR}"
13587330f729Sjoerg      CACHE PATH "Path to ${name} source directory")
13597330f729Sjoerg    set(${canonical_full_name}_BUILD_DEFAULT ON)
13607330f729Sjoerg    if(NOT LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR OR NOT EXISTS ${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR})
13617330f729Sjoerg      set(${canonical_full_name}_BUILD_DEFAULT OFF)
13627330f729Sjoerg    endif()
13637330f729Sjoerg    if("${LLVM_EXTERNAL_${nameUPPER}_BUILD}" STREQUAL "OFF")
13647330f729Sjoerg      set(${canonical_full_name}_BUILD_DEFAULT OFF)
13657330f729Sjoerg    endif()
13667330f729Sjoerg    option(${canonical_full_name}_BUILD
13677330f729Sjoerg      "Whether to build ${name} as part of LLVM"
13687330f729Sjoerg      ${${canonical_full_name}_BUILD_DEFAULT})
13697330f729Sjoerg    if (${canonical_full_name}_BUILD)
13707330f729Sjoerg      if(EXISTS ${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR})
13717330f729Sjoerg        add_subdirectory(${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR} ${add_llvm_external_dir})
13727330f729Sjoerg      elseif(NOT "${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR}" STREQUAL "")
13737330f729Sjoerg        message(WARNING "Nonexistent directory for ${name}: ${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR}")
13747330f729Sjoerg      endif()
13757330f729Sjoerg    endif()
13767330f729Sjoerg  endif()
13777330f729Sjoergendfunction()
13787330f729Sjoerg
13797330f729Sjoerg# Add external project that may want to be built as part of llvm such as Clang,
13807330f729Sjoerg# lld, and Polly. This adds two options. One for the source directory of the
13817330f729Sjoerg# project, which defaults to ${CMAKE_CURRENT_SOURCE_DIR}/${name}. Another to
13827330f729Sjoerg# enable or disable building it with everything else.
13837330f729Sjoerg# Additional parameter can be specified as the name of directory.
13847330f729Sjoergmacro(add_llvm_external_project name)
13857330f729Sjoerg  add_llvm_subdirectory(LLVM TOOL ${name} ${ARGN})
13867330f729Sjoergendmacro()
13877330f729Sjoerg
13887330f729Sjoergmacro(add_llvm_tool_subdirectory name)
13897330f729Sjoerg  add_llvm_external_project(${name})
13907330f729Sjoergendmacro(add_llvm_tool_subdirectory)
13917330f729Sjoerg
13927330f729Sjoergfunction(get_project_name_from_src_var var output)
13937330f729Sjoerg  string(REGEX MATCH "LLVM_EXTERNAL_(.*)_SOURCE_DIR"
13947330f729Sjoerg         MACHED_TOOL "${var}")
13957330f729Sjoerg  if(MACHED_TOOL)
13967330f729Sjoerg    set(${output} ${CMAKE_MATCH_1} PARENT_SCOPE)
13977330f729Sjoerg  else()
13987330f729Sjoerg    set(${output} PARENT_SCOPE)
13997330f729Sjoerg  endif()
14007330f729Sjoergendfunction()
14017330f729Sjoerg
14027330f729Sjoergfunction(create_subdirectory_options project type)
14037330f729Sjoerg  file(GLOB sub-dirs "${CMAKE_CURRENT_SOURCE_DIR}/*")
14047330f729Sjoerg  foreach(dir ${sub-dirs})
14057330f729Sjoerg    if(IS_DIRECTORY "${dir}" AND EXISTS "${dir}/CMakeLists.txt")
14067330f729Sjoerg      canonicalize_tool_name(${dir} name)
14077330f729Sjoerg      option(${project}_${type}_${name}_BUILD
14087330f729Sjoerg           "Whether to build ${name} as part of ${project}" On)
14097330f729Sjoerg      mark_as_advanced(${project}_${type}_${name}_BUILD)
14107330f729Sjoerg    endif()
14117330f729Sjoerg  endforeach()
14127330f729Sjoergendfunction(create_subdirectory_options)
14137330f729Sjoerg
14147330f729Sjoergfunction(create_llvm_tool_options)
14157330f729Sjoerg  create_subdirectory_options(LLVM TOOL)
14167330f729Sjoergendfunction(create_llvm_tool_options)
14177330f729Sjoerg
14187330f729Sjoergfunction(llvm_add_implicit_projects project)
14197330f729Sjoerg  set(list_of_implicit_subdirs "")
14207330f729Sjoerg  file(GLOB sub-dirs "${CMAKE_CURRENT_SOURCE_DIR}/*")
14217330f729Sjoerg  foreach(dir ${sub-dirs})
14227330f729Sjoerg    if(IS_DIRECTORY "${dir}" AND EXISTS "${dir}/CMakeLists.txt")
14237330f729Sjoerg      canonicalize_tool_name(${dir} name)
14247330f729Sjoerg      if (${project}_TOOL_${name}_BUILD)
14257330f729Sjoerg        get_filename_component(fn "${dir}" NAME)
14267330f729Sjoerg        list(APPEND list_of_implicit_subdirs "${fn}")
14277330f729Sjoerg      endif()
14287330f729Sjoerg    endif()
14297330f729Sjoerg  endforeach()
14307330f729Sjoerg
14317330f729Sjoerg  foreach(external_proj ${list_of_implicit_subdirs})
14327330f729Sjoerg    add_llvm_subdirectory(${project} TOOL "${external_proj}" ${ARGN})
14337330f729Sjoerg  endforeach()
14347330f729Sjoergendfunction(llvm_add_implicit_projects)
14357330f729Sjoerg
14367330f729Sjoergfunction(add_llvm_implicit_projects)
14377330f729Sjoerg  llvm_add_implicit_projects(LLVM)
14387330f729Sjoergendfunction(add_llvm_implicit_projects)
14397330f729Sjoerg
14407330f729Sjoerg# Generic support for adding a unittest.
14417330f729Sjoergfunction(add_unittest test_suite test_name)
14427330f729Sjoerg  if( NOT LLVM_BUILD_TESTS )
14437330f729Sjoerg    set(EXCLUDE_FROM_ALL ON)
14447330f729Sjoerg  endif()
14457330f729Sjoerg
14467330f729Sjoerg  if (SUPPORTS_VARIADIC_MACROS_FLAG)
14477330f729Sjoerg    list(APPEND LLVM_COMPILE_FLAGS "-Wno-variadic-macros")
14487330f729Sjoerg  endif ()
14497330f729Sjoerg  # Some parts of gtest rely on this GNU extension, don't warn on it.
14507330f729Sjoerg  if(SUPPORTS_GNU_ZERO_VARIADIC_MACRO_ARGUMENTS_FLAG)
14517330f729Sjoerg    list(APPEND LLVM_COMPILE_FLAGS "-Wno-gnu-zero-variadic-macro-arguments")
14527330f729Sjoerg  endif()
14537330f729Sjoerg
14547330f729Sjoerg  set(LLVM_REQUIRES_RTTI OFF)
14557330f729Sjoerg
14567330f729Sjoerg  list(APPEND LLVM_LINK_COMPONENTS Support) # gtest needs it for raw_ostream
14577330f729Sjoerg  add_llvm_executable(${test_name} IGNORE_EXTERNALIZE_DEBUGINFO NO_INSTALL_RPATH ${ARGN})
1458*82d56013Sjoerg
1459*82d56013Sjoerg  # The runtime benefits of LTO don't outweight the compile time costs for tests.
1460*82d56013Sjoerg  if(LLVM_ENABLE_LTO)
1461*82d56013Sjoerg    if((UNIX OR MINGW) AND LLVM_USE_LINKER STREQUAL "lld")
1462*82d56013Sjoerg      set_property(TARGET ${test_name} APPEND_STRING PROPERTY
1463*82d56013Sjoerg                    LINK_FLAGS " -Wl,--lto-O0")
1464*82d56013Sjoerg    elseif(LINKER_IS_LLD_LINK)
1465*82d56013Sjoerg      set_property(TARGET ${test_name} APPEND_STRING PROPERTY
1466*82d56013Sjoerg                    LINK_FLAGS " /opt:lldlto=0")
1467*82d56013Sjoerg    endif()
1468*82d56013Sjoerg  endif()
1469*82d56013Sjoerg
14707330f729Sjoerg  set(outdir ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR})
14717330f729Sjoerg  set_output_directory(${test_name} BINARY_DIR ${outdir} LIBRARY_DIR ${outdir})
14727330f729Sjoerg  # libpthreads overrides some standard library symbols, so main
14737330f729Sjoerg  # executable must be linked with it in order to provide consistent
14747330f729Sjoerg  # API for all shared libaries loaded by this executable.
14757330f729Sjoerg  target_link_libraries(${test_name} PRIVATE gtest_main gtest ${LLVM_PTHREAD_LIB})
14767330f729Sjoerg
14777330f729Sjoerg  add_dependencies(${test_suite} ${test_name})
14787330f729Sjoerg  get_target_property(test_suite_folder ${test_suite} FOLDER)
1479*82d56013Sjoerg  if (test_suite_folder)
14807330f729Sjoerg    set_property(TARGET ${test_name} PROPERTY FOLDER "${test_suite_folder}")
14817330f729Sjoerg  endif ()
14827330f729Sjoergendfunction()
14837330f729Sjoerg
14847330f729Sjoerg# Use for test binaries that call llvm::getInputFileDirectory(). Use of this
14857330f729Sjoerg# is discouraged.
14867330f729Sjoergfunction(add_unittest_with_input_files test_suite test_name)
14877330f729Sjoerg  set(LLVM_UNITTEST_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
14887330f729Sjoerg  configure_file(
14897330f729Sjoerg    ${LLVM_MAIN_SRC_DIR}/unittests/unittest.cfg.in
14907330f729Sjoerg    ${CMAKE_CURRENT_BINARY_DIR}/llvm.srcdir.txt)
14917330f729Sjoerg
14927330f729Sjoerg  add_unittest(${test_suite} ${test_name} ${ARGN})
14937330f729Sjoergendfunction()
14947330f729Sjoerg
14957330f729Sjoerg# Generic support for adding a benchmark.
14967330f729Sjoergfunction(add_benchmark benchmark_name)
14977330f729Sjoerg  if( NOT LLVM_BUILD_BENCHMARKS )
14987330f729Sjoerg    set(EXCLUDE_FROM_ALL ON)
14997330f729Sjoerg  endif()
15007330f729Sjoerg
15017330f729Sjoerg  add_llvm_executable(${benchmark_name} IGNORE_EXTERNALIZE_DEBUGINFO NO_INSTALL_RPATH ${ARGN})
15027330f729Sjoerg  set(outdir ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR})
15037330f729Sjoerg  set_output_directory(${benchmark_name} BINARY_DIR ${outdir} LIBRARY_DIR ${outdir})
15047330f729Sjoerg  set_property(TARGET ${benchmark_name} PROPERTY FOLDER "Utils")
15057330f729Sjoerg  target_link_libraries(${benchmark_name} PRIVATE benchmark)
15067330f729Sjoergendfunction()
15077330f729Sjoerg
15087330f729Sjoerg# This function canonicalize the CMake variables passed by names
15097330f729Sjoerg# from CMake boolean to 0/1 suitable for passing into Python or C++,
15107330f729Sjoerg# in place.
15117330f729Sjoergfunction(llvm_canonicalize_cmake_booleans)
15127330f729Sjoerg  foreach(var ${ARGN})
15137330f729Sjoerg    if(${var})
15147330f729Sjoerg      set(${var} 1 PARENT_SCOPE)
15157330f729Sjoerg    else()
15167330f729Sjoerg      set(${var} 0 PARENT_SCOPE)
15177330f729Sjoerg    endif()
15187330f729Sjoerg  endforeach()
15197330f729Sjoergendfunction(llvm_canonicalize_cmake_booleans)
15207330f729Sjoerg
15217330f729Sjoergmacro(set_llvm_build_mode)
15227330f729Sjoerg  # Configuration-time: See Unit/lit.site.cfg.in
15237330f729Sjoerg  if (CMAKE_CFG_INTDIR STREQUAL ".")
15247330f729Sjoerg    set(LLVM_BUILD_MODE ".")
15257330f729Sjoerg  else ()
15267330f729Sjoerg    set(LLVM_BUILD_MODE "%(build_mode)s")
15277330f729Sjoerg  endif ()
15287330f729Sjoergendmacro()
15297330f729Sjoerg
1530*82d56013Sjoerg# Takes a list of path names in pathlist and a base directory, and returns
1531*82d56013Sjoerg# a list of paths relative to the base directory in out_pathlist.
1532*82d56013Sjoerg# Paths that are on a different drive than the basedir (on Windows) or that
1533*82d56013Sjoerg# contain symlinks are returned absolute.
1534*82d56013Sjoerg# Use with LLVM_LIT_PATH_FUNCTION below.
1535*82d56013Sjoergfunction(make_paths_relative out_pathlist basedir pathlist)
1536*82d56013Sjoerg  # Passing ARG_PATH_VALUES as-is to execute_process() makes cmake strip
1537*82d56013Sjoerg  # empty list entries. So escape the ;s in the list and do the splitting
1538*82d56013Sjoerg  # ourselves. cmake has no relpath function, so use Python for that.
1539*82d56013Sjoerg  string(REPLACE ";" "\\;" pathlist_escaped "${pathlist}")
1540*82d56013Sjoerg  execute_process(COMMAND "${Python3_EXECUTABLE}" "-c" "\n
1541*82d56013Sjoergimport os, sys\n
1542*82d56013Sjoergbase = sys.argv[1]
1543*82d56013Sjoergdef haslink(p):\n
1544*82d56013Sjoerg    if not p or p == os.path.dirname(p): return False\n
1545*82d56013Sjoerg    return os.path.islink(p) or haslink(os.path.dirname(p))\n
1546*82d56013Sjoergdef relpath(p):\n
1547*82d56013Sjoerg    if not p: return ''\n
1548*82d56013Sjoerg    if os.path.splitdrive(p)[0] != os.path.splitdrive(base)[0]: return p\n
1549*82d56013Sjoerg    if haslink(p) or haslink(base): return p\n
1550*82d56013Sjoerg    return os.path.relpath(p, base)\n
1551*82d56013Sjoergif len(sys.argv) < 3: sys.exit(0)\n
1552*82d56013Sjoergsys.stdout.write(';'.join(relpath(p) for p in sys.argv[2].split(';')))"
1553*82d56013Sjoerg    ${basedir}
1554*82d56013Sjoerg    ${pathlist_escaped}
1555*82d56013Sjoerg    OUTPUT_VARIABLE pathlist_relative
1556*82d56013Sjoerg    ERROR_VARIABLE error
1557*82d56013Sjoerg    RESULT_VARIABLE result)
1558*82d56013Sjoerg  if (NOT result EQUAL 0)
1559*82d56013Sjoerg    message(FATAL_ERROR "make_paths_relative() failed due to error '${result}', with stderr\n${error}")
1560*82d56013Sjoerg  endif()
1561*82d56013Sjoerg  set(${out_pathlist} "${pathlist_relative}" PARENT_SCOPE)
1562*82d56013Sjoergendfunction()
1563*82d56013Sjoerg
1564*82d56013Sjoerg# Converts a file that's relative to the current python file to an absolute
1565*82d56013Sjoerg# path. Since this uses __file__, it has to be emitted into python files that
1566*82d56013Sjoerg# use it and can't be in a lit module. Use with make_paths_relative().
1567*82d56013Sjoergstring(CONCAT LLVM_LIT_PATH_FUNCTION
1568*82d56013Sjoerg  "# Allow generated file to be relocatable.\n"
1569*82d56013Sjoerg  "def path(p):\n"
1570*82d56013Sjoerg  "    if not p: return ''\n"
1571*82d56013Sjoerg  "    return os.path.join(os.path.dirname(os.path.abspath(__file__)), p)\n"
1572*82d56013Sjoerg  )
1573*82d56013Sjoerg
15747330f729Sjoerg# This function provides an automatic way to 'configure'-like generate a file
15757330f729Sjoerg# based on a set of common and custom variables, specifically targeting the
15767330f729Sjoerg# variables needed for the 'lit.site.cfg' files. This function bundles the
15777330f729Sjoerg# common variables that any Lit instance is likely to need, and custom
15787330f729Sjoerg# variables can be passed in.
1579*82d56013Sjoerg# The keyword PATHS is followed by a list of cmake variable names that are
1580*82d56013Sjoerg# mentioned as `path("@varname@")` in the lit.cfg.py.in file. Variables in that
1581*82d56013Sjoerg# list are treated as paths that are relative to the directory the generated
1582*82d56013Sjoerg# lit.cfg.py file is in, and the `path()` function converts the relative
1583*82d56013Sjoerg# path back to absolute form. This makes it possible to move a build directory
1584*82d56013Sjoerg# containing lit.cfg.py files from one machine to another.
15857330f729Sjoergfunction(configure_lit_site_cfg site_in site_out)
1586*82d56013Sjoerg  cmake_parse_arguments(ARG "" "" "MAIN_CONFIG;OUTPUT_MAPPING;PATHS" ${ARGN})
15877330f729Sjoerg
15887330f729Sjoerg  if ("${ARG_MAIN_CONFIG}" STREQUAL "")
15897330f729Sjoerg    get_filename_component(INPUT_DIR ${site_in} DIRECTORY)
15907330f729Sjoerg    set(ARG_MAIN_CONFIG "${INPUT_DIR}/lit.cfg")
15917330f729Sjoerg  endif()
15927330f729Sjoerg  if ("${ARG_OUTPUT_MAPPING}" STREQUAL "")
15937330f729Sjoerg    set(ARG_OUTPUT_MAPPING "${site_out}")
15947330f729Sjoerg  endif()
15957330f729Sjoerg
15967330f729Sjoerg  foreach(c ${LLVM_TARGETS_TO_BUILD})
15977330f729Sjoerg    set(TARGETS_BUILT "${TARGETS_BUILT} ${c}")
15987330f729Sjoerg  endforeach(c)
15997330f729Sjoerg  set(TARGETS_TO_BUILD ${TARGETS_BUILT})
16007330f729Sjoerg
16017330f729Sjoerg  set(SHLIBEXT "${LTDL_SHLIB_EXT}")
16027330f729Sjoerg
16037330f729Sjoerg  set_llvm_build_mode()
16047330f729Sjoerg
1605*82d56013Sjoerg  # The below might not be the build tree but provided binary tree.
16067330f729Sjoerg  set(LLVM_SOURCE_DIR ${LLVM_MAIN_SRC_DIR})
16077330f729Sjoerg  set(LLVM_BINARY_DIR ${LLVM_BINARY_DIR})
16087330f729Sjoerg  string(REPLACE "${CMAKE_CFG_INTDIR}" "${LLVM_BUILD_MODE}" LLVM_TOOLS_DIR "${LLVM_TOOLS_BINARY_DIR}")
1609*82d56013Sjoerg  string(REPLACE "${CMAKE_CFG_INTDIR}" "${LLVM_BUILD_MODE}" LLVM_LIBS_DIR  "${LLVM_LIBRARY_DIR}")
16107330f729Sjoerg
16117330f729Sjoerg  # SHLIBDIR points the build tree.
16127330f729Sjoerg  string(REPLACE "${CMAKE_CFG_INTDIR}" "${LLVM_BUILD_MODE}" SHLIBDIR "${LLVM_SHLIB_OUTPUT_INTDIR}")
16137330f729Sjoerg
16147330f729Sjoerg  # FIXME: "ENABLE_SHARED" doesn't make sense, since it is used just for
16157330f729Sjoerg  # plugins. We may rename it.
16167330f729Sjoerg  if(LLVM_ENABLE_PLUGINS)
16177330f729Sjoerg    set(ENABLE_SHARED "1")
16187330f729Sjoerg  else()
16197330f729Sjoerg    set(ENABLE_SHARED "0")
16207330f729Sjoerg  endif()
16217330f729Sjoerg
16227330f729Sjoerg  if(LLVM_ENABLE_ASSERTIONS AND NOT MSVC_IDE)
16237330f729Sjoerg    set(ENABLE_ASSERTIONS "1")
16247330f729Sjoerg  else()
16257330f729Sjoerg    set(ENABLE_ASSERTIONS "0")
16267330f729Sjoerg  endif()
16277330f729Sjoerg
16287330f729Sjoerg  set(HOST_OS ${CMAKE_SYSTEM_NAME})
16297330f729Sjoerg  set(HOST_ARCH ${CMAKE_SYSTEM_PROCESSOR})
16307330f729Sjoerg
16317330f729Sjoerg  set(HOST_CC "${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1}")
16327330f729Sjoerg  set(HOST_CXX "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1}")
16337330f729Sjoerg  set(HOST_LDFLAGS "${CMAKE_EXE_LINKER_FLAGS}")
16347330f729Sjoerg
1635*82d56013Sjoerg  string(CONCAT LIT_SITE_CFG_IN_HEADER
1636*82d56013Sjoerg    "# Autogenerated from ${site_in}\n# Do not edit!\n\n"
1637*82d56013Sjoerg    "${LLVM_LIT_PATH_FUNCTION}"
1638*82d56013Sjoerg    )
16397330f729Sjoerg
16407330f729Sjoerg  # Override config_target_triple (and the env)
16417330f729Sjoerg  if(LLVM_TARGET_TRIPLE_ENV)
16427330f729Sjoerg    # This is expanded into the heading.
1643*82d56013Sjoerg    string(CONCAT LIT_SITE_CFG_IN_HEADER "${LIT_SITE_CFG_IN_HEADER}"
16447330f729Sjoerg      "import os\n"
16457330f729Sjoerg      "target_env = \"${LLVM_TARGET_TRIPLE_ENV}\"\n"
16467330f729Sjoerg      "config.target_triple = config.environment[target_env] = os.environ.get(target_env, \"${TARGET_TRIPLE}\")\n"
16477330f729Sjoerg      )
16487330f729Sjoerg
16497330f729Sjoerg    # This is expanded to; config.target_triple = ""+config.target_triple+""
16507330f729Sjoerg    set(TARGET_TRIPLE "\"+config.target_triple+\"")
16517330f729Sjoerg  endif()
16527330f729Sjoerg
1653*82d56013Sjoerg  if (ARG_PATHS)
1654*82d56013Sjoerg    # Walk ARG_PATHS and collect the current value of the variables in there.
1655*82d56013Sjoerg    # list(APPEND) ignores empty elements exactly if the list is empty,
1656*82d56013Sjoerg    # so start the list with a dummy element and drop it, to make sure that
1657*82d56013Sjoerg    # even empty values make it into the values list.
1658*82d56013Sjoerg    set(ARG_PATH_VALUES "dummy")
1659*82d56013Sjoerg    foreach(path ${ARG_PATHS})
1660*82d56013Sjoerg      list(APPEND ARG_PATH_VALUES "${${path}}")
1661*82d56013Sjoerg    endforeach()
1662*82d56013Sjoerg    list(REMOVE_AT ARG_PATH_VALUES 0)
1663*82d56013Sjoerg
1664*82d56013Sjoerg    get_filename_component(OUTPUT_DIR ${site_out} DIRECTORY)
1665*82d56013Sjoerg    make_paths_relative(
1666*82d56013Sjoerg        ARG_PATH_VALUES_RELATIVE "${OUTPUT_DIR}" "${ARG_PATH_VALUES}")
1667*82d56013Sjoerg
1668*82d56013Sjoerg    list(LENGTH ARG_PATHS len_paths)
1669*82d56013Sjoerg    list(LENGTH ARG_PATH_VALUES len_path_values)
1670*82d56013Sjoerg    list(LENGTH ARG_PATH_VALUES_RELATIVE len_path_value_rels)
1671*82d56013Sjoerg    if ((NOT ${len_paths} EQUAL ${len_path_values}) OR
1672*82d56013Sjoerg        (NOT ${len_paths} EQUAL ${len_path_value_rels}))
1673*82d56013Sjoerg      message(SEND_ERROR "PATHS lengths got confused")
1674*82d56013Sjoerg    endif()
1675*82d56013Sjoerg
1676*82d56013Sjoerg    # Transform variables mentioned in ARG_PATHS to relative paths for
1677*82d56013Sjoerg    # the configure_file() call. Variables are copied to subscopeds by cmake,
1678*82d56013Sjoerg    # so this only modifies the local copy of the variables.
1679*82d56013Sjoerg    math(EXPR arg_path_limit "${len_paths} - 1")
1680*82d56013Sjoerg    foreach(i RANGE ${arg_path_limit})
1681*82d56013Sjoerg      list(GET ARG_PATHS ${i} val1)
1682*82d56013Sjoerg      list(GET ARG_PATH_VALUES_RELATIVE ${i} val2)
1683*82d56013Sjoerg      set(${val1} ${val2})
1684*82d56013Sjoerg    endforeach()
1685*82d56013Sjoerg  endif()
1686*82d56013Sjoerg
16877330f729Sjoerg  configure_file(${site_in} ${site_out} @ONLY)
1688*82d56013Sjoerg
16897330f729Sjoerg  if (EXISTS "${ARG_MAIN_CONFIG}")
1690*82d56013Sjoerg    # Remember main config / generated site config for llvm-lit.in.
1691*82d56013Sjoerg    get_property(LLVM_LIT_CONFIG_FILES GLOBAL PROPERTY LLVM_LIT_CONFIG_FILES)
1692*82d56013Sjoerg    list(APPEND LLVM_LIT_CONFIG_FILES "${ARG_MAIN_CONFIG}" "${site_out}")
1693*82d56013Sjoerg    set_property(GLOBAL PROPERTY LLVM_LIT_CONFIG_FILES ${LLVM_LIT_CONFIG_FILES})
16947330f729Sjoerg  endif()
16957330f729Sjoergendfunction()
16967330f729Sjoerg
16977330f729Sjoergfunction(dump_all_cmake_variables)
16987330f729Sjoerg  get_cmake_property(_variableNames VARIABLES)
16997330f729Sjoerg  foreach (_variableName ${_variableNames})
17007330f729Sjoerg    message(STATUS "${_variableName}=${${_variableName}}")
17017330f729Sjoerg  endforeach()
17027330f729Sjoergendfunction()
17037330f729Sjoerg
17047330f729Sjoergfunction(get_llvm_lit_path base_dir file_name)
17057330f729Sjoerg  cmake_parse_arguments(ARG "ALLOW_EXTERNAL" "" "" ${ARGN})
17067330f729Sjoerg
17077330f729Sjoerg  if (ARG_ALLOW_EXTERNAL)
17087330f729Sjoerg    set (LLVM_EXTERNAL_LIT "" CACHE STRING "Command used to spawn lit")
17097330f729Sjoerg    if ("${LLVM_EXTERNAL_LIT}" STREQUAL "")
17107330f729Sjoerg      set(LLVM_EXTERNAL_LIT "${LLVM_DEFAULT_EXTERNAL_LIT}")
17117330f729Sjoerg    endif()
17127330f729Sjoerg
17137330f729Sjoerg    if (NOT "${LLVM_EXTERNAL_LIT}" STREQUAL "")
17147330f729Sjoerg      if (EXISTS ${LLVM_EXTERNAL_LIT})
17157330f729Sjoerg        get_filename_component(LIT_FILE_NAME ${LLVM_EXTERNAL_LIT} NAME)
17167330f729Sjoerg        get_filename_component(LIT_BASE_DIR ${LLVM_EXTERNAL_LIT} DIRECTORY)
17177330f729Sjoerg        set(${file_name} ${LIT_FILE_NAME} PARENT_SCOPE)
17187330f729Sjoerg        set(${base_dir} ${LIT_BASE_DIR} PARENT_SCOPE)
17197330f729Sjoerg        return()
1720*82d56013Sjoerg      elseif (NOT DEFINED CACHE{LLVM_EXTERNAL_LIT_MISSING_WARNED_ONCE})
17217330f729Sjoerg        message(WARNING "LLVM_EXTERNAL_LIT set to ${LLVM_EXTERNAL_LIT}, but the path does not exist.")
1722*82d56013Sjoerg        set(LLVM_EXTERNAL_LIT_MISSING_WARNED_ONCE YES CACHE INTERNAL "")
17237330f729Sjoerg      endif()
17247330f729Sjoerg    endif()
17257330f729Sjoerg  endif()
17267330f729Sjoerg
17277330f729Sjoerg  set(lit_file_name "llvm-lit")
17287330f729Sjoerg  if (CMAKE_HOST_WIN32 AND NOT CYGWIN)
17297330f729Sjoerg    # llvm-lit needs suffix.py for multiprocess to find a main module.
17307330f729Sjoerg    set(lit_file_name "${lit_file_name}.py")
17317330f729Sjoerg  endif ()
17327330f729Sjoerg  set(${file_name} ${lit_file_name} PARENT_SCOPE)
17337330f729Sjoerg
17347330f729Sjoerg  get_property(LLVM_LIT_BASE_DIR GLOBAL PROPERTY LLVM_LIT_BASE_DIR)
17357330f729Sjoerg  if (NOT "${LLVM_LIT_BASE_DIR}" STREQUAL "")
17367330f729Sjoerg    set(${base_dir} ${LLVM_LIT_BASE_DIR} PARENT_SCOPE)
17377330f729Sjoerg  endif()
17387330f729Sjoerg
17397330f729Sjoerg  # Allow individual projects to provide an override
17407330f729Sjoerg  if (NOT "${LLVM_LIT_OUTPUT_DIR}" STREQUAL "")
17417330f729Sjoerg    set(LLVM_LIT_BASE_DIR ${LLVM_LIT_OUTPUT_DIR})
17427330f729Sjoerg  elseif(NOT "${LLVM_RUNTIME_OUTPUT_INTDIR}" STREQUAL "")
17437330f729Sjoerg    set(LLVM_LIT_BASE_DIR ${LLVM_RUNTIME_OUTPUT_INTDIR})
17447330f729Sjoerg  else()
17457330f729Sjoerg    set(LLVM_LIT_BASE_DIR "")
17467330f729Sjoerg  endif()
17477330f729Sjoerg
17487330f729Sjoerg  # Cache this so we don't have to do it again and have subsequent calls
17497330f729Sjoerg  # potentially disagree on the value.
17507330f729Sjoerg  set_property(GLOBAL PROPERTY LLVM_LIT_BASE_DIR ${LLVM_LIT_BASE_DIR})
17517330f729Sjoerg  set(${base_dir} ${LLVM_LIT_BASE_DIR} PARENT_SCOPE)
17527330f729Sjoergendfunction()
17537330f729Sjoerg
17547330f729Sjoerg# A raw function to create a lit target. This is used to implement the testuite
17557330f729Sjoerg# management functions.
17567330f729Sjoergfunction(add_lit_target target comment)
17577330f729Sjoerg  cmake_parse_arguments(ARG "" "" "PARAMS;DEPENDS;ARGS" ${ARGN})
17587330f729Sjoerg  set(LIT_ARGS "${ARG_ARGS} ${LLVM_LIT_ARGS}")
17597330f729Sjoerg  separate_arguments(LIT_ARGS)
17607330f729Sjoerg  if (NOT CMAKE_CFG_INTDIR STREQUAL ".")
17617330f729Sjoerg    list(APPEND LIT_ARGS --param build_mode=${CMAKE_CFG_INTDIR})
17627330f729Sjoerg  endif ()
17637330f729Sjoerg
17647330f729Sjoerg  # Get the path to the lit to *run* tests with.  This can be overriden by
17657330f729Sjoerg  # the user by specifying -DLLVM_EXTERNAL_LIT=<path-to-lit.py>
17667330f729Sjoerg  get_llvm_lit_path(
17677330f729Sjoerg    lit_base_dir
17687330f729Sjoerg    lit_file_name
17697330f729Sjoerg    ALLOW_EXTERNAL
17707330f729Sjoerg    )
17717330f729Sjoerg
1772*82d56013Sjoerg  set(LIT_COMMAND "${Python3_EXECUTABLE};${lit_base_dir}/${lit_file_name}")
17737330f729Sjoerg  list(APPEND LIT_COMMAND ${LIT_ARGS})
17747330f729Sjoerg  foreach(param ${ARG_PARAMS})
17757330f729Sjoerg    list(APPEND LIT_COMMAND --param ${param})
17767330f729Sjoerg  endforeach()
17777330f729Sjoerg  if (ARG_UNPARSED_ARGUMENTS)
17787330f729Sjoerg    add_custom_target(${target}
17797330f729Sjoerg      COMMAND ${LIT_COMMAND} ${ARG_UNPARSED_ARGUMENTS}
17807330f729Sjoerg      COMMENT "${comment}"
17817330f729Sjoerg      USES_TERMINAL
17827330f729Sjoerg      )
17837330f729Sjoerg  else()
17847330f729Sjoerg    add_custom_target(${target}
17857330f729Sjoerg      COMMAND ${CMAKE_COMMAND} -E echo "${target} does nothing, no tools built.")
17867330f729Sjoerg    message(STATUS "${target} does nothing.")
17877330f729Sjoerg  endif()
17887330f729Sjoerg
17897330f729Sjoerg  if (ARG_DEPENDS)
17907330f729Sjoerg    add_dependencies(${target} ${ARG_DEPENDS})
17917330f729Sjoerg  endif()
17927330f729Sjoerg
17937330f729Sjoerg  # Tests should be excluded from "Build Solution".
17947330f729Sjoerg  set_target_properties(${target} PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD ON)
17957330f729Sjoergendfunction()
17967330f729Sjoerg
17977330f729Sjoerg# A function to add a set of lit test suites to be driven through 'check-*' targets.
17987330f729Sjoergfunction(add_lit_testsuite target comment)
1799*82d56013Sjoerg  cmake_parse_arguments(ARG "EXCLUDE_FROM_CHECK_ALL" "" "PARAMS;DEPENDS;ARGS" ${ARGN})
18007330f729Sjoerg
18017330f729Sjoerg  # EXCLUDE_FROM_ALL excludes the test ${target} out of check-all.
1802*82d56013Sjoerg  if(NOT ARG_EXCLUDE_FROM_CHECK_ALL)
18037330f729Sjoerg    # Register the testsuites, params and depends for the global check rule.
18047330f729Sjoerg    set_property(GLOBAL APPEND PROPERTY LLVM_LIT_TESTSUITES ${ARG_UNPARSED_ARGUMENTS})
18057330f729Sjoerg    set_property(GLOBAL APPEND PROPERTY LLVM_LIT_PARAMS ${ARG_PARAMS})
18067330f729Sjoerg    set_property(GLOBAL APPEND PROPERTY LLVM_LIT_DEPENDS ${ARG_DEPENDS})
18077330f729Sjoerg    set_property(GLOBAL APPEND PROPERTY LLVM_LIT_EXTRA_ARGS ${ARG_ARGS})
18087330f729Sjoerg  endif()
18097330f729Sjoerg
18107330f729Sjoerg  # Produce a specific suffixed check rule.
18117330f729Sjoerg  add_lit_target(${target} ${comment}
18127330f729Sjoerg    ${ARG_UNPARSED_ARGUMENTS}
18137330f729Sjoerg    PARAMS ${ARG_PARAMS}
18147330f729Sjoerg    DEPENDS ${ARG_DEPENDS}
18157330f729Sjoerg    ARGS ${ARG_ARGS}
18167330f729Sjoerg    )
18177330f729Sjoergendfunction()
18187330f729Sjoerg
18197330f729Sjoergfunction(add_lit_testsuites project directory)
18207330f729Sjoerg  if (NOT LLVM_ENABLE_IDE)
1821*82d56013Sjoerg    cmake_parse_arguments(ARG "EXCLUDE_FROM_CHECK_ALL" "" "PARAMS;DEPENDS;ARGS" ${ARGN})
18227330f729Sjoerg
18237330f729Sjoerg    # Search recursively for test directories by assuming anything not
18247330f729Sjoerg    # in a directory called Inputs contains tests.
18257330f729Sjoerg    file(GLOB_RECURSE to_process LIST_DIRECTORIES true ${directory}/*)
18267330f729Sjoerg    foreach(lit_suite ${to_process})
18277330f729Sjoerg      if(NOT IS_DIRECTORY ${lit_suite})
18287330f729Sjoerg        continue()
18297330f729Sjoerg      endif()
18307330f729Sjoerg      string(FIND ${lit_suite} Inputs is_inputs)
18317330f729Sjoerg      string(FIND ${lit_suite} Output is_output)
18327330f729Sjoerg      if (NOT (is_inputs EQUAL -1 AND is_output EQUAL -1))
18337330f729Sjoerg        continue()
18347330f729Sjoerg      endif()
18357330f729Sjoerg
18367330f729Sjoerg      # Create a check- target for the directory.
18377330f729Sjoerg      string(REPLACE ${directory} "" name_slash ${lit_suite})
18387330f729Sjoerg      if (name_slash)
18397330f729Sjoerg        string(REPLACE "/" "-" name_slash ${name_slash})
18407330f729Sjoerg        string(REPLACE "\\" "-" name_dashes ${name_slash})
18417330f729Sjoerg        string(TOLOWER "${project}${name_dashes}" name_var)
18427330f729Sjoerg        add_lit_target("check-${name_var}" "Running lit suite ${lit_suite}"
18437330f729Sjoerg          ${lit_suite}
1844*82d56013Sjoerg          ${EXCLUDE_FROM_CHECK_ALL}
18457330f729Sjoerg          PARAMS ${ARG_PARAMS}
18467330f729Sjoerg          DEPENDS ${ARG_DEPENDS}
18477330f729Sjoerg          ARGS ${ARG_ARGS}
18487330f729Sjoerg        )
18497330f729Sjoerg      endif()
18507330f729Sjoerg    endforeach()
18517330f729Sjoerg  endif()
18527330f729Sjoergendfunction()
18537330f729Sjoerg
18547330f729Sjoergfunction(llvm_install_library_symlink name dest type)
1855*82d56013Sjoerg  cmake_parse_arguments(ARG "" "COMPONENT" "" ${ARGN})
18567330f729Sjoerg  foreach(path ${CMAKE_MODULE_PATH})
18577330f729Sjoerg    if(EXISTS ${path}/LLVMInstallSymlink.cmake)
18587330f729Sjoerg      set(INSTALL_SYMLINK ${path}/LLVMInstallSymlink.cmake)
18597330f729Sjoerg      break()
18607330f729Sjoerg    endif()
18617330f729Sjoerg  endforeach()
18627330f729Sjoerg
18637330f729Sjoerg  set(component ${ARG_COMPONENT})
18647330f729Sjoerg  if(NOT component)
18657330f729Sjoerg    set(component ${name})
18667330f729Sjoerg  endif()
18677330f729Sjoerg
18687330f729Sjoerg  set(full_name ${CMAKE_${type}_LIBRARY_PREFIX}${name}${CMAKE_${type}_LIBRARY_SUFFIX})
18697330f729Sjoerg  set(full_dest ${CMAKE_${type}_LIBRARY_PREFIX}${dest}${CMAKE_${type}_LIBRARY_SUFFIX})
18707330f729Sjoerg
18717330f729Sjoerg  set(output_dir lib${LLVM_LIBDIR_SUFFIX})
18727330f729Sjoerg  if(WIN32 AND "${type}" STREQUAL "SHARED")
18737330f729Sjoerg    set(output_dir bin)
18747330f729Sjoerg  endif()
18757330f729Sjoerg
18767330f729Sjoerg  install(SCRIPT ${INSTALL_SYMLINK}
18777330f729Sjoerg          CODE "install_symlink(${full_name} ${full_dest} ${output_dir})"
18787330f729Sjoerg          COMPONENT ${component})
18797330f729Sjoerg
18807330f729Sjoergendfunction()
18817330f729Sjoerg
18827330f729Sjoergfunction(llvm_install_symlink name dest)
18837330f729Sjoerg  cmake_parse_arguments(ARG "ALWAYS_GENERATE" "COMPONENT" "" ${ARGN})
18847330f729Sjoerg  foreach(path ${CMAKE_MODULE_PATH})
18857330f729Sjoerg    if(EXISTS ${path}/LLVMInstallSymlink.cmake)
18867330f729Sjoerg      set(INSTALL_SYMLINK ${path}/LLVMInstallSymlink.cmake)
18877330f729Sjoerg      break()
18887330f729Sjoerg    endif()
18897330f729Sjoerg  endforeach()
18907330f729Sjoerg
18917330f729Sjoerg  if(ARG_COMPONENT)
18927330f729Sjoerg    set(component ${ARG_COMPONENT})
18937330f729Sjoerg  else()
18947330f729Sjoerg    if(ARG_ALWAYS_GENERATE)
18957330f729Sjoerg      set(component ${dest})
18967330f729Sjoerg    else()
18977330f729Sjoerg      set(component ${name})
18987330f729Sjoerg    endif()
18997330f729Sjoerg  endif()
19007330f729Sjoerg
19017330f729Sjoerg  set(full_name ${name}${CMAKE_EXECUTABLE_SUFFIX})
19027330f729Sjoerg  set(full_dest ${dest}${CMAKE_EXECUTABLE_SUFFIX})
19037330f729Sjoerg
19047330f729Sjoerg  install(SCRIPT ${INSTALL_SYMLINK}
19057330f729Sjoerg          CODE "install_symlink(${full_name} ${full_dest} ${LLVM_TOOLS_INSTALL_DIR})"
19067330f729Sjoerg          COMPONENT ${component})
19077330f729Sjoerg
19087330f729Sjoerg  if (NOT LLVM_ENABLE_IDE AND NOT ARG_ALWAYS_GENERATE)
19097330f729Sjoerg    add_llvm_install_targets(install-${name}
1910*82d56013Sjoerg                             DEPENDS ${name} ${dest}
1911*82d56013Sjoerg                             COMPONENT ${name}
1912*82d56013Sjoerg                             SYMLINK ${dest})
19137330f729Sjoerg  endif()
19147330f729Sjoergendfunction()
19157330f729Sjoerg
19167330f729Sjoergfunction(add_llvm_tool_symlink link_name target)
19177330f729Sjoerg  cmake_parse_arguments(ARG "ALWAYS_GENERATE" "OUTPUT_DIR" "" ${ARGN})
19187330f729Sjoerg  set(dest_binary "$<TARGET_FILE:${target}>")
19197330f729Sjoerg
19207330f729Sjoerg  # This got a bit gross... For multi-configuration generators the target
19217330f729Sjoerg  # properties return the resolved value of the string, not the build system
19227330f729Sjoerg  # expression. To reconstruct the platform-agnostic path we have to do some
19237330f729Sjoerg  # magic. First we grab one of the types, and a type-specific path. Then from
19247330f729Sjoerg  # the type-specific path we find the last occurrence of the type in the path,
19257330f729Sjoerg  # and replace it with CMAKE_CFG_INTDIR. This allows the build step to be type
19267330f729Sjoerg  # agnostic again.
19277330f729Sjoerg  if(NOT ARG_OUTPUT_DIR)
19287330f729Sjoerg    # If you're not overriding the OUTPUT_DIR, we can make the link relative in
19297330f729Sjoerg    # the same directory.
19307330f729Sjoerg    if(CMAKE_HOST_UNIX)
19317330f729Sjoerg      set(dest_binary "$<TARGET_FILE_NAME:${target}>")
19327330f729Sjoerg    endif()
19337330f729Sjoerg    if(CMAKE_CONFIGURATION_TYPES)
19347330f729Sjoerg      list(GET CMAKE_CONFIGURATION_TYPES 0 first_type)
19357330f729Sjoerg      string(TOUPPER ${first_type} first_type_upper)
19367330f729Sjoerg      set(first_type_suffix _${first_type_upper})
19377330f729Sjoerg    endif()
19387330f729Sjoerg    get_target_property(target_type ${target} TYPE)
19397330f729Sjoerg    if(${target_type} STREQUAL "STATIC_LIBRARY")
19407330f729Sjoerg      get_target_property(ARG_OUTPUT_DIR ${target} ARCHIVE_OUTPUT_DIRECTORY${first_type_suffix})
19417330f729Sjoerg    elseif(UNIX AND ${target_type} STREQUAL "SHARED_LIBRARY")
19427330f729Sjoerg      get_target_property(ARG_OUTPUT_DIR ${target} LIBRARY_OUTPUT_DIRECTORY${first_type_suffix})
19437330f729Sjoerg    else()
19447330f729Sjoerg      get_target_property(ARG_OUTPUT_DIR ${target} RUNTIME_OUTPUT_DIRECTORY${first_type_suffix})
19457330f729Sjoerg    endif()
19467330f729Sjoerg    if(CMAKE_CONFIGURATION_TYPES)
19477330f729Sjoerg      string(FIND "${ARG_OUTPUT_DIR}" "/${first_type}/" type_start REVERSE)
19487330f729Sjoerg      string(SUBSTRING "${ARG_OUTPUT_DIR}" 0 ${type_start} path_prefix)
19497330f729Sjoerg      string(SUBSTRING "${ARG_OUTPUT_DIR}" ${type_start} -1 path_suffix)
19507330f729Sjoerg      string(REPLACE "/${first_type}/" "/${CMAKE_CFG_INTDIR}/"
19517330f729Sjoerg             path_suffix ${path_suffix})
19527330f729Sjoerg      set(ARG_OUTPUT_DIR ${path_prefix}${path_suffix})
19537330f729Sjoerg    endif()
19547330f729Sjoerg  endif()
19557330f729Sjoerg
19567330f729Sjoerg  if(CMAKE_HOST_UNIX)
19577330f729Sjoerg    set(LLVM_LINK_OR_COPY create_symlink)
19587330f729Sjoerg  else()
19597330f729Sjoerg    set(LLVM_LINK_OR_COPY copy)
19607330f729Sjoerg  endif()
19617330f729Sjoerg
19627330f729Sjoerg  set(output_path "${ARG_OUTPUT_DIR}/${link_name}${CMAKE_EXECUTABLE_SUFFIX}")
19637330f729Sjoerg
19647330f729Sjoerg  set(target_name ${link_name})
19657330f729Sjoerg  if(TARGET ${link_name})
19667330f729Sjoerg    set(target_name ${link_name}-link)
19677330f729Sjoerg  endif()
19687330f729Sjoerg
19697330f729Sjoerg
19707330f729Sjoerg  if(ARG_ALWAYS_GENERATE)
19717330f729Sjoerg    set_property(DIRECTORY APPEND PROPERTY
19727330f729Sjoerg      ADDITIONAL_MAKE_CLEAN_FILES ${dest_binary})
19737330f729Sjoerg    add_custom_command(TARGET ${target} POST_BUILD
19747330f729Sjoerg      COMMAND ${CMAKE_COMMAND} -E ${LLVM_LINK_OR_COPY} "${dest_binary}" "${output_path}")
19757330f729Sjoerg  else()
19767330f729Sjoerg    add_custom_command(OUTPUT ${output_path}
19777330f729Sjoerg                     COMMAND ${CMAKE_COMMAND} -E ${LLVM_LINK_OR_COPY} "${dest_binary}" "${output_path}"
19787330f729Sjoerg                     DEPENDS ${target})
19797330f729Sjoerg    add_custom_target(${target_name} ALL DEPENDS ${target} ${output_path})
19807330f729Sjoerg    set_target_properties(${target_name} PROPERTIES FOLDER Tools)
19817330f729Sjoerg
19827330f729Sjoerg    # Make sure both the link and target are toolchain tools
19837330f729Sjoerg    if (${link_name} IN_LIST LLVM_TOOLCHAIN_TOOLS AND ${target} IN_LIST LLVM_TOOLCHAIN_TOOLS)
19847330f729Sjoerg      set(TOOL_IS_TOOLCHAIN ON)
19857330f729Sjoerg    endif()
19867330f729Sjoerg
19877330f729Sjoerg    if ((TOOL_IS_TOOLCHAIN OR NOT LLVM_INSTALL_TOOLCHAIN_ONLY) AND LLVM_BUILD_TOOLS)
19887330f729Sjoerg      llvm_install_symlink(${link_name} ${target})
19897330f729Sjoerg    endif()
19907330f729Sjoerg  endif()
19917330f729Sjoergendfunction()
19927330f729Sjoerg
19937330f729Sjoergfunction(llvm_externalize_debuginfo name)
19947330f729Sjoerg  if(NOT LLVM_EXTERNALIZE_DEBUGINFO)
19957330f729Sjoerg    return()
19967330f729Sjoerg  endif()
19977330f729Sjoerg
19987330f729Sjoerg  if(NOT LLVM_EXTERNALIZE_DEBUGINFO_SKIP_STRIP)
19997330f729Sjoerg    if(APPLE)
20007330f729Sjoerg      if(NOT CMAKE_STRIP)
20017330f729Sjoerg        set(CMAKE_STRIP xcrun strip)
20027330f729Sjoerg      endif()
20037330f729Sjoerg      set(strip_command COMMAND ${CMAKE_STRIP} -Sxl $<TARGET_FILE:${name}>)
20047330f729Sjoerg    else()
20057330f729Sjoerg      set(strip_command COMMAND ${CMAKE_STRIP} -g -x $<TARGET_FILE:${name}>)
20067330f729Sjoerg    endif()
20077330f729Sjoerg  endif()
20087330f729Sjoerg
20097330f729Sjoerg  if(APPLE)
20107330f729Sjoerg    if(LLVM_EXTERNALIZE_DEBUGINFO_EXTENSION)
20117330f729Sjoerg      set(file_ext ${LLVM_EXTERNALIZE_DEBUGINFO_EXTENSION})
20127330f729Sjoerg    else()
20137330f729Sjoerg      set(file_ext dSYM)
20147330f729Sjoerg    endif()
20157330f729Sjoerg
20167330f729Sjoerg    set(output_name "$<TARGET_FILE_NAME:${name}>.${file_ext}")
20177330f729Sjoerg
20187330f729Sjoerg    if(LLVM_EXTERNALIZE_DEBUGINFO_OUTPUT_DIR)
20197330f729Sjoerg      set(output_path "-o=${LLVM_EXTERNALIZE_DEBUGINFO_OUTPUT_DIR}/${output_name}")
20207330f729Sjoerg    else()
20217330f729Sjoerg      set(output_path "-o=${output_name}")
20227330f729Sjoerg    endif()
20237330f729Sjoerg
20247330f729Sjoerg    if(CMAKE_CXX_FLAGS MATCHES "-flto"
20257330f729Sjoerg      OR CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE} MATCHES "-flto")
20267330f729Sjoerg
20277330f729Sjoerg      set(lto_object ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${name}-lto.o)
20287330f729Sjoerg      set_property(TARGET ${name} APPEND_STRING PROPERTY
20297330f729Sjoerg        LINK_FLAGS " -Wl,-object_path_lto,${lto_object}")
20307330f729Sjoerg    endif()
20317330f729Sjoerg    if(NOT CMAKE_DSYMUTIL)
20327330f729Sjoerg      set(CMAKE_DSYMUTIL xcrun dsymutil)
20337330f729Sjoerg    endif()
20347330f729Sjoerg    add_custom_command(TARGET ${name} POST_BUILD
20357330f729Sjoerg      COMMAND ${CMAKE_DSYMUTIL} ${output_path} $<TARGET_FILE:${name}>
20367330f729Sjoerg      ${strip_command}
20377330f729Sjoerg      )
20387330f729Sjoerg  else()
20397330f729Sjoerg    add_custom_command(TARGET ${name} POST_BUILD
20407330f729Sjoerg      COMMAND ${CMAKE_OBJCOPY} --only-keep-debug $<TARGET_FILE:${name}> $<TARGET_FILE:${name}>.debug
20417330f729Sjoerg      ${strip_command} -R .gnu_debuglink
20427330f729Sjoerg      COMMAND ${CMAKE_OBJCOPY} --add-gnu-debuglink=$<TARGET_FILE:${name}>.debug $<TARGET_FILE:${name}>
20437330f729Sjoerg      )
20447330f729Sjoerg  endif()
20457330f729Sjoergendfunction()
20467330f729Sjoerg
20477330f729Sjoerg# Usage: llvm_codesign(name [FORCE] [ENTITLEMENTS file] [BUNDLE_PATH path])
20487330f729Sjoergfunction(llvm_codesign name)
20497330f729Sjoerg  cmake_parse_arguments(ARG "FORCE" "ENTITLEMENTS;BUNDLE_PATH" "" ${ARGN})
20507330f729Sjoerg
20517330f729Sjoerg  if(NOT LLVM_CODESIGNING_IDENTITY)
20527330f729Sjoerg    return()
20537330f729Sjoerg  endif()
20547330f729Sjoerg
20557330f729Sjoerg  if(CMAKE_GENERATOR STREQUAL "Xcode")
20567330f729Sjoerg    set_target_properties(${name} PROPERTIES
20577330f729Sjoerg      XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY ${LLVM_CODESIGNING_IDENTITY}
20587330f729Sjoerg    )
20597330f729Sjoerg    if(DEFINED ARG_ENTITLEMENTS)
20607330f729Sjoerg      set_target_properties(${name} PROPERTIES
20617330f729Sjoerg        XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS ${ARG_ENTITLEMENTS}
20627330f729Sjoerg      )
20637330f729Sjoerg    endif()
20647330f729Sjoerg  elseif(APPLE AND CMAKE_HOST_SYSTEM_NAME MATCHES Darwin)
20657330f729Sjoerg    if(NOT CMAKE_CODESIGN)
20667330f729Sjoerg      set(CMAKE_CODESIGN xcrun codesign)
20677330f729Sjoerg    endif()
20687330f729Sjoerg    if(NOT CMAKE_CODESIGN_ALLOCATE)
20697330f729Sjoerg      execute_process(
20707330f729Sjoerg        COMMAND xcrun -f codesign_allocate
20717330f729Sjoerg        OUTPUT_STRIP_TRAILING_WHITESPACE
20727330f729Sjoerg        OUTPUT_VARIABLE CMAKE_CODESIGN_ALLOCATE
20737330f729Sjoerg      )
20747330f729Sjoerg    endif()
20757330f729Sjoerg    if(DEFINED ARG_ENTITLEMENTS)
20767330f729Sjoerg      set(pass_entitlements --entitlements ${ARG_ENTITLEMENTS})
20777330f729Sjoerg    endif()
20787330f729Sjoerg
20797330f729Sjoerg    if (NOT ARG_BUNDLE_PATH)
20807330f729Sjoerg      set(ARG_BUNDLE_PATH $<TARGET_FILE:${name}>)
20817330f729Sjoerg    endif()
20827330f729Sjoerg
2083*82d56013Sjoerg    # ld64 now always codesigns the binaries it creates. Apply the force arg
2084*82d56013Sjoerg    # unconditionally so that we can - for example - add entitlements to the
2085*82d56013Sjoerg    # targets that need it.
20867330f729Sjoerg    set(force_flag "-f")
20877330f729Sjoerg
20887330f729Sjoerg    add_custom_command(
20897330f729Sjoerg      TARGET ${name} POST_BUILD
20907330f729Sjoerg      COMMAND ${CMAKE_COMMAND} -E
20917330f729Sjoerg              env CODESIGN_ALLOCATE=${CMAKE_CODESIGN_ALLOCATE}
20927330f729Sjoerg              ${CMAKE_CODESIGN} -s ${LLVM_CODESIGNING_IDENTITY}
20937330f729Sjoerg              ${pass_entitlements} ${force_flag} ${ARG_BUNDLE_PATH}
20947330f729Sjoerg    )
20957330f729Sjoerg  endif()
20967330f729Sjoergendfunction()
20977330f729Sjoerg
20987330f729Sjoergfunction(llvm_setup_rpath name)
20997330f729Sjoerg  if(CMAKE_INSTALL_RPATH)
21007330f729Sjoerg    return()
21017330f729Sjoerg  endif()
21027330f729Sjoerg
21037330f729Sjoerg  if(LLVM_INSTALL_PREFIX AND NOT (LLVM_INSTALL_PREFIX STREQUAL CMAKE_INSTALL_PREFIX))
21047330f729Sjoerg    set(extra_libdir ${LLVM_LIBRARY_DIR})
21057330f729Sjoerg  elseif(LLVM_BUILD_LIBRARY_DIR)
21067330f729Sjoerg    set(extra_libdir ${LLVM_LIBRARY_DIR})
21077330f729Sjoerg  endif()
21087330f729Sjoerg
21097330f729Sjoerg  if (APPLE)
21107330f729Sjoerg    set(_install_name_dir INSTALL_NAME_DIR "@rpath")
21117330f729Sjoerg    set(_install_rpath "@loader_path/../lib${LLVM_LIBDIR_SUFFIX}" ${extra_libdir})
2112*82d56013Sjoerg  elseif(${CMAKE_SYSTEM_NAME} MATCHES "AIX" AND BUILD_SHARED_LIBS)
2113*82d56013Sjoerg    # $ORIGIN is not interpreted at link time by aix ld.
2114*82d56013Sjoerg    # Since BUILD_SHARED_LIBS is only recommended for use by developers,
2115*82d56013Sjoerg    # hardcode the rpath to build/install lib dir first in this mode.
2116*82d56013Sjoerg    # FIXME: update this when there is better solution.
2117*82d56013Sjoerg    set(_install_rpath "${LLVM_LIBRARY_OUTPUT_INTDIR}" "${CMAKE_INSTALL_PREFIX}/lib${LLVM_LIBDIR_SUFFIX}" ${extra_libdir})
21187330f729Sjoerg  elseif(UNIX)
21197330f729Sjoerg    set(_install_rpath "\$ORIGIN/../lib${LLVM_LIBDIR_SUFFIX}" ${extra_libdir})
21207330f729Sjoerg    if(${CMAKE_SYSTEM_NAME} MATCHES "(FreeBSD|DragonFly)")
21217330f729Sjoerg      set_property(TARGET ${name} APPEND_STRING PROPERTY
21227330f729Sjoerg                   LINK_FLAGS " -Wl,-z,origin ")
21237330f729Sjoerg    endif()
21247330f729Sjoerg    if(LLVM_LINKER_IS_GNULD)
21257330f729Sjoerg      # $ORIGIN is not interpreted at link time by ld.bfd
21267330f729Sjoerg      set_property(TARGET ${name} APPEND_STRING PROPERTY
21277330f729Sjoerg                   LINK_FLAGS " -Wl,-rpath-link,${LLVM_LIBRARY_OUTPUT_INTDIR} ")
21287330f729Sjoerg    endif()
21297330f729Sjoerg  else()
21307330f729Sjoerg    return()
21317330f729Sjoerg  endif()
21327330f729Sjoerg
2133*82d56013Sjoerg  # Enable BUILD_WITH_INSTALL_RPATH unless CMAKE_BUILD_RPATH is set.
2134*82d56013Sjoerg  if("${CMAKE_BUILD_RPATH}" STREQUAL "")
2135*82d56013Sjoerg    set_property(TARGET ${name} PROPERTY BUILD_WITH_INSTALL_RPATH ON)
2136*82d56013Sjoerg  endif()
2137*82d56013Sjoerg
21387330f729Sjoerg  set_target_properties(${name} PROPERTIES
21397330f729Sjoerg                        INSTALL_RPATH "${_install_rpath}"
21407330f729Sjoerg                        ${_install_name_dir})
21417330f729Sjoergendfunction()
21427330f729Sjoerg
21437330f729Sjoergfunction(setup_dependency_debugging name)
21447330f729Sjoerg  if(NOT LLVM_DEPENDENCY_DEBUGGING)
21457330f729Sjoerg    return()
21467330f729Sjoerg  endif()
21477330f729Sjoerg
21487330f729Sjoerg  if("intrinsics_gen" IN_LIST ARGN)
21497330f729Sjoerg    return()
21507330f729Sjoerg  endif()
21517330f729Sjoerg
21527330f729Sjoerg  set(deny_attributes_inc "(deny file* (literal \"${LLVM_BINARY_DIR}/include/llvm/IR/Attributes.inc\"))")
21537330f729Sjoerg  set(deny_intrinsics_inc "(deny file* (literal \"${LLVM_BINARY_DIR}/include/llvm/IR/Intrinsics.inc\"))")
21547330f729Sjoerg
21557330f729Sjoerg  set(sandbox_command "sandbox-exec -p '(version 1) (allow default) ${deny_attributes_inc} ${deny_intrinsics_inc}'")
21567330f729Sjoerg  set_target_properties(${name} PROPERTIES RULE_LAUNCH_COMPILE ${sandbox_command})
21577330f729Sjoergendfunction()
21587330f729Sjoerg
2159*82d56013Sjoerg# If the sources at the given `path` are under version control, set `out_var`
2160*82d56013Sjoerg# to the the path of a file which will be modified when the VCS revision
2161*82d56013Sjoerg# changes, attempting to create that file if it does not exist; if no such
2162*82d56013Sjoerg# file exists and one cannot be created, instead set `out_var` to the
2163*82d56013Sjoerg# empty string.
2164*82d56013Sjoerg#
2165*82d56013Sjoerg# If the sources are not under version control, do not define `out_var`.
21667330f729Sjoergfunction(find_first_existing_vc_file path out_var)
21677330f729Sjoerg  if(NOT EXISTS "${path}")
21687330f729Sjoerg    return()
21697330f729Sjoerg  endif()
21707330f729Sjoerg  find_package(Git)
21717330f729Sjoerg  if(GIT_FOUND)
21727330f729Sjoerg    execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --git-dir
21737330f729Sjoerg      WORKING_DIRECTORY ${path}
21747330f729Sjoerg      RESULT_VARIABLE git_result
21757330f729Sjoerg      OUTPUT_VARIABLE git_output
21767330f729Sjoerg      ERROR_QUIET)
21777330f729Sjoerg    if(git_result EQUAL 0)
21787330f729Sjoerg      string(STRIP "${git_output}" git_output)
21797330f729Sjoerg      get_filename_component(git_dir ${git_output} ABSOLUTE BASE_DIR ${path})
21807330f729Sjoerg      # Some branchless cases (e.g. 'repo') may not yet have .git/logs/HEAD
21817330f729Sjoerg      if (NOT EXISTS "${git_dir}/logs/HEAD")
2182*82d56013Sjoerg        execute_process(COMMAND ${CMAKE_COMMAND} -E touch HEAD
2183*82d56013Sjoerg          WORKING_DIRECTORY "${git_dir}/logs"
2184*82d56013Sjoerg          RESULT_VARIABLE touch_head_result
2185*82d56013Sjoerg          ERROR_QUIET)
2186*82d56013Sjoerg        if (NOT touch_head_result EQUAL 0)
2187*82d56013Sjoerg          set(${out_var} "" PARENT_SCOPE)
2188*82d56013Sjoerg          return()
2189*82d56013Sjoerg        endif()
21907330f729Sjoerg      endif()
21917330f729Sjoerg      set(${out_var} "${git_dir}/logs/HEAD" PARENT_SCOPE)
21927330f729Sjoerg    endif()
21937330f729Sjoerg  endif()
21947330f729Sjoergendfunction()
2195