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