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