smeenai created this revision. smeenai added reviewers: beanz, compnerd, phosek, tstellar. Herald added subscribers: llvm-commits, cfe-commits, tatianashp, msifontes, jurahul, Kayjukh, grosul1, Joonsoo, liufengdb, aartbik, lucyrfox, mgester, arpith-jacob, antiagainst, shauheen, rriddle, mehdi_amini, mgorny. Herald added a reviewer: sscalpone. Herald added projects: clang, MLIR, LLVM. smeenai requested review of this revision. Herald added subscribers: stephenneuendorffer, nicolasvasilache.
LLVM's build system contains support for configuring a distribution, but it can often be useful to be able to configure multiple distributions (e.g. if you want separate distributions for the tools and the libraries). Add this support to the build system, along with documentation and usage examples. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D89177 Files: clang/cmake/caches/MultiDistributionExample.cmake clang/cmake/modules/AddClang.cmake clang/cmake/modules/CMakeLists.txt clang/cmake/modules/ClangConfig.cmake.in flang/cmake/modules/AddFlang.cmake flang/cmake/modules/CMakeLists.txt flang/cmake/modules/FlangConfig.cmake.in lld/cmake/modules/AddLLD.cmake lld/cmake/modules/CMakeLists.txt lld/cmake/modules/LLDConfig.cmake.in llvm/cmake/modules/AddLLVM.cmake llvm/cmake/modules/CMakeLists.txt llvm/cmake/modules/LLVMConfig.cmake.in llvm/cmake/modules/LLVMDistributionSupport.cmake llvm/docs/BuildingADistribution.rst mlir/cmake/modules/AddMLIR.cmake mlir/cmake/modules/CMakeLists.txt mlir/cmake/modules/MLIRConfig.cmake.in
Index: mlir/cmake/modules/MLIRConfig.cmake.in =================================================================== --- mlir/cmake/modules/MLIRConfig.cmake.in +++ mlir/cmake/modules/MLIRConfig.cmake.in @@ -20,7 +20,7 @@ set_property(GLOBAL PROPERTY MLIR_TRANSLATION_LIBS "@MLIR_TRANSLATION_LIBS@") # Provide all our library targets to users. -include("@MLIR_CONFIG_EXPORTS_FILE@") +@mlir_config_include_exports@ # By creating these targets here, subprojects that depend on MLIR's # tablegen-generated headers can always depend on these targets whether building Index: mlir/cmake/modules/CMakeLists.txt =================================================================== --- mlir/cmake/modules/CMakeLists.txt +++ mlir/cmake/modules/CMakeLists.txt @@ -1,3 +1,5 @@ +include(LLVMDistributionSupport) + # Generate a list of CMake library targets so that other CMake projects can # link against them. LLVM calls its version of this file LLVMExports.cmake, but # the usual CMake convention seems to be ${Project}Targets.cmake. @@ -19,7 +21,7 @@ # Generate MlirConfig.cmake for the build tree. set(MLIR_CONFIG_CMAKE_DIR "${mlir_cmake_builddir}") set(MLIR_CONFIG_LLVM_CMAKE_DIR "${llvm_cmake_builddir}") -set(MLIR_CONFIG_EXPORTS_FILE "\${MLIR_CMAKE_DIR}/MLIRTargets.cmake") +set(mlir_config_include_exports "include(\"\${MLIR_CMAKE_DIR}/MLIRTargets.cmake\")") set(MLIR_CONFIG_INCLUDE_DIRS "${MLIR_SOURCE_DIR}/include" "${MLIR_BINARY_DIR}/include" @@ -30,7 +32,6 @@ @ONLY) set(MLIR_CONFIG_CMAKE_DIR) set(MLIR_CONFIG_LLVM_CMAKE_DIR) -set(MLIR_CONFIG_EXPORTS_FILE) set(MLIR_CONFIG_INCLUDE_DIRS) # For compatibility with projects that include(MLIRConfig) @@ -55,7 +56,7 @@ endforeach(p) set(MLIR_CONFIG_CMAKE_DIR "\${MLIR_INSTALL_PREFIX}/${MLIR_INSTALL_PACKAGE_DIR}") set(MLIR_CONFIG_LLVM_CMAKE_DIR "\${MLIR_INSTALL_PREFIX}/${LLVM_INSTALL_PACKAGE_DIR}") -set(MLIR_CONFIG_EXPORTS_FILE "\${MLIR_CMAKE_DIR}/MLIRTargets.cmake") +get_config_exports_includes(MLIR mlir_config_include_exports) set(MLIR_CONFIG_INCLUDE_DIRS "\${MLIR_INSTALL_PREFIX}/include" ) @@ -66,17 +67,12 @@ set(MLIR_CONFIG_CODE) set(MLIR_CONFIG_CMAKE_DIR) set(MLIR_CONFIG_LLVM_CMAKE_DIR) -set(MLIR_CONFIG_EXPORTS_FILE) set(MLIR_CONFIG_INCLUDE_DIRS) if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY) # Not TOOLCHAIN ONLY, so install the MLIR parts as well # Include the cmake files so other tools can use mlir-tblgen, etc. - get_property(mlir_has_exports GLOBAL PROPERTY MLIR_HAS_EXPORTS) - if(mlir_has_exports) - install(EXPORT MLIRTargets DESTINATION ${MLIR_INSTALL_PACKAGE_DIR} - COMPONENT mlir-cmake-exports) - endif() + install_distribution_exports(MLIR) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/MLIRConfig.cmake Index: mlir/cmake/modules/AddMLIR.cmake =================================================================== --- mlir/cmake/modules/AddMLIR.cmake +++ mlir/cmake/modules/AddMLIR.cmake @@ -1,3 +1,5 @@ +include(LLVMDistributionSupport) + function(mlir_tablegen ofn) tablegen(MLIR ${ARGV}) set(TABLEGEN_OUTPUT ${TABLEGEN_OUTPUT} ${CMAKE_CURRENT_BINARY_DIR}/${ofn} @@ -139,11 +141,10 @@ function(add_mlir_library_install name) if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY) set(export_to_mlirtargets) - if (${name} IN_LIST LLVM_DISTRIBUTION_COMPONENTS OR - "mlir-libraries" IN_LIST LLVM_DISTRIBUTION_COMPONENTS OR - NOT LLVM_DISTRIBUTION_COMPONENTS) - set(export_to_mlirtargets EXPORT MLIRTargets) - set_property(GLOBAL PROPERTY MLIR_HAS_EXPORTS True) + get_llvm_distribution(${name} in_distribution distribution UMBRELLA mlir-libraries) + if (in_distribution) + set(export_to_mlirtargets EXPORT MLIR${distribution}Targets) + set_property(GLOBAL PROPERTY MLIR${distribution}_HAS_EXPORTS True) endif() install(TARGETS ${name} Index: llvm/docs/BuildingADistribution.rst =================================================================== --- llvm/docs/BuildingADistribution.rst +++ llvm/docs/BuildingADistribution.rst @@ -87,6 +87,40 @@ the list. This is a convenience build target to allow building just the distributed pieces without needing to build all configured targets. +.. _Multi-distribution configurations: + +Multi-distribution configurations +--------------------------------- + +The ``install-distribution`` target described above is for building a single +distribution. LLVM's build system also supports building multiple distributions, +which can be used to e.g. have one distribution containing just tools and +another for libraries (to enable development). These are configured by setting +the *LLVM_DISTRIBUTIONS* variable to hold a list of all distribution names +(which conventionally start with an uppercase letter, e.g. "Development"), and +then setting the *LLVM_<distribution>_DISTRIBUTION_COMPONENTS* variable to the +list of targets for that distribution. For each distribution, the build system +generates an ``install-${distribution}-distribution`` target, where +``${distribution}`` is the name of the distribution in lowercase, to install +that distribution. Each target can only be in one distribution. + +Each distribution creates its own set of CMake exports, and the target to +install the CMake exports for a particular distribution for a project is named +``${project}-${distribution}-cmake-exports``, where ``${project}`` is the name +of the project in lowercase and ``${distribution}`` is the name of the +distribution in lowercase, unless the project is LLVM, in which case the target +is just named ``${distribution}-cmake-exports``. These targets need to be +explicitly included in the *LLVM_<distribution>_DISTRIBUTION_COMPONENTS* +variable in order to be included as part of the distribution. + +Unlike with the single distribution setup, when building multiple distributions, +any components specified in *LLVM_RUNTIME_DISTRIBUTION_COMPONENTS* are not +automatically added to any distribution. Instead, you must include the targets +explicitly in some *LLVM_<distribution>_DISTRIBUTION_COMPONENTS* list. + +We strongly encourage looking at ``clang/cmake/caches/MultiDistributionExample.cmake`` +as an example of configuring multiple distributions. + Special Notes for Library-only Distributions -------------------------------------------- @@ -179,6 +213,11 @@ of the libraries and runtimes. Component names match the names of the build system targets. +**LLVM_DISTRIBUTIONS**:STRING + This variable can be set to a semi-colon separated list of distributions. See + the :ref:`Multi-distribution configurations` section above for details on this + and other CMake variables to configure multiple distributions. + **LLVM_RUNTIME_DISTRIBUTION_COMPONENTS**:STRING This variable can be set to a semi-colon separated list of runtime library components. This is used in conjunction with *LLVM_ENABLE_RUNTIMES* to specify Index: llvm/cmake/modules/LLVMDistributionSupport.cmake =================================================================== --- llvm/cmake/modules/LLVMDistributionSupport.cmake +++ llvm/cmake/modules/LLVMDistributionSupport.cmake @@ -1,36 +1,227 @@ +# Utility functions for packaging an LLVM distribution. See the +# BuildingADistribution documentation for more details. -if(LLVM_DISTRIBUTION_COMPONENTS) +# These functions assume a number of conventions that are common across all LLVM +# subprojects: +# - The generated CMake exports file for ${project} is called ${project}Targets +# (except for LLVM where it's called ${project}Exports for legacy reasons). +# - The build target for the CMake exports is called ${project}-cmake-exports +# (except LLVM where it's just cmake-exports). +# - The ${PROJECT}${distribution}_HAS_EXPORTS global property holds whether a +# project has any exports for a particular ${distribution} (where ${PROJECT} +# is the project name in uppercase). +# - The ${PROJECT}_CMAKE_DIR variable is computed by ${project}Config.cmake to +# hold the path of the installed CMake modules directory. +# - The ${PROJECT}_INSTALL_PACKAGE_DIR variable contains the install destination +# for the project's CMake modules. + +include_guard(GLOBAL) + +if(LLVM_DISTRIBUTION_COMPONENTS AND LLVM_DISTRIBUTIONS) + message(FATAL_ERROR "LLVM_DISTRIBUTION_COMPONENTS and LLVM_DISTRIBUTIONS cannot be specified together") +endif() + +if(LLVM_DISTRIBUTION_COMPONENTS OR LLVM_DISTRIBUTIONS) if(LLVM_ENABLE_IDE) message(FATAL_ERROR "LLVM_DISTRIBUTION_COMPONENTS cannot be specified with multi-configuration generators (i.e. Xcode or Visual Studio)") endif() endif() -function(llvm_distribution_add_targets) - add_custom_target(distribution) - add_custom_target(install-distribution) - add_custom_target(install-distribution-stripped) - - foreach(target ${LLVM_DISTRIBUTION_COMPONENTS} - ${LLVM_RUNTIME_DISTRIBUTION_COMPONENTS}) - if(TARGET ${target}) - add_dependencies(distribution ${target}) - else() - message(SEND_ERROR "Specified distribution component '${target}' doesn't have a target") +# Build the map of targets to distributions that's used to look up the +# distribution for a target later. The distribution for ${target} is stored in +# the global property LLVM_DISTRIBUTION_FOR_${target}. +function(llvm_distribution_build_target_map) + foreach(target ${LLVM_DISTRIBUTION_COMPONENTS}) + # CMake doesn't easily distinguish between properties that are unset and + # properties that are empty (you have to do a second get_property call with + # the SET option, which is unergonomic), so just use a space to denote the + # default (unnamed) distribution. + set_property(GLOBAL PROPERTY LLVM_DISTRIBUTION_FOR_${target} " ") + endforeach() + + foreach(distribution ${LLVM_DISTRIBUTIONS}) + foreach(target ${LLVM_${distribution}_DISTRIBUTION_COMPONENTS}) + # We don't allow a target to be in multiple distributions, because we + # wouldn't know which export set to place it in. + get_property(current_distribution GLOBAL PROPERTY LLVM_DISTRIBUTION_FOR_${target}) + if(current_distribution AND NOT current_distribution STREQUAL distribution) + message(SEND_ERROR "Target ${target} cannot be in multiple distributions ${distribution} and ${current_distribution}") + endif() + set_property(GLOBAL PROPERTY LLVM_DISTRIBUTION_FOR_${target} ${distribution}) + endforeach() + endforeach() +endfunction() + +# The include guard ensures this will only be called once. The rest of this file +# only defines other functions (i.e. it doesn't execute any more code directly). +llvm_distribution_build_target_map() + +# Look up the distribution a particular target belongs to. By convention, the +# project calling this should set the ${PROJECT}${distribution}_HAS_EXPORTS +# global property to true if the target is in ${distribution} (${PROJECT} is the +# project name in uppercase). +# - target: The target to look up. +# - in_distribution_var: The variable with this name is set in the caller's +# scope to indicate if the target is in any distribution. If no distributions +# have been configured, this will always be set to true. +# - distribution_var: The variable with this name is set in the caller's scope +# to indicate the distribution name for the target. If the target belongs to +# the default (unnamed) distribution, or if no distributions have been +# configured, it's set to the empty string. +# - UMBRELLA: The (optional) umbrella target that the target is a part of. For +# example, all LLVM libraries have the umbrella target llvm-libraries. +function(get_llvm_distribution target in_distribution_var distribution_var) + if(NOT LLVM_DISTRIBUTION_COMPONENTS AND NOT LLVM_DISTRIBUTIONS) + set(${in_distribution_var} YES PARENT_SCOPE) + set(${distribution_var} "" PARENT_SCOPE) + return() + endif() + + cmake_parse_arguments(ARG "" UMBRELLA "" ${ARGN}) + get_property(distribution GLOBAL PROPERTY LLVM_DISTRIBUTION_FOR_${target}) + if(ARG_UMBRELLA) + get_property(umbrella_distribution GLOBAL PROPERTY LLVM_DISTRIBUTION_FOR_${ARG_UMBRELLA}) + if(distribution AND umbrella_distribution AND NOT distribution STREQUAL umbrella_distribution) + message(SEND_ERROR "Target ${target} has different distribution ${distribution} from its" + " umbrella target ${ARG_UMBRELLA} distribution ${umbrella_distribution}") + elseif(NOT distribution) + set(distribution ${umbrella_distribution}) endif() + endif() + if(distribution) + set(${in_distribution_var} YES PARENT_SCOPE) + if(distribution STREQUAL " ") + set(distribution "") + endif() + set(${distribution_var} "${distribution}" PARENT_SCOPE) + else() + set(${in_distribution_var} NO PARENT_SCOPE) + endif() +endfunction() - if(TARGET install-${target}) - add_dependencies(install-distribution install-${target}) - else() - message(SEND_ERROR "Specified distribution component '${target}' doesn't have an install target") +# Produce a string of CMake include() commands to include the exported targets +# files for all distributions. See the comment at the top of this file for +# various assumptions made. +# - project: The project to produce the commands for. IMPORTANT: The casing of +# this argument should match the casing used by the project's Config.cmake +# file. The correct casing for the LLVM projects is Clang, Flang, LLD, LLVM, +# and MLIR. +# - includes_var: The variable with this name is set in the caller's scope to +# the string of include commands. +function(get_config_exports_includes project includes_var) + string(TOUPPER "${project}" project_upper) + set(prefix "\${${project_upper}_CMAKE_DIR}/${project}") + if(project STREQUAL "LLVM") + set(suffix "Exports.cmake") # legacy + else() + set(suffix "Targets.cmake") + endif() + + if(NOT LLVM_DISTRIBUTIONS) + set(${includes_var} "include(\"${prefix}${suffix}\")" PARENT_SCOPE) + else() + set(includes) + foreach(distribution ${LLVM_DISTRIBUTIONS}) + list(APPEND includes "include(\"${prefix}${distribution}${suffix}\" OPTIONAL)") + endforeach() + string(REPLACE ";" "\n" includes "${includes}") + set(${includes_var} "${includes}" PARENT_SCOPE) + endif() +endfunction() + +# Create the install commands and targets for the distributions' CMake exports. +# The target to install ${distribution} for a project is called +# ${project}-${distribution}-cmake-exports, where ${project} is the project name +# in lowercase and ${distribution} is the distribution name in lowercase, except +# for LLVM, where the target is just called ${distribution}-cmake-exports. See +# the comment at the top of this file for various assumptions made. +# - project: The project. See the comment for get_config_exports_includes above +# for the correct casing of this argument. +function(install_distribution_exports project) + string(TOUPPER "${project}" project_upper) + string(TOLOWER "${project}" project_lower) + if(project STREQUAL "LLVM") + set(prefix "") + set(suffix "Exports") # legacy + else() + set(prefix "${project_lower}-") + set(suffix "Targets") + endif() + set(destination "${${project_upper}_INSTALL_PACKAGE_DIR}") + + if(NOT LLVM_DISTRIBUTIONS) + get_property(has_exports GLOBAL PROPERTY ${project_upper}_HAS_EXPORTS) + if(has_exports) + install(EXPORT ${project}${suffix} DESTINATION "${destination}" + COMPONENT ${prefix}cmake-exports) endif() + else() + foreach(distribution ${LLVM_DISTRIBUTIONS}) + get_property(has_exports GLOBAL PROPERTY ${project_upper}${distribution}_HAS_EXPORTS) + if(has_exports) + string(TOLOWER ${distribution} distribution_lower) + set(target ${prefix}${distribution_lower}-cmake-exports) + install(EXPORT ${project}${distribution}${suffix} DESTINATION "${destination}" + COMPONENT ${target}) + if(NOT LLVM_ENABLE_IDE) + add_custom_target(${target}) + add_llvm_install_targets(install-${target} COMPONENT ${target}) + endif() + endif() + endforeach() + endif() +endfunction() + +# Create the targets for installing the configured distributions. The +# ${distribution} target builds the distribution, install-${distribution} +# installs it, and install-${distribution}-stripped installs a stripped version, +# where ${distribution} is the distribution name in lowercase, or "distribution" +# for the default distribution. +function(llvm_distribution_add_targets) + set(distributions "${LLVM_DISTRIBUTIONS}") + if(NOT distributions) + # CMake seemingly doesn't distinguish between an empty list and a list + # containing one element which is the empty string, so just use a space for + # the latter and fix it in the loop. + set(distributions " ") + endif() - if(TARGET install-${target}-stripped) - add_dependencies(install-distribution-stripped install-${target}-stripped) + foreach(distribution ${distributions}) + if(distribution STREQUAL " ") + set(distribution_target distribution) + # Preserve legacy behavior for LLVM_DISTRIBUTION_COMPONENTS. + set(distribution_components ${LLVM_DISTRIBUTION_COMPONENTS} ${LLVM_RUNTIME_DISTRIBUTION_COMPONENTS}) else() - message(SEND_ERROR - "Specified distribution component '${target}' doesn't have an install-stripped target." - " Its installation target creation should be changed to use add_llvm_install_targets," - " or you should manually create the 'install-${target}-stripped' target.") + string(TOLOWER ${distribution} distribution_lower) + set(distribution_target ${distribution_lower}-distribution) + set(distribution_components ${LLVM_${distribution}_DISTRIBUTION_COMPONENTS}) endif() + + add_custom_target(${distribution_target}) + add_custom_target(install-${distribution_target}) + add_custom_target(install-${distribution_target}-stripped) + + foreach(target ${distribution_components}) + if(TARGET ${target}) + add_dependencies(${distribution_target} ${target}) + else() + message(SEND_ERROR "Specified distribution component '${target}' doesn't have a target") + endif() + + if(TARGET install-${target}) + add_dependencies(install-${distribution_target} install-${target}) + else() + message(SEND_ERROR "Specified distribution component '${target}' doesn't have an install target") + endif() + + if(TARGET install-${target}-stripped) + add_dependencies(install-${distribution_target}-stripped install-${target}-stripped) + else() + message(SEND_ERROR + "Specified distribution component '${target}' doesn't have an install-stripped target." + " Its installation target creation should be changed to use add_llvm_install_targets," + " or you should manually create the 'install-${target}-stripped' target.") + endif() + endforeach() endforeach() endfunction() Index: llvm/cmake/modules/LLVMConfig.cmake.in =================================================================== --- llvm/cmake/modules/LLVMConfig.cmake.in +++ llvm/cmake/modules/LLVMConfig.cmake.in @@ -108,8 +108,7 @@ set(LLVM_ENABLE_SHARED_LIBS @BUILD_SHARED_LIBS@) if(NOT TARGET LLVMSupport) - set(LLVM_EXPORTED_TARGETS "@LLVM_CONFIG_EXPORTS@") - include("@LLVM_CONFIG_EXPORTS_FILE@") + @llvm_config_include_exports@ @llvm_config_include_buildtree_only_exports@ endif() Index: llvm/cmake/modules/CMakeLists.txt =================================================================== --- llvm/cmake/modules/CMakeLists.txt +++ llvm/cmake/modules/CMakeLists.txt @@ -1,3 +1,5 @@ +include(LLVMDistributionSupport) + set(LLVM_INSTALL_PACKAGE_DIR lib${LLVM_LIBDIR_SUFFIX}/cmake/llvm) set(llvm_cmake_builddir "${LLVM_BINARY_DIR}/${LLVM_INSTALL_PACKAGE_DIR}") @@ -77,8 +79,8 @@ # LLVM_CONFIG_CMAKE_DIR being the source directory. In contrast in the install # tree, both the generated LLVMExports.cmake file and the rest of the cmake # source files are put in the same cmake directory. -set(LLVM_CONFIG_EXPORTS_FILE "${LLVM_EXPORTS_FILE}") set(LLVM_CONFIG_EXPORTS "${LLVM_EXPORTS};${LLVM_EXPORTS_BUILDTREE_ONLY}") +set(llvm_config_include_exports "include(\"${LLVM_EXPORTS_FILE}\")") set(llvm_config_include_buildtree_only_exports "include(\"${LLVM_BUILDTREEONLY_EXPORTS_FILE}\")") configure_file( @@ -121,7 +123,7 @@ set(LLVM_CONFIG_DEFAULT_EXTERNAL_LIT "${LLVM_CONFIG_TOOLS_BINARY_DIR}/llvm-lit") endif() -set(LLVM_CONFIG_EXPORTS_FILE "\${LLVM_CMAKE_DIR}/LLVMExports.cmake") +get_config_exports_includes(LLVM llvm_config_include_exports) set(LLVM_CONFIG_EXPORTS "${LLVM_EXPORTS}") configure_file( LLVMConfig.cmake.in @@ -135,11 +137,7 @@ @ONLY) if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY) - get_property(llvm_has_exports GLOBAL PROPERTY LLVM_HAS_EXPORTS) - if(llvm_has_exports) - install(EXPORT LLVMExports DESTINATION ${LLVM_INSTALL_PACKAGE_DIR} - COMPONENT cmake-exports) - endif() + install_distribution_exports(LLVM) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/LLVMConfig.cmake Index: llvm/cmake/modules/AddLLVM.cmake =================================================================== --- llvm/cmake/modules/AddLLVM.cmake +++ llvm/cmake/modules/AddLLVM.cmake @@ -1,3 +1,4 @@ +include(LLVMDistributionSupport) include(LLVMProcessSources) include(LLVM-Config) include(DetermineGCCCompatible) @@ -756,13 +757,16 @@ set_property(GLOBAL APPEND PROPERTY LLVM_EXPORTS_BUILDTREE_ONLY ${name}) else() if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY OR ARG_INSTALL_WITH_TOOLCHAIN) - set(export_to_llvmexports) - if(${name} IN_LIST LLVM_DISTRIBUTION_COMPONENTS OR - (in_llvm_libs AND "llvm-libraries" IN_LIST LLVM_DISTRIBUTION_COMPONENTS) OR - NOT LLVM_DISTRIBUTION_COMPONENTS) - set(export_to_llvmexports EXPORT LLVMExports) - set_property(GLOBAL PROPERTY LLVM_HAS_EXPORTS True) + if(in_llvm_libs) + set(umbrella UMBRELLA llvm-libraries) + else() + set(umbrella) + endif() + get_llvm_distribution(${name} in_distribution distribution ${umbrella}) + if(in_distribution) + set(export_to_llvmexports EXPORT LLVM${distribution}Exports) + set_property(GLOBAL PROPERTY LLVM${distribution}_HAS_EXPORTS True) endif() install(TARGETS ${name} @@ -1171,10 +1175,10 @@ if ( ${name} IN_LIST LLVM_TOOLCHAIN_TOOLS OR NOT LLVM_INSTALL_TOOLCHAIN_ONLY) if( LLVM_BUILD_TOOLS ) set(export_to_llvmexports) - if(${name} IN_LIST LLVM_DISTRIBUTION_COMPONENTS OR - NOT LLVM_DISTRIBUTION_COMPONENTS) - set(export_to_llvmexports EXPORT LLVMExports) - set_property(GLOBAL PROPERTY LLVM_HAS_EXPORTS True) + get_llvm_distribution(${name} in_distribution distribution) + if(in_distribution) + set(export_to_llvmexports EXPORT LLVM${distribution}Exports) + set_property(GLOBAL PROPERTY LLVM${distribution}_HAS_EXPORTS True) endif() install(TARGETS ${name} @@ -1230,10 +1234,10 @@ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY) if (LLVM_INSTALL_UTILS AND LLVM_BUILD_UTILS) set(export_to_llvmexports) - if (${name} IN_LIST LLVM_DISTRIBUTION_COMPONENTS OR - NOT LLVM_DISTRIBUTION_COMPONENTS) - set(export_to_llvmexports EXPORT LLVMExports) - set_property(GLOBAL PROPERTY LLVM_HAS_EXPORTS True) + get_llvm_distribution(${name} in_distribution distribution) + if (in_distribution) + set(export_to_llvmexports EXPORT LLVM${distribution}Exports) + set_property(GLOBAL PROPERTY LLVM${distribution}_HAS_EXPORTS True) endif() install(TARGETS ${name} Index: lld/cmake/modules/LLDConfig.cmake.in =================================================================== --- lld/cmake/modules/LLDConfig.cmake.in +++ lld/cmake/modules/LLDConfig.cmake.in @@ -10,4 +10,4 @@ set(LLD_INCLUDE_DIRS "@LLD_CONFIG_INCLUDE_DIRS@") # Provide all our library targets to users. -include("@LLD_CONFIG_EXPORTS_FILE@") +@lld_config_include_exports@ Index: lld/cmake/modules/CMakeLists.txt =================================================================== --- lld/cmake/modules/CMakeLists.txt +++ lld/cmake/modules/CMakeLists.txt @@ -14,7 +14,7 @@ # Generate LLDConfig.cmake for the build tree. set(LLD_CONFIG_CMAKE_DIR "${lld_cmake_builddir}") set(LLD_CONFIG_LLVM_CMAKE_DIR "${llvm_cmake_builddir}") -set(LLD_CONFIG_EXPORTS_FILE "${lld_cmake_builddir}/LLDTargets.cmake") +set(lld_config_include_exports "include(\"${lld_cmake_builddir}/LLDTargets.cmake\")") set(LLD_CONFIG_INCLUDE_DIRS "${LLD_SOURCE_DIR}/include" "${LLD_BINARY_DIR}/include" @@ -25,7 +25,6 @@ @ONLY) set(LLD_CONFIG_CMAKE_DIR) set(LLD_CONFIG_LLVM_CMAKE_DIR) -set(LLD_CONFIG_EXPORTS_FILE) # Generate LLDConfig.cmake for the install tree. set(LLD_CONFIG_CODE " @@ -40,7 +39,7 @@ endforeach(p) set(LLD_CONFIG_CMAKE_DIR "\${LLD_INSTALL_PREFIX}/${LLD_INSTALL_PACKAGE_DIR}") set(LLD_CONFIG_LLVM_CMAKE_DIR "\${LLD_INSTALL_PREFIX}/${LLVM_INSTALL_PACKAGE_DIR}") -set(LLD_CONFIG_EXPORTS_FILE "\${LLD_CMAKE_DIR}/LLDTargets.cmake") +get_config_exports_includes(LLD lld_config_include_exports) set(LLD_CONFIG_INCLUDE_DIRS "\${LLD_INSTALL_PREFIX}/include") configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/LLDConfig.cmake.in @@ -48,14 +47,9 @@ @ONLY) set(LLD_CONFIG_CODE) set(LLD_CONFIG_CMAKE_DIR) -set(LLD_CONFIG_EXPORTS_FILE) if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY) - get_property(lld_has_exports GLOBAL PROPERTY LLD_HAS_EXPORTS) - if(lld_has_exports) - install(EXPORT LLDTargets DESTINATION ${LLD_INSTALL_PACKAGE_DIR} - COMPONENT lld-cmake-exports) - endif() + install_distribution_exports(LLD) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/LLDConfig.cmake Index: lld/cmake/modules/AddLLD.cmake =================================================================== --- lld/cmake/modules/AddLLD.cmake +++ lld/cmake/modules/AddLLD.cmake @@ -1,3 +1,5 @@ +include(LLVMDistributionSupport) + macro(add_lld_library name) cmake_parse_arguments(ARG "SHARED" @@ -11,10 +13,10 @@ set_target_properties(${name} PROPERTIES FOLDER "lld libraries") if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY) - if(${name} IN_LIST LLVM_DISTRIBUTION_COMPONENTS OR - NOT LLVM_DISTRIBUTION_COMPONENTS) - set(export_to_lldtargets EXPORT LLDTargets) - set_property(GLOBAL PROPERTY LLD_HAS_EXPORTS True) + get_llvm_distribution(${name} in_distribution distribution) + if(in_distribution) + set(export_to_lldtargets EXPORT LLD${distribution}Targets) + set_property(GLOBAL PROPERTY LLD${distribution}_HAS_EXPORTS True) endif() install(TARGETS ${name} @@ -46,10 +48,10 @@ add_lld_executable(${name} ${ARGN}) if (LLD_BUILD_TOOLS) - if(${name} IN_LIST LLVM_DISTRIBUTION_COMPONENTS OR - NOT LLVM_DISTRIBUTION_COMPONENTS) - set(export_to_lldtargets EXPORT LLDTargets) - set_property(GLOBAL PROPERTY LLD_HAS_EXPORTS True) + get_llvm_distribution(${name} in_distribution distribution) + if(in_distribution) + set(export_to_lldtargets EXPORT LLD${distribution}Targets) + set_property(GLOBAL PROPERTY LLD${distribution}_HAS_EXPORTS True) endif() install(TARGETS ${name} Index: flang/cmake/modules/FlangConfig.cmake.in =================================================================== --- flang/cmake/modules/FlangConfig.cmake.in +++ flang/cmake/modules/FlangConfig.cmake.in @@ -10,4 +10,4 @@ set(FLANG_INCLUDE_DIRS "@FLANG_CONFIG_INCLUDE_DIRS@") # Provide all our library targets to users. -include("@FLANG_CONFIG_EXPORTS_FILE@") +@flang_config_include_exports@ Index: flang/cmake/modules/CMakeLists.txt =================================================================== --- flang/cmake/modules/CMakeLists.txt +++ flang/cmake/modules/CMakeLists.txt @@ -14,7 +14,7 @@ # Generate FlangConfig.cmake for the build tree. set(FLANG_CONFIG_CMAKE_DIR "${flang_cmake_builddir}") set(FLANG_CONFIG_LLVM_CMAKE_DIR "${llvm_cmake_builddir}") -set(FLANG_CONFIG_EXPORTS_FILE "${flang_cmake_builddir}/FlangTargets.cmake") +set(flang_config_include_exports "include(\"${flang_cmake_builddir}/FlangTargets.cmake\")") set(FLANG_CONFIG_INCLUDE_DIRS "${FLANG_SOURCE_DIR}/include" "${FLANG_BINARY_DIR}/include" @@ -25,7 +25,6 @@ @ONLY) set(FLANG_CONFIG_CMAKE_DIR) set(FLANG_CONFIG_LLVM_CMAKE_DIR) -set(FLANG_CONFIG_EXPORTS_FILE) # Generate FlangConfig.cmake for the install tree. set(FLANG_CONFIG_CODE " @@ -41,7 +40,7 @@ set(FLANG_CONFIG_CMAKE_DIR "\${FLANG_INSTALL_PREFIX}/${FLANG_INSTALL_PACKAGE_DIR}") set(FLANG_CONFIG_LLVM_CMAKE_DIR "\${FLANG_INSTALL_PREFIX}/${LLVM_INSTALL_PACKAGE_DIR}") -set(FLANG_CONFIG_EXPORTS_FILE "\${FLANG_CMAKE_DIR}/FlangTargets.cmake") +get_config_exports_includes(Flang flang_config_include_exports) set(FLANG_CONFIG_INCLUDE_DIRS "\${FLANG_INSTALL_PREFIX}/include") configure_file( @@ -54,11 +53,7 @@ set(FLANG_CONFIG_EXPORTS_FILE) if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY) - get_property(flang_has_exports GLOBAL PROPERTY FLANG_HAS_EXPORTS) - if(flang_has_exports) - install(EXPORT FlangTargets DESTINATION ${FLANG_INSTALL_PACKAGE_DIR} - COMPONENT flang-cmake-exports) - endif() + install_distribution_exports(Flang) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/FlangConfig.cmake Index: flang/cmake/modules/AddFlang.cmake =================================================================== --- flang/cmake/modules/AddFlang.cmake +++ flang/cmake/modules/AddFlang.cmake @@ -1,3 +1,5 @@ +include(LLVMDistributionSupport) + macro(set_flang_windows_version_resource_properties name) if (DEFINED windows_resource_file) set_windows_version_resource_properties(${name} ${windows_resource_file} @@ -65,11 +67,10 @@ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY OR ${name} STREQUAL "libflang") set(export_to_flangtargets) - if (${name} IN_LIST LLVM_DISTRIBUTION_COMPONENTS OR - "flang-libraries" IN_LIST LLVM_DISTRIBUTION_COMPONENTS OR - NOT LLVM_DISTRIBUTION_COMPONENTS) - set(export_to_flangtargets EXPORT FlangTargets) - set_property(GLOBAL PROPERTY FLANG_HAS_EXPORTS True) + get_llvm_distribution(${name} in_distribution distribution UMBRELLA flang-libraries) + if (in_distribution) + set(export_to_flangtargets EXPORT Flang${distribution}Targets) + set_property(GLOBAL PROPERTY FLANG${distribution}_HAS_EXPORTS True) endif() install(TARGETS ${name} @@ -112,10 +113,10 @@ if (FLANG_BUILD_TOOLS) set(export_to_flangtargets) - if (${name} IN_LIST LLVM_DISTRIBUTION_COMPONENTS OR - NOT LLVM_DISTRIBUTION_COMPONENTS) - set(export_to_flangtargets EXPORT FlangTargets) - set_property(GLOBAL PROPERTY FLANG_HAS_EXPORTS True) + get_llvm_distribution(${name} in_distribution distribution) + if (in_distribution) + set(export_to_flangtargets EXPORT Flang${distribution}Targets) + set_property(GLOBAL PROPERTY FLANG${distribution}_HAS_EXPORTS True) endif() install(TARGETS ${name} Index: clang/cmake/modules/ClangConfig.cmake.in =================================================================== --- clang/cmake/modules/ClangConfig.cmake.in +++ clang/cmake/modules/ClangConfig.cmake.in @@ -11,7 +11,7 @@ set(CLANG_LINK_CLANG_DYLIB "@CLANG_LINK_CLANG_DYLIB@") # Provide all our library targets to users. -include("@CLANG_CONFIG_EXPORTS_FILE@") +@clang_config_include_exports@ # By creating clang-tablegen-targets here, subprojects that depend on Clang's # tablegen-generated headers can always depend on this target whether building Index: clang/cmake/modules/CMakeLists.txt =================================================================== --- clang/cmake/modules/CMakeLists.txt +++ clang/cmake/modules/CMakeLists.txt @@ -1,3 +1,5 @@ +include(LLVMDistributionSupport) + # Generate a list of CMake library targets so that other CMake projects can # link against them. LLVM calls its version of this file LLVMExports.cmake, but # the usual CMake convention seems to be ${Project}Targets.cmake. @@ -14,7 +16,7 @@ # Generate ClangConfig.cmake for the build tree. set(CLANG_CONFIG_CMAKE_DIR "${clang_cmake_builddir}") set(CLANG_CONFIG_LLVM_CMAKE_DIR "${llvm_cmake_builddir}") -set(CLANG_CONFIG_EXPORTS_FILE "${clang_cmake_builddir}/ClangTargets.cmake") +set(clang_config_include_exports "include(\"${clang_cmake_builddir}/ClangTargets.cmake\")") set(CLANG_CONFIG_INCLUDE_DIRS "${CLANG_SOURCE_DIR}/include" "${CLANG_BINARY_DIR}/include" @@ -25,7 +27,6 @@ @ONLY) set(CLANG_CONFIG_CMAKE_DIR) set(CLANG_CONFIG_LLVM_CMAKE_DIR) -set(CLANG_CONFIG_EXPORTS_FILE) # Generate ClangConfig.cmake for the install tree. set(CLANG_CONFIG_CODE " @@ -40,7 +41,7 @@ endforeach(p) set(CLANG_CONFIG_CMAKE_DIR "\${CLANG_INSTALL_PREFIX}/${CLANG_INSTALL_PACKAGE_DIR}") set(CLANG_CONFIG_LLVM_CMAKE_DIR "\${CLANG_INSTALL_PREFIX}/${LLVM_INSTALL_PACKAGE_DIR}") -set(CLANG_CONFIG_EXPORTS_FILE "\${CLANG_CMAKE_DIR}/ClangTargets.cmake") +get_config_exports_includes(Clang clang_config_include_exports) set(CLANG_CONFIG_INCLUDE_DIRS "\${CLANG_INSTALL_PREFIX}/include" ) @@ -50,14 +51,9 @@ @ONLY) set(CLANG_CONFIG_CODE) set(CLANG_CONFIG_CMAKE_DIR) -set(CLANG_CONFIG_EXPORTS_FILE) if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY) - get_property(clang_has_exports GLOBAL PROPERTY CLANG_HAS_EXPORTS) - if(clang_has_exports) - install(EXPORT ClangTargets DESTINATION ${CLANG_INSTALL_PACKAGE_DIR} - COMPONENT clang-cmake-exports) - endif() + install_distribution_exports(Clang) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ClangConfig.cmake Index: clang/cmake/modules/AddClang.cmake =================================================================== --- clang/cmake/modules/AddClang.cmake +++ clang/cmake/modules/AddClang.cmake @@ -1,3 +1,5 @@ +include(LLVMDistributionSupport) + function(clang_tablegen) # Syntax: # clang_tablegen output-file [tablegen-arg ...] SOURCE source-file @@ -113,11 +115,10 @@ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY OR ARG_INSTALL_WITH_TOOLCHAIN) set(export_to_clangtargets) - if(${lib} IN_LIST LLVM_DISTRIBUTION_COMPONENTS OR - "clang-libraries" IN_LIST LLVM_DISTRIBUTION_COMPONENTS OR - NOT LLVM_DISTRIBUTION_COMPONENTS) - set(export_to_clangtargets EXPORT ClangTargets) - set_property(GLOBAL PROPERTY CLANG_HAS_EXPORTS True) + get_llvm_distribution(${name} in_distribution distribution UMBRELLA clang-libraries) + if(in_distribution) + set(export_to_clangtargets EXPORT Clang${distribution}Targets) + set_property(GLOBAL PROPERTY CLANG${distribution}_HAS_EXPORTS True) endif() install(TARGETS ${lib} @@ -162,10 +163,10 @@ if (CLANG_BUILD_TOOLS) set(export_to_clangtargets) - if(${name} IN_LIST LLVM_DISTRIBUTION_COMPONENTS OR - NOT LLVM_DISTRIBUTION_COMPONENTS) - set(export_to_clangtargets EXPORT ClangTargets) - set_property(GLOBAL PROPERTY CLANG_HAS_EXPORTS True) + get_llvm_distribution(${name} in_distribution distribution) + if(in_distribution) + set(export_to_clangtargets EXPORT Clang${distribution}Targets) + set_property(GLOBAL PROPERTY CLANG${distribution}_HAS_EXPORTS True) endif() install(TARGETS ${name} Index: clang/cmake/caches/MultiDistributionExample.cmake =================================================================== --- /dev/null +++ clang/cmake/caches/MultiDistributionExample.cmake @@ -0,0 +1,74 @@ +# This file sets up a CMakeCache for a simple build with multiple distributions. +# Note that for a real distribution, you likely want to perform a boostrap +# build; see clang/cmake/caches/DistributionExample.cmake and the +# BuildingADistribution documentation for details. This cache file doesn't +# demonstrate bootstrapping so it can focus on the configuration details +# specific to multiple distributions instead. + +# Build an optimized toolchain for an example set of targets. +set(CMAKE_BUILD_TYPE Release CACHE STRING "") +set(LLVM_TARGETS_TO_BUILD + AArch64 + ARM + X86 + CACHE STRING "") + +# Enable the LLVM projects and runtimes. +set(LLVM_ENABLE_PROJECTS + clang + lld + CACHE STRING "") +set(LLVM_ENABLE_RUNTIMES + compiler-rt + libcxx + libcxxabi + CACHE STRING "") + +# We'll build two distributions: Toolchain, which just holds the tools +# (intended for most end users), and Development, which has libraries (for end +# users who wish to develop their own tooling using those libraries). This will +# produce the install-toolchain-distribution and install-development-distribution +# targets to install the distributions. +set(LLVM_DISTRIBUTIONS + Toolchain + Development + CACHE STRING "") + +# We want to include the C++ headers in our distribution. +set(LLVM_RUNTIME_DISTRIBUTION_COMPONENTS + cxx-headers + CACHE STRING "") + +# You likely want more tools; this is just an example :) Note that we need to +# include cxx-headers explicitly here (in addition to it being added to +# LLVM_RUNTIME_DISTRIBUTION_COMPONENTS above). +set(LLVM_Toolchain_DISTRIBUTION_COMPONENTS + builtins + clang + clang-resource-headers + cxx-headers + lld + llvm-objdump + CACHE STRING "") + +# Note that we need to include the CMake exports targets for the distribution +# (development-cmake-exports and clang-development-cmake-exports), as well as +# the general CMake exports target for each project (cmake-exports and +# clang-cmake-exports), in our list of targets. The distribution CMake exports +# targets just install the CMake exports file for the distribution's targets, +# whereas the project CMake exports targets install the rest of the project's +# CMake exports (which are needed in order to import the project from other +# CMake_projects via find_package, and include the distribution's CMake exports +# file to get the exported targets). +set(LLVM_Development_DISTRIBUTION_COMPONENTS + # LLVM + cmake-exports + development-cmake-exports + llvm-headers + llvm-libraries + # Clang + clang-cmake-exports + clang-development-cmake-exports + clang-headers + clang-libraries + CACHE STRING "")
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits