mirror of
https://github.com/Kitware/CMake.git
synced 2026-11-06 05:16:58 +00:00
Ninja: Add install_prep targets for minimal builds
Add `install_prep/<component>` convenience targets to the Ninja
generators to build dependencies of install components, and
`install_prep/all` to build the dependencies of all install components.
This is similar in flavor to commit ba6b6fbc24 (Ninja: Add Build
Dependencies for Tests, 2026-04-07), but here for the install command.
Co-authored-by: Tyler Yankee <tyler.yankee@kitware.com>
Issue: #27643
This commit is contained in:
1 parent
5ea2838ac6
commit
0ea2d28b54
109 files changed
+2067
-4
No files matched your search
@@ -47,6 +47,10 @@ are executed in order during installation.
|
||||
and the order that install rules added in different subdirectories will run is
|
||||
not guaranteed.
|
||||
|
||||
.. versionadded:: 4.5
|
||||
Some generators provide ``install_prep/`` build targets that build only the
|
||||
prerequisites of an installation. See :ref:`Install Preparation Targets`.
|
||||
|
||||
Common Options
|
||||
""""""""""""""
|
||||
|
||||
@@ -122,6 +126,11 @@ signatures that specify them. The common options are:
|
||||
:module:`CPackComponent` module. Global target ``list_install_components``
|
||||
lists all available components.
|
||||
|
||||
.. versionadded:: 4.5
|
||||
Some generators provide an ``install_prep/<component>`` build target that
|
||||
builds the prerequisites of installing a component. See
|
||||
:ref:`Install Preparation Targets`.
|
||||
|
||||
``EXCLUDE_FROM_ALL``
|
||||
.. versionadded:: 3.6
|
||||
|
||||
|
||||
@@ -31,6 +31,27 @@ Builtin Targets
|
||||
Created only if the :prop_gbl:`INSTALL_PARALLEL` global property is ``ON``.
|
||||
Runs the install step for each subdirectory independently and in parallel.
|
||||
|
||||
``install_prep/<component>``
|
||||
|
||||
.. versionadded:: 4.5
|
||||
|
||||
Created if the project has install rules, unless the
|
||||
:variable:`CMAKE_SKIP_INSTALL_PREP_TARGETS` or
|
||||
:variable:`CMAKE_SKIP_INSTALL_RULES` variable is enabled. Builds all known
|
||||
build dependencies for the named install component. Components whose
|
||||
names cannot be represented safely are excluded. See
|
||||
:ref:`Install Preparation Targets` and :ref:`Target Names`.
|
||||
|
||||
``install_prep/all``
|
||||
|
||||
.. versionadded:: 4.5
|
||||
|
||||
Created if the project has install rules, unless the
|
||||
:variable:`CMAKE_SKIP_INSTALL_PREP_TARGETS` or
|
||||
:variable:`CMAKE_SKIP_INSTALL_RULES` variable is enabled. Builds all known
|
||||
build dependencies for an installation that does not select a component.
|
||||
See :ref:`Install Preparation Targets`.
|
||||
|
||||
``test_prep/<test-name>``
|
||||
|
||||
.. versionadded:: 4.4
|
||||
|
||||
@@ -68,10 +68,14 @@ project-wide convenience targets.
|
||||
:manual:`cmake-generators(7)` manual for the target names documented by
|
||||
each generator.
|
||||
|
||||
Some convenience targets derive their names from other names in the project.
|
||||
The ``test_prep/<name>`` targets use test names, which have their own
|
||||
representability rules beyond those above. See also :command:`add_test` and
|
||||
:variable:`CMAKE_TEST_BUILD_DEPENDS`.
|
||||
Some convenience targets derive their names from other names in the project:
|
||||
|
||||
* The ``test_prep/<name>`` targets use test names, which have their own
|
||||
representability rules beyond those above. See also :command:`add_test`
|
||||
and :variable:`CMAKE_TEST_BUILD_DEPENDS`.
|
||||
* The ``install_prep/<component>`` targets use install component names.
|
||||
A component name may contain the characters allowed in target names above,
|
||||
plus ``:`` and ``/``. See also :ref:`Install Preparation Targets`.
|
||||
|
||||
.. _`Executables`:
|
||||
|
||||
@@ -1773,3 +1777,109 @@ target properties with a limited set of names:
|
||||
* .. versionadded:: 3.11
|
||||
Properties named with a leading underscore (``_``)
|
||||
or lowercase ASCII character.
|
||||
|
||||
Preparation Targets
|
||||
===================
|
||||
|
||||
The :ref:`Ninja Generators` provide convenience targets that build only the
|
||||
prerequisites of a later step, such as running tests or installing.
|
||||
|
||||
.. _`Install Preparation Targets`:
|
||||
|
||||
Install Preparation Targets
|
||||
---------------------------
|
||||
|
||||
.. versionadded:: 4.5
|
||||
|
||||
If the project has install rules, the generators which support preparation
|
||||
targets provide convenience build targets that build the known prerequisites
|
||||
of an installation before running the installation, unless
|
||||
:variable:`CMAKE_SKIP_INSTALL_PREP_TARGETS` or
|
||||
:variable:`CMAKE_SKIP_INSTALL_RULES` is enabled:
|
||||
|
||||
``install_prep/all``
|
||||
Prepare for an installation that does not select a component, such as
|
||||
:option:`cmake --install \<build-dir\> <cmake --install>` without
|
||||
:cmake-install-option:`--component`. This includes rules of every component,
|
||||
but omits :command:`install` rules using the ``EXCLUDE_FROM_ALL`` option.
|
||||
|
||||
``install_prep/<component>``
|
||||
Prepare to install ``<component>``. Rules for that component are included
|
||||
even when they use the ``EXCLUDE_FROM_ALL`` option.
|
||||
|
||||
Building ``install_prep/all`` does not necessarily prepare the installation
|
||||
of a particular component, because installing a component also runs that
|
||||
component's ``EXCLUDE_FROM_ALL`` rules. Build the matching
|
||||
``install_prep/<component>`` target before installing a specific component.
|
||||
|
||||
For example:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
cmake --build <build-dir> --config Release --target install_prep/Runtime
|
||||
cmake --install <build-dir> --config Release --component Runtime
|
||||
|
||||
Only install rules active for the selected configuration contribute build
|
||||
dependencies. For multi-config generators, the same configuration should
|
||||
be used for the preparation and installation steps.
|
||||
|
||||
A component preparation target is generated only when its name can be
|
||||
represented safely by the native build tool, as described under
|
||||
:ref:`Target Names`. CMake warns about a component that has build
|
||||
dependencies but whose name cannot be represented.
|
||||
|
||||
.. note::
|
||||
A component named ``all`` does not get its own target because its name would
|
||||
conflict with ``install_prep/all``. Its rules contribute to
|
||||
``install_prep/all`` only when they do not use the ``EXCLUDE_FROM_ALL``
|
||||
option.
|
||||
|
||||
CMake infers dependencies associated with installed target artifacts,
|
||||
imported runtime artifacts, runtime dependency sets, C++ module BMIs, and
|
||||
C++ module export metadata. Preparing BMIs or module export metadata builds
|
||||
the targets that produce them.
|
||||
|
||||
Installing files with the ``FILES`` or ``PROGRAMS`` signatures of the
|
||||
:command:`install` command, or a target's file sets or its
|
||||
:prop_tgt:`PUBLIC_HEADER`, :prop_tgt:`PRIVATE_HEADER`, or :prop_tgt:`RESOURCE`
|
||||
files, implies build dependencies only for files that the build produces,
|
||||
i.e., target output artifacts, and outputs and byproducts of custom commands
|
||||
and custom targets. How such a file is prepared depends on how it is produced:
|
||||
|
||||
* A target's output artifact, such as one named by :genex:`TARGET_FILE`, is
|
||||
prepared by building that target.
|
||||
|
||||
* A file that is the output of a custom command attached to exactly one
|
||||
target is prepared by running that custom command. The target which
|
||||
installs the file (or the file set to which the file belongs), if any, is
|
||||
not built.
|
||||
|
||||
* Any other generated file, such as a byproduct or the output of a custom
|
||||
command attached to more than one target, is prepared by depending on the
|
||||
file itself, which runs whatever produces it.
|
||||
|
||||
For example:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
# Preparation runs only the custom command, not the library build.
|
||||
add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/generated.h"
|
||||
COMMAND ...)
|
||||
add_library(A a.c "${CMAKE_CURRENT_BINARY_DIR}/generated.h")
|
||||
set_property(TARGET A PROPERTY PUBLIC_HEADER
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/generated.h")
|
||||
|
||||
# Preparation runs gen, the producer of the byproduct.
|
||||
add_custom_target(gen COMMAND ...
|
||||
BYPRODUCTS "${CMAKE_CURRENT_BINARY_DIR}/byproduct.h")
|
||||
add_library(B b.c)
|
||||
add_dependencies(B gen)
|
||||
set_property(TARGET B PROPERTY PUBLIC_HEADER
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/byproduct.h")
|
||||
|
||||
Rules created by the ``DIRECTORY``, ``SCRIPT``, and ``CODE`` signatures of
|
||||
the :command:`install` command, or by the deprecated
|
||||
:command:`install_targets` command, do not imply build dependencies.
|
||||
|
||||
Install rules below a directory added with :prop_dir:`EXCLUDE_FROM_ALL` are
|
||||
ignored, matching installation from the parent directory.
|
||||
@@ -299,6 +299,7 @@ Variables that Change Behavior
|
||||
/variable/CMAKE_PROJECT_TOP_LEVEL_INCLUDES
|
||||
/variable/CMAKE_REQUIRE_FIND_PACKAGE_PackageName
|
||||
/variable/CMAKE_SKIP_INSTALL_ALL_DEPENDENCY
|
||||
/variable/CMAKE_SKIP_INSTALL_PREP_TARGETS
|
||||
/variable/CMAKE_SKIP_TEST_ALL_DEPENDENCY
|
||||
/variable/CMAKE_STAGING_PREFIX
|
||||
/variable/CMAKE_SUBLIME_TEXT_2_ENV_SETTINGS
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
CMAKE_SKIP_INSTALL_PREP_TARGETS
|
||||
-------------------------------
|
||||
|
||||
.. versionadded:: 4.5
|
||||
|
||||
Do not generate ``install_prep/<component>`` and ``install_prep/all`` build
|
||||
targets.
|
||||
|
||||
When this variable is set to a true value, CMake does not generate the
|
||||
preparation targets that build the known prerequisites of a subsequent
|
||||
component-specific or full installation, even when using a generator
|
||||
that supports them. See :ref:`Install Preparation Targets`. The
|
||||
preparation targets are also not generated if the project has no install
|
||||
rules or :variable:`CMAKE_SKIP_INSTALL_RULES` is enabled.
|
||||
|
||||
Set this variable in the top-level directory. It is off by default, in
|
||||
which case the preparation targets are generated.
|
||||
@@ -539,6 +539,8 @@ Entry const kEntries[] = {
|
||||
"Do not include RPATHs in the build tree"_s },
|
||||
{ "CMAKE_SKIP_INSTALL_ALL_DEPENDENCY"_s,
|
||||
"If true, install target does not depend on all target; installation proceeds independently of build status."_s },
|
||||
{ "CMAKE_SKIP_INSTALL_PREP_TARGETS"_s,
|
||||
"Do not generate install_prep/<component> and install_prep/all build targets."_s },
|
||||
{ "CMAKE_SKIP_INSTALL_RPATH"_s,
|
||||
"Do not include RPATHs in the install tree"_s },
|
||||
{ "CMAKE_SKIP_LINTING"_s,
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
#include "cmInstallGenerator.h"
|
||||
#include "cmInstallRuntimeDependencySet.h"
|
||||
#include "cmInstallSbomGenerator.h"
|
||||
#include "cmLinkItem.h"
|
||||
#include "cmLinkLineComputer.h"
|
||||
#include "cmList.h"
|
||||
#include "cmListFileCache.h"
|
||||
@@ -2583,6 +2584,8 @@ void cmGlobalGenerator::ClearGeneratorMembers()
|
||||
this->GeneratedByBuildIndex.clear();
|
||||
this->GeneratedByBuildIndexComputed = false;
|
||||
|
||||
this->InstallPrepDependencies.clear();
|
||||
|
||||
this->Makefiles.clear();
|
||||
|
||||
this->LocalGenerators.clear();
|
||||
@@ -3380,6 +3383,246 @@ std::string cmGlobalGenerator::GetTestBuildDependencyPath(
|
||||
return target->GetFullPath(config);
|
||||
}
|
||||
|
||||
std::vector<cmInstallGenerator::BuildDependency> const&
|
||||
cmGlobalGenerator::GetInstallPrepDependencies(
|
||||
cmInstallGenerator const* installer, std::string const& config)
|
||||
{
|
||||
auto const inserted = this->InstallPrepDependencies.emplace(
|
||||
std::make_pair(installer, config),
|
||||
std::vector<cmInstallGenerator::BuildDependency>());
|
||||
if (inserted.second) {
|
||||
installer->GetInstallBuildDependencies(config, inserted.first->second);
|
||||
}
|
||||
return inserted.first->second;
|
||||
}
|
||||
|
||||
cmGlobalGenerator::InstallPrepTargets cmGlobalGenerator::GetInstallPrepTargets(
|
||||
std::string const& config)
|
||||
{
|
||||
InstallPrepTargets prepTargets;
|
||||
if (!this->AreInstallPrepTargetsEnabled()) {
|
||||
return prepTargets;
|
||||
}
|
||||
|
||||
auto isRepresentableComponent = [this](std::string const& component) {
|
||||
return component != "all" &&
|
||||
this->IsInstallPrepComponentRepresentable(component);
|
||||
};
|
||||
|
||||
for (std::string const& component : this->InstallComponents) {
|
||||
if (isRepresentableComponent(component)) {
|
||||
prepTargets.Components[component];
|
||||
}
|
||||
}
|
||||
|
||||
auto addDependency = [](InstallPrepTargets::TargetMap& targets,
|
||||
cmInstallGenerator::BuildDependency dependency) {
|
||||
if (dependency.Type ==
|
||||
cmInstallGenerator::BuildDependencyType::GeneratedFile) {
|
||||
targets[dependency.Target].GeneratedFiles.insert(dependency.File);
|
||||
return;
|
||||
}
|
||||
std::set<cmGeneratorTarget const*> visited;
|
||||
std::function<void(cmGeneratorTarget const*,
|
||||
cmInstallGenerator::BuildDependencyType)>
|
||||
addTarget;
|
||||
addTarget = [&addTarget, &targets,
|
||||
&visited](cmGeneratorTarget const* target,
|
||||
cmInstallGenerator::BuildDependencyType type) {
|
||||
if (!target || !visited.insert(target).second) {
|
||||
return;
|
||||
}
|
||||
if (!target->IsInBuildSystem() || target->IsImported()) {
|
||||
for (cmLinkItem const& utility : target->GetUtilityItems()) {
|
||||
addTarget(utility.Target,
|
||||
cmInstallGenerator::BuildDependencyType::Normal);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
InstallPrepTargets::TargetRequirements& requirements = targets[target];
|
||||
if (type == cmInstallGenerator::BuildDependencyType::InstallArtifact) {
|
||||
requirements.InstallArtifact = true;
|
||||
} else {
|
||||
requirements.Normal = true;
|
||||
}
|
||||
};
|
||||
addTarget(dependency.Target, dependency.Type);
|
||||
};
|
||||
|
||||
for (auto const& localGen : this->LocalGenerators) {
|
||||
if (this->IsExcluded(this->LocalGenerators.front().get(),
|
||||
localGen.get())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (auto const& installer :
|
||||
localGen->GetMakefile()->GetInstallGenerators()) {
|
||||
if (!installer->InstallsForConfig(config)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::vector<cmInstallGenerator::BuildDependency> const& dependencies =
|
||||
this->GetInstallPrepDependencies(installer.get(), config);
|
||||
std::vector<std::string> components;
|
||||
installer->GetInstallBuildDependencyComponents(components);
|
||||
for (cmInstallGenerator::BuildDependency const& dependency :
|
||||
dependencies) {
|
||||
if (!dependency.Target) {
|
||||
// A generated file that no target prepares.
|
||||
if (dependency.Type ==
|
||||
cmInstallGenerator::BuildDependencyType::GeneratedFile) {
|
||||
if (installer->GetAllComponentsFlag()) {
|
||||
for (auto const& component : prepTargets.Components) {
|
||||
prepTargets.ComponentFiles[component.first].insert(
|
||||
dependency.File);
|
||||
}
|
||||
} else {
|
||||
for (std::string const& component : components) {
|
||||
if (isRepresentableComponent(component)) {
|
||||
prepTargets.ComponentFiles[component].insert(
|
||||
dependency.File);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!installer->GetExcludeFromAll()) {
|
||||
prepTargets.AllFiles.insert(dependency.File);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (installer->GetAllComponentsFlag()) {
|
||||
for (auto& component : prepTargets.Components) {
|
||||
addDependency(component.second, dependency);
|
||||
}
|
||||
} else {
|
||||
for (std::string const& component : components) {
|
||||
if (isRepresentableComponent(component)) {
|
||||
addDependency(prepTargets.Components[component], dependency);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!installer->GetExcludeFromAll()) {
|
||||
addDependency(prepTargets.All, dependency);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return prepTargets;
|
||||
}
|
||||
|
||||
bool cmGlobalGenerator::IsInstallPrepComponentRepresentable(
|
||||
std::string const& component) const
|
||||
{
|
||||
static cmsys::RegularExpression const invalidComponentRegex(
|
||||
"[^a-zA-Z0-9_.:+/-]|(^|/)\\.?\\.?($|/)");
|
||||
cmsys::RegularExpressionMatch match;
|
||||
return !component.empty() &&
|
||||
!invalidComponentRegex.find(component.c_str(), match);
|
||||
}
|
||||
|
||||
void cmGlobalGenerator::CheckInstallPrepTargets()
|
||||
{
|
||||
if (!this->AreInstallPrepTargetsEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Diagnose install rules with build dependencies that no preparation target
|
||||
// builds.
|
||||
std::vector<std::string> const configs =
|
||||
this->Makefiles.front()->GetGeneratorConfigs(
|
||||
cmMakefile::IncludeEmptyConfig);
|
||||
std::set<std::string> unrepresentableComponents;
|
||||
std::set<std::string> unpreparedFiles;
|
||||
for (auto const& localGen : this->LocalGenerators) {
|
||||
if (this->IsExcluded(this->LocalGenerators.front().get(),
|
||||
localGen.get())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (auto const& installer :
|
||||
localGen->GetMakefile()->GetInstallGenerators()) {
|
||||
std::vector<cmInstallGenerator::BuildDependency> dependencies;
|
||||
for (std::string const& config : configs) {
|
||||
if (installer->InstallsForConfig(config)) {
|
||||
std::vector<cmInstallGenerator::BuildDependency> const&
|
||||
configDependencies =
|
||||
this->GetInstallPrepDependencies(installer.get(), config);
|
||||
dependencies.insert(dependencies.end(), configDependencies.begin(),
|
||||
configDependencies.end());
|
||||
}
|
||||
}
|
||||
|
||||
// A generated file that no target prepares.
|
||||
if (!this->SupportsInstallPrepFileDependencies()) {
|
||||
for (cmInstallGenerator::BuildDependency const& dependency :
|
||||
dependencies) {
|
||||
if (!dependency.Target &&
|
||||
dependency.Type ==
|
||||
cmInstallGenerator::BuildDependencyType::GeneratedFile &&
|
||||
unpreparedFiles.insert(dependency.File).second) {
|
||||
localGen->IssueDiagnostic(
|
||||
cmDiagnostics::CMD_AUTHOR,
|
||||
cmStrCat("An install rule installs or depends on file\n ",
|
||||
dependency.File,
|
||||
"\nwhich is generated but is not the unique output of "
|
||||
"a build target, so \"install_prep/\" targets cannot "
|
||||
"build it with this generator. Produce the file with "
|
||||
"a custom command attached to a single target to "
|
||||
"prepare it."),
|
||||
installer->GetDiagnosticContext());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (installer->GetAllComponentsFlag() || dependencies.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::vector<std::string> components;
|
||||
installer->GetInstallBuildDependencyComponents(components);
|
||||
for (std::string const& component : components) {
|
||||
if (component == "all") {
|
||||
// A component named "all" has no preparation target of its own,
|
||||
// and install_prep/all omits EXCLUDE_FROM_ALL rules.
|
||||
if (installer->GetExcludeFromAll()) {
|
||||
localGen->IssueDiagnostic(
|
||||
cmDiagnostics::CMD_AUTHOR,
|
||||
"An install rule in the component named \"all\" uses "
|
||||
"EXCLUDE_FROM_ALL and has build dependencies, but no "
|
||||
"install_prep/ target builds them: install_prep/all omits "
|
||||
"EXCLUDE_FROM_ALL rules, and the \"all\" component has no "
|
||||
"preparation target of its own. Rename the component or "
|
||||
"remove EXCLUDE_FROM_ALL.",
|
||||
installer->GetDiagnosticContext());
|
||||
}
|
||||
} else if (!this->IsInstallPrepComponentRepresentable(component) &&
|
||||
unrepresentableComponents.insert(component).second) {
|
||||
localGen->IssueDiagnostic(
|
||||
cmDiagnostics::CMD_AUTHOR,
|
||||
cmStrCat("The install component \"", component,
|
||||
"\" has build dependencies, but its name cannot be used "
|
||||
"in a build target name with this generator. No "
|
||||
"\"install_prep/\" target will be generated for it. "
|
||||
"Rename the component to build its dependencies with an "
|
||||
"\"install_prep/\" target."),
|
||||
installer->GetDiagnosticContext());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool cmGlobalGenerator::AreInstallPrepTargetsEnabled() const
|
||||
{
|
||||
return !this->Makefiles.empty() && this->InstallTargetEnabled &&
|
||||
!this->Makefiles.front()->IsOn("CMAKE_SKIP_INSTALL_PREP_TARGETS") &&
|
||||
!this->Makefiles.front()->IsOn("CMAKE_SKIP_INSTALL_RULES");
|
||||
}
|
||||
|
||||
// If the file has no extension it's either a raw executable or might
|
||||
// be a direct reference to a binary within a framework (bad practice!).
|
||||
// This is where we change the path to point to the framework directory.
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "cmDuration.h"
|
||||
#include "cmExportFileGenerator.h"
|
||||
#include "cmExportSet.h"
|
||||
#include "cmInstallGenerator.h"
|
||||
#include "cmLocalGenerator.h"
|
||||
#include "cmSbomBuilder.h"
|
||||
#include "cmStateSnapshot.h"
|
||||
@@ -137,6 +138,44 @@ public:
|
||||
std::string const& config,
|
||||
cmTestGenerator::BuildDependencies const& deps) const;
|
||||
|
||||
struct InstallPrepTargets
|
||||
{
|
||||
struct TargetRequirements
|
||||
{
|
||||
bool Normal = false;
|
||||
bool InstallArtifact = false;
|
||||
std::set<std::string> GeneratedFiles;
|
||||
};
|
||||
|
||||
using TargetMap = std::map<cmGeneratorTarget const*, TargetRequirements>;
|
||||
|
||||
TargetMap All;
|
||||
std::map<std::string, TargetMap> Components;
|
||||
|
||||
// Generated files that no target prepares, such as byproducts installed
|
||||
// by install(FILES). Only generators that support depending on them
|
||||
// prepare these files.
|
||||
std::set<std::string> AllFiles;
|
||||
std::map<std::string, std::set<std::string>> ComponentFiles;
|
||||
};
|
||||
|
||||
InstallPrepTargets GetInstallPrepTargets(std::string const& config);
|
||||
|
||||
// Whether install preparation targets can depend on a generated file that
|
||||
// is not the unique output of a target.
|
||||
virtual bool SupportsInstallPrepFileDependencies() const { return false; }
|
||||
|
||||
// Whether the name of an install component can be used in the name of its
|
||||
// install preparation target.
|
||||
virtual bool IsInstallPrepComponentRepresentable(
|
||||
std::string const& component) const;
|
||||
|
||||
// Diagnose install rules that no install preparation target prepares.
|
||||
// Generators that write install preparation targets call this once.
|
||||
void CheckInstallPrepTargets();
|
||||
|
||||
bool AreInstallPrepTargetsEnabled() const;
|
||||
|
||||
/** Check whether the given name matches the current generator. */
|
||||
virtual bool MatchesGeneratorName(std::string const& name) const
|
||||
{
|
||||
@@ -1049,6 +1088,16 @@ private:
|
||||
std::unordered_set<std::string> GeneratedByBuildIndex;
|
||||
bool GeneratedByBuildIndexComputed = false;
|
||||
|
||||
// The build dependencies of each install rule for each configuration,
|
||||
// computed once and shared by CheckInstallPrepTargets and
|
||||
// GetInstallPrepTargets.
|
||||
std::map<std::pair<cmInstallGenerator const*, std::string>,
|
||||
std::vector<cmInstallGenerator::BuildDependency>>
|
||||
InstallPrepDependencies;
|
||||
std::vector<cmInstallGenerator::BuildDependency> const&
|
||||
GetInstallPrepDependencies(cmInstallGenerator const* installer,
|
||||
std::string const& config);
|
||||
|
||||
friend class cmake;
|
||||
void CreateGeneratorTargets(
|
||||
TargetTypes targetTypes, cmMakefile* mf, cmLocalGenerator* lg,
|
||||
|
||||
@@ -647,6 +647,7 @@ void cmGlobalNinjaGenerator::Generate()
|
||||
this->cmGlobalGenerator::Generate();
|
||||
|
||||
this->WriteAssumedSourceDependencies();
|
||||
this->WriteInstallPrepTargets();
|
||||
this->WriteTestPrepTargets();
|
||||
this->WriteTargetAliases(*this->GetCommonFileStream());
|
||||
this->WriteFolderTargets(*this->GetCommonFileStream());
|
||||
@@ -1298,6 +1299,61 @@ void cmGlobalNinjaGenerator::WriteAssumedSourceDependencies()
|
||||
}
|
||||
}
|
||||
|
||||
void cmGlobalNinjaGenerator::WriteInstallPrepTargets()
|
||||
{
|
||||
if (!this->AreInstallPrepTargetsEnabled()) {
|
||||
return;
|
||||
}
|
||||
this->CheckInstallPrepTargets();
|
||||
|
||||
auto writeConfig = [this](std::string const& config, std::ostream& os) {
|
||||
auto writePrepTarget =
|
||||
[this, &config,
|
||||
&os](std::string const& name,
|
||||
cmGlobalGenerator::InstallPrepTargets::TargetMap const& targets,
|
||||
std::set<std::string> const& files) {
|
||||
cmNinjaBuild build("phony");
|
||||
build.Outputs.push_back(this->ConvertToNinjaPath(name));
|
||||
for (std::string const& file : files) {
|
||||
build.ExplicitDeps.push_back(this->ConvertToNinjaPath(file));
|
||||
}
|
||||
for (auto const& target : targets) {
|
||||
if (target.second.Normal || target.second.InstallArtifact) {
|
||||
this->AppendTargetOutputs(target.first, build.ExplicitDeps, config,
|
||||
DependOnTargetArtifact);
|
||||
}
|
||||
for (std::string const& file : target.second.GeneratedFiles) {
|
||||
build.ExplicitDeps.push_back(this->ConvertToNinjaPath(file));
|
||||
}
|
||||
}
|
||||
std::sort(build.ExplicitDeps.begin(), build.ExplicitDeps.end());
|
||||
build.ExplicitDeps.erase(
|
||||
std::unique(build.ExplicitDeps.begin(), build.ExplicitDeps.end()),
|
||||
build.ExplicitDeps.end());
|
||||
this->WriteBuild(os, build);
|
||||
};
|
||||
|
||||
InstallPrepTargets const prepTargets = this->GetInstallPrepTargets(config);
|
||||
std::set<std::string> const noFiles;
|
||||
for (auto const& component : prepTargets.Components) {
|
||||
auto const it = prepTargets.ComponentFiles.find(component.first);
|
||||
std::set<std::string> const& files =
|
||||
it == prepTargets.ComponentFiles.end() ? noFiles : it->second;
|
||||
writePrepTarget(cmStrCat("install_prep/", component.first),
|
||||
component.second, files);
|
||||
}
|
||||
writePrepTarget("install_prep/all", prepTargets.All, prepTargets.AllFiles);
|
||||
};
|
||||
|
||||
if (this->IsMultiConfig()) {
|
||||
for (std::string const& config : this->GetConfigNames()) {
|
||||
writeConfig(config, *this->GetConfigFileStream(config));
|
||||
}
|
||||
} else {
|
||||
writeConfig(this->GetConfigNames().front(), *this->GetCommonFileStream());
|
||||
}
|
||||
}
|
||||
|
||||
void cmGlobalNinjaGenerator::WriteTestPrepTargets()
|
||||
{
|
||||
auto writeConfig = [this](std::string const& config, std::ostream& os) {
|
||||
|
||||
@@ -103,6 +103,8 @@ public:
|
||||
|
||||
bool IsIPOSupported() const override { return true; }
|
||||
|
||||
bool SupportsInstallPrepFileDependencies() const override { return true; }
|
||||
|
||||
/**
|
||||
* Write a build statement @a build to @a os.
|
||||
* @warning no escaping of any kind is done here.
|
||||
@@ -532,6 +534,7 @@ private:
|
||||
void WriteDisclaimer(std::ostream& os) const;
|
||||
|
||||
void WriteAssumedSourceDependencies();
|
||||
void WriteInstallPrepTargets();
|
||||
void WriteTestPrepTargets();
|
||||
|
||||
void WriteTargetAliases(std::ostream& os);
|
||||
|
||||
@@ -866,6 +866,7 @@ bool CreateInstallGeneratorsForTarget(
|
||||
privateHeaderGenerator = CreateInstallFilesGenerator(
|
||||
helper.Makefile, absFiles, privateHeaderArgs, false,
|
||||
helper.GetIncludeDestination(&privateHeaderArgs), configurations);
|
||||
privateHeaderGenerator->SetOwningTarget(target.GetName());
|
||||
} else {
|
||||
helper.Makefile->IssueDiagnostic(
|
||||
cmDiagnostics::CMD_AUTHOR,
|
||||
@@ -889,6 +890,7 @@ bool CreateInstallGeneratorsForTarget(
|
||||
publicHeaderGenerator = CreateInstallFilesGenerator(
|
||||
helper.Makefile, absFiles, publicHeaderArgs, false,
|
||||
helper.GetIncludeDestination(&publicHeaderArgs), configurations);
|
||||
publicHeaderGenerator->SetOwningTarget(target.GetName());
|
||||
} else {
|
||||
helper.Makefile->IssueDiagnostic(
|
||||
cmDiagnostics::CMD_AUTHOR,
|
||||
@@ -912,6 +914,7 @@ bool CreateInstallGeneratorsForTarget(
|
||||
resourceGenerator = CreateInstallFilesGenerator(
|
||||
helper.Makefile, absFiles, resourceArgs, false,
|
||||
resourceArgs.GetDestination(), configurations);
|
||||
resourceGenerator->SetOwningTarget(target.GetName());
|
||||
} else if (!target.IsAppBundleOnApple()) {
|
||||
helper.Makefile->IssueDiagnostic(
|
||||
cmDiagnostics::CMD_AUTHOR,
|
||||
|
||||
@@ -43,6 +43,15 @@ bool cmInstallCxxModuleBmiGenerator::Compute(cmLocalGenerator* lg)
|
||||
return true;
|
||||
}
|
||||
|
||||
void cmInstallCxxModuleBmiGenerator::GetInstallBuildDependencies(
|
||||
std::string const& config, std::vector<BuildDependency>& dependencies) const
|
||||
{
|
||||
if (this->Target && this->Target->HaveInterfaceCxx20ModuleSources() &&
|
||||
!this->GetDestination(config).empty()) {
|
||||
dependencies.push_back({ this->Target, BuildDependencyType::Normal });
|
||||
}
|
||||
}
|
||||
|
||||
std::string cmInstallCxxModuleBmiGenerator::GetScriptLocation(
|
||||
std::string const& config) const
|
||||
{
|
||||
|
||||
@@ -29,6 +29,10 @@ public:
|
||||
|
||||
bool Compute(cmLocalGenerator* lg) override;
|
||||
|
||||
void GetInstallBuildDependencies(
|
||||
std::string const& config,
|
||||
std::vector<BuildDependency>& dependencies) const override;
|
||||
|
||||
std::string const& GetFilePermissions() const
|
||||
{
|
||||
return this->FilePermissions;
|
||||
|
||||
@@ -10,11 +10,13 @@
|
||||
#include "cmDiagnosticContext.h"
|
||||
#include "cmExportInstallFileGenerator.h"
|
||||
#include "cmExportSet.h"
|
||||
#include "cmGeneratorTarget.h"
|
||||
#include "cmInstallType.h"
|
||||
#include "cmLocalGenerator.h"
|
||||
#include "cmScriptGenerator.h"
|
||||
#include "cmStringAlgorithms.h"
|
||||
#include "cmSystemTools.h"
|
||||
#include "cmTargetExport.h"
|
||||
|
||||
cmInstallExportGenerator::cmInstallExportGenerator(
|
||||
cmExportSet* exportSet, std::string destination, std::string filePermissions,
|
||||
@@ -42,6 +44,23 @@ bool cmInstallExportGenerator::Compute(cmLocalGenerator* lg)
|
||||
return this->ExportSet->Compute(lg);
|
||||
}
|
||||
|
||||
void cmInstallExportGenerator::GetInstallBuildDependencies(
|
||||
std::string const&, std::vector<BuildDependency>& dependencies) const
|
||||
{
|
||||
if (this->CxxModulesDirectory.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Module export metadata is generated during the target's build.
|
||||
for (auto const& targetExport : this->ExportSet->GetTargetExports()) {
|
||||
auto const* target = targetExport->Target;
|
||||
if (!targetExport->NamelinkOnly && target &&
|
||||
target->HaveCxx20ModuleSources()) {
|
||||
dependencies.push_back({ target, BuildDependencyType::Normal });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string cmInstallExportGenerator::TempDirCalculate() const
|
||||
{
|
||||
// Choose a temporary directory in which to generate the import
|
||||
|
||||
@@ -42,6 +42,10 @@ public:
|
||||
|
||||
bool Compute(cmLocalGenerator* lg) override;
|
||||
|
||||
void GetInstallBuildDependencies(
|
||||
std::string const& config,
|
||||
std::vector<BuildDependency>& dependencies) const override;
|
||||
|
||||
cmLocalGenerator* GetLocalGenerator() const { return this->LocalGenerator; }
|
||||
|
||||
std::string const& GetNamespace() const { return this->Namespace; }
|
||||
|
||||
@@ -93,6 +93,21 @@ bool cmInstallFileSetGenerator::Compute(cmLocalGenerator* lg)
|
||||
return true;
|
||||
}
|
||||
|
||||
void cmInstallFileSetGenerator::GetInstallBuildDependencies(
|
||||
std::string const& config, std::vector<BuildDependency>& dependencies) const
|
||||
{
|
||||
if (!this->FileSet) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<std::string> files;
|
||||
for (auto const& dirEntry : this->CalculateFilesPerDir(config)) {
|
||||
files.insert(files.end(), dirEntry.second.begin(), dirEntry.second.end());
|
||||
}
|
||||
AddGeneratedFileDependencies(this->LocalGenerator->GetGlobalGenerator(),
|
||||
config, this->Target, files, dependencies);
|
||||
}
|
||||
|
||||
std::string cmInstallFileSetGenerator::GetDestination() const
|
||||
{
|
||||
this->CheckAbsoluteDestination(this->Destination, this->LocalGenerator);
|
||||
|
||||
@@ -29,6 +29,10 @@ public:
|
||||
|
||||
bool Compute(cmLocalGenerator* lg) override;
|
||||
|
||||
void GetInstallBuildDependencies(
|
||||
std::string const& config,
|
||||
std::vector<BuildDependency>& dependencies) const override;
|
||||
|
||||
struct DestinationContext
|
||||
{
|
||||
std::string UnescapedDestination;
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "cmGeneratorExpression.h"
|
||||
#include "cmInstallType.h"
|
||||
#include "cmList.h"
|
||||
#include "cmLocalGenerator.h"
|
||||
|
||||
cmInstallFilesGenerator::cmInstallFilesGenerator(
|
||||
std::vector<std::string> const& files, std::string const& dest,
|
||||
@@ -48,9 +49,20 @@ cmInstallFilesGenerator::~cmInstallFilesGenerator() = default;
|
||||
bool cmInstallFilesGenerator::Compute(cmLocalGenerator* lg)
|
||||
{
|
||||
this->LocalGenerator = lg;
|
||||
if (!this->OwningTargetName.empty()) {
|
||||
this->OwningTarget = lg->FindGeneratorTargetToUse(this->OwningTargetName);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void cmInstallFilesGenerator::GetInstallBuildDependencies(
|
||||
std::string const& config, std::vector<BuildDependency>& dependencies) const
|
||||
{
|
||||
AddGeneratedFileDependencies(this->LocalGenerator->GetGlobalGenerator(),
|
||||
config, this->OwningTarget,
|
||||
this->GetFiles(config), dependencies);
|
||||
}
|
||||
|
||||
std::string cmInstallFilesGenerator::GetDestination(
|
||||
std::string const& config) const
|
||||
{
|
||||
|
||||
@@ -6,11 +6,13 @@
|
||||
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "cmInstallGenerator.h"
|
||||
|
||||
class cmDiagnosticContext;
|
||||
class cmGeneratorTarget;
|
||||
class cmLocalGenerator;
|
||||
|
||||
/** \class cmInstallFilesGenerator
|
||||
@@ -30,11 +32,20 @@ public:
|
||||
|
||||
bool Compute(cmLocalGenerator* lg) override;
|
||||
|
||||
void GetInstallBuildDependencies(
|
||||
std::string const& config,
|
||||
std::vector<BuildDependency>& dependencies) const override;
|
||||
|
||||
std::string GetDestination(std::string const& config) const;
|
||||
std::string GetRename(std::string const& config) const;
|
||||
std::vector<std::string> GetFiles(std::string const& config) const;
|
||||
bool GetOptional() const { return this->Optional; }
|
||||
|
||||
void SetOwningTarget(std::string targetName)
|
||||
{
|
||||
this->OwningTargetName = std::move(targetName);
|
||||
}
|
||||
|
||||
protected:
|
||||
void GenerateScriptActions(std::ostream& os, Indent indent) override;
|
||||
void GenerateScriptForConfig(std::ostream& os, std::string const& config,
|
||||
@@ -47,6 +58,8 @@ protected:
|
||||
std::vector<std::string> const Files;
|
||||
std::string const FilePermissions;
|
||||
std::string const Rename;
|
||||
std::string OwningTargetName;
|
||||
cmGeneratorTarget const* OwningTarget = nullptr;
|
||||
bool const Programs;
|
||||
bool const Optional;
|
||||
};
|
||||
@@ -8,6 +8,8 @@
|
||||
#include <cm/string_view>
|
||||
|
||||
#include "cmDiagnostics.h"
|
||||
#include "cmGeneratorTarget.h"
|
||||
#include "cmGlobalGenerator.h"
|
||||
#include "cmLocalGenerator.h"
|
||||
#include "cmMakefile.h"
|
||||
#include "cmStringAlgorithms.h"
|
||||
@@ -282,6 +284,25 @@ std::string cmInstallGenerator::GetDestDirPath(std::string const& file)
|
||||
return toDestDirPath;
|
||||
}
|
||||
|
||||
void cmInstallGenerator::AddGeneratedFileDependencies(
|
||||
cmGlobalGenerator* gg, std::string const& config,
|
||||
cmGeneratorTarget const* target, std::vector<std::string> const& files,
|
||||
std::vector<BuildDependency>& dependencies)
|
||||
{
|
||||
for (std::string const& file : files) {
|
||||
if (cmGeneratorTarget const* owner = gg->FindOutputOwningTarget(file)) {
|
||||
dependencies.push_back(
|
||||
{ owner, BuildDependencyType::GeneratedFile, file });
|
||||
} else if (cmGeneratorTarget const* linker =
|
||||
gg->FindArtifactOwningTarget(file, config)) {
|
||||
dependencies.push_back({ linker, BuildDependencyType::Normal });
|
||||
} else if (gg->IsGeneratedByBuild(file)) {
|
||||
dependencies.push_back(
|
||||
{ target, BuildDependencyType::GeneratedFile, file });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cmInstallGenerator::AddTweak(std::ostream& os, Indent indent,
|
||||
std::string const& config,
|
||||
std::string const& file,
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <functional>
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "cmDiagnosticContext.h"
|
||||
@@ -16,6 +17,8 @@
|
||||
class cmLocalGenerator;
|
||||
class cmMakefile;
|
||||
class cmListFileBacktrace;
|
||||
class cmGeneratorTarget;
|
||||
class cmGlobalGenerator;
|
||||
|
||||
/** \class cmInstallGenerator
|
||||
* \brief Support class for generating install scripts.
|
||||
@@ -24,6 +27,28 @@ class cmListFileBacktrace;
|
||||
class cmInstallGenerator : public cmScriptGenerator
|
||||
{
|
||||
public:
|
||||
enum class BuildDependencyType
|
||||
{
|
||||
Normal,
|
||||
InstallArtifact,
|
||||
GeneratedFile,
|
||||
};
|
||||
|
||||
struct BuildDependency
|
||||
{
|
||||
BuildDependency(cmGeneratorTarget const* target, BuildDependencyType type,
|
||||
std::string file = std::string())
|
||||
: Target(target)
|
||||
, Type(type)
|
||||
, File(std::move(file))
|
||||
{
|
||||
}
|
||||
|
||||
cmGeneratorTarget const* Target;
|
||||
BuildDependencyType Type;
|
||||
std::string File; // only for GeneratedFile dependencies
|
||||
};
|
||||
|
||||
enum MessageLevel
|
||||
{
|
||||
MessageDefault,
|
||||
@@ -75,6 +100,19 @@ public:
|
||||
|
||||
virtual bool Compute(cmLocalGenerator*) { return true; }
|
||||
|
||||
virtual void GetInstallBuildDependencies(std::string const&,
|
||||
std::vector<BuildDependency>&) const
|
||||
{
|
||||
}
|
||||
|
||||
virtual void GetInstallBuildDependencyComponents(
|
||||
std::vector<std::string>& components) const
|
||||
{
|
||||
if (!this->Component.empty()) {
|
||||
components.push_back(this->Component);
|
||||
}
|
||||
}
|
||||
|
||||
std::string const& GetComponent() const { return this->Component; }
|
||||
|
||||
bool GetExcludeFromAll() const { return this->ExcludeFromAll; }
|
||||
@@ -110,6 +148,16 @@ protected:
|
||||
std::vector<std::string> const& files,
|
||||
TweakMethod const& tweak);
|
||||
|
||||
// Add dependencies for the files that the build produces among the given
|
||||
// files. A file linked by a target depends on building that target. Any
|
||||
// other generated file is attributed to the target owning the custom
|
||||
// command that produces it or, if no single target owns it, such as for a
|
||||
// byproduct, to the installing target, if any.
|
||||
static void AddGeneratedFileDependencies(
|
||||
cmGlobalGenerator* gg, std::string const& config,
|
||||
cmGeneratorTarget const* target, std::vector<std::string> const& files,
|
||||
std::vector<BuildDependency>& dependencies);
|
||||
|
||||
// Information shared by most generator types.
|
||||
std::string Destination;
|
||||
std::string const Component;
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
#include "cmScriptGenerator.h"
|
||||
#include "cmStringAlgorithms.h"
|
||||
|
||||
class cmGeneratorTarget;
|
||||
|
||||
namespace {
|
||||
template <typename T, typename F>
|
||||
void WriteMultiArgument(std::ostream& os, cm::string_view keyword,
|
||||
@@ -113,6 +115,29 @@ bool cmInstallGetRuntimeDependenciesGenerator::Compute(cmLocalGenerator* lg)
|
||||
return true;
|
||||
}
|
||||
|
||||
void cmInstallGetRuntimeDependenciesGenerator::GetInstallBuildDependencies(
|
||||
std::string const&, std::vector<BuildDependency>& dependencies) const
|
||||
{
|
||||
std::vector<cmGeneratorTarget const*> targets;
|
||||
this->RuntimeDependencySet->GetInstallBuildDependencies(targets);
|
||||
for (cmGeneratorTarget const* target : targets) {
|
||||
dependencies.push_back({ target, BuildDependencyType::Normal });
|
||||
}
|
||||
}
|
||||
|
||||
void cmInstallGetRuntimeDependenciesGenerator::
|
||||
GetInstallBuildDependencyComponents(
|
||||
std::vector<std::string>& components) const
|
||||
{
|
||||
if (!this->LibraryComponent.empty()) {
|
||||
components.push_back(this->LibraryComponent);
|
||||
}
|
||||
if (!this->FrameworkComponent.empty() &&
|
||||
this->FrameworkComponent != this->LibraryComponent) {
|
||||
components.push_back(this->FrameworkComponent);
|
||||
}
|
||||
}
|
||||
|
||||
void cmInstallGetRuntimeDependenciesGenerator::GenerateScript(std::ostream& os)
|
||||
{
|
||||
// Track indentation.
|
||||
|
||||
@@ -32,6 +32,13 @@ public:
|
||||
|
||||
bool Compute(cmLocalGenerator* lg) override;
|
||||
|
||||
void GetInstallBuildDependencies(
|
||||
std::string const& config,
|
||||
std::vector<BuildDependency>& dependencies) const override;
|
||||
|
||||
void GetInstallBuildDependencyComponents(
|
||||
std::vector<std::string>& components) const override;
|
||||
|
||||
protected:
|
||||
void GenerateScript(std::ostream& os) override;
|
||||
|
||||
|
||||
@@ -57,6 +57,12 @@ bool cmInstallImportedRuntimeArtifactsGenerator::Compute(cmLocalGenerator* lg)
|
||||
return true;
|
||||
}
|
||||
|
||||
void cmInstallImportedRuntimeArtifactsGenerator::GetInstallBuildDependencies(
|
||||
std::string const&, std::vector<BuildDependency>& dependencies) const
|
||||
{
|
||||
dependencies.push_back({ this->Target, BuildDependencyType::Normal });
|
||||
}
|
||||
|
||||
std::string cmInstallImportedRuntimeArtifactsGenerator::GetDestination(
|
||||
std::string const& config) const
|
||||
{
|
||||
|
||||
@@ -24,6 +24,10 @@ public:
|
||||
|
||||
bool Compute(cmLocalGenerator* lg) override;
|
||||
|
||||
void GetInstallBuildDependencies(
|
||||
std::string const& config,
|
||||
std::vector<BuildDependency>& dependencies) const override;
|
||||
|
||||
cmGeneratorTarget* GetTarget() const { return this->Target; }
|
||||
|
||||
bool GetOptional() const { return this->Optional; }
|
||||
|
||||
@@ -51,6 +51,28 @@ std::string cmInstallRuntimeDependencySet::TargetItem::GetItemPath(
|
||||
return this->Target->GetTarget()->GetFullPath(config);
|
||||
}
|
||||
|
||||
cmGeneratorTarget const*
|
||||
cmInstallRuntimeDependencySet::TargetItem::GetGeneratorTarget() const
|
||||
{
|
||||
return this->Target->GetTarget();
|
||||
}
|
||||
|
||||
void cmInstallRuntimeDependencySet::GetInstallBuildDependencies(
|
||||
std::vector<cmGeneratorTarget const*>& dependencies) const
|
||||
{
|
||||
auto appendTargets =
|
||||
[&dependencies](std::vector<std::unique_ptr<Item>> const& items) {
|
||||
for (auto const& item : items) {
|
||||
if (cmGeneratorTarget const* target = item->GetGeneratorTarget()) {
|
||||
dependencies.push_back(target);
|
||||
}
|
||||
}
|
||||
};
|
||||
appendTargets(this->Executables);
|
||||
appendTargets(this->Libraries);
|
||||
appendTargets(this->Modules);
|
||||
}
|
||||
|
||||
namespace {
|
||||
std::set<cmGeneratorTarget const*> const& GetTargetDependsClosure(
|
||||
std::map<cmGeneratorTarget const*, std::set<cmGeneratorTarget const*>>&
|
||||
@@ -93,3 +115,9 @@ std::string cmInstallRuntimeDependencySet::ImportedTargetItem::GetItemPath(
|
||||
{
|
||||
return this->Target->GetTarget()->GetFullPath(config);
|
||||
}
|
||||
|
||||
cmGeneratorTarget const*
|
||||
cmInstallRuntimeDependencySet::ImportedTargetItem::GetGeneratorTarget() const
|
||||
{
|
||||
return this->Target->GetTarget();
|
||||
}
|
||||
@@ -41,6 +41,11 @@ public:
|
||||
|
||||
virtual std::string GetItemPath(std::string const& config) const = 0;
|
||||
|
||||
virtual cmGeneratorTarget const* GetGeneratorTarget() const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual void AddPostExcludeFiles(
|
||||
std::string const& /*config*/, std::set<std::string>& /*files*/,
|
||||
cmInstallRuntimeDependencySet* /*set*/) const
|
||||
@@ -58,6 +63,8 @@ public:
|
||||
|
||||
std::string GetItemPath(std::string const& config) const override;
|
||||
|
||||
cmGeneratorTarget const* GetGeneratorTarget() const override;
|
||||
|
||||
void AddPostExcludeFiles(
|
||||
std::string const& config, std::set<std::string>& files,
|
||||
cmInstallRuntimeDependencySet* set) const override;
|
||||
@@ -76,6 +83,8 @@ public:
|
||||
|
||||
std::string GetItemPath(std::string const& config) const override;
|
||||
|
||||
cmGeneratorTarget const* GetGeneratorTarget() const override;
|
||||
|
||||
private:
|
||||
cmInstallImportedRuntimeArtifactsGenerator* Target;
|
||||
};
|
||||
@@ -145,6 +154,9 @@ public:
|
||||
|
||||
Item* GetBundleExecutable() const { return this->BundleExecutable; }
|
||||
|
||||
void GetInstallBuildDependencies(
|
||||
std::vector<cmGeneratorTarget const*>& dependencies) const;
|
||||
|
||||
bool Empty() const
|
||||
{
|
||||
return this->Executables.empty() && this->Libraries.empty() &&
|
||||
|
||||
@@ -558,6 +558,15 @@ bool cmInstallTargetGenerator::Compute(cmLocalGenerator* lg)
|
||||
return true;
|
||||
}
|
||||
|
||||
void cmInstallTargetGenerator::GetInstallBuildDependencies(
|
||||
std::string const& config, std::vector<BuildDependency>& dependencies) const
|
||||
{
|
||||
if (!this->GetFiles(config).From.empty()) {
|
||||
dependencies.push_back(
|
||||
{ this->Target, BuildDependencyType::InstallArtifact });
|
||||
}
|
||||
}
|
||||
|
||||
void cmInstallTargetGenerator::PreReplacementTweaks(std::ostream& os,
|
||||
Indent indent,
|
||||
std::string const& config,
|
||||
|
||||
@@ -62,6 +62,10 @@ public:
|
||||
|
||||
bool Compute(cmLocalGenerator* lg) override;
|
||||
|
||||
void GetInstallBuildDependencies(
|
||||
std::string const& config,
|
||||
std::vector<BuildDependency>& dependencies) const override;
|
||||
|
||||
cmGeneratorTarget* GetTarget() const { return this->Target; }
|
||||
|
||||
bool IsImportLibrary() const { return this->ImportLibrary; }
|
||||
|
||||
@@ -292,6 +292,9 @@ if(CMAKE_GENERATOR MATCHES "Ninja")
|
||||
-DRunCMake_GENERATOR_IS_MULTI_CONFIG=${_isMultiConfig})
|
||||
endif()
|
||||
add_RunCMake_test(InstallParallel)
|
||||
if(CMAKE_GENERATOR MATCHES "Ninja")
|
||||
add_RunCMake_test(InstallPrep)
|
||||
endif()
|
||||
add_RunCMake_test(CTest)
|
||||
add_RunCMake_test(CTestLaunch)
|
||||
|
||||
|
||||
@@ -176,6 +176,19 @@ function (run_cxx_module_test_rebuild directory)
|
||||
run_cxx_module_test("${directory}" ${ARGN})
|
||||
endfunction ()
|
||||
|
||||
function (run_cxx_module_install_prep_test kind)
|
||||
set(test "install-prep-${kind}")
|
||||
set(prefix "${RunCMake_BINARY_DIR}/${test}-install")
|
||||
file(REMOVE_RECURSE "${prefix}")
|
||||
set(RunCMake_CXXModules_INSTALL 0)
|
||||
run_cxx_module_test_target("${test}" "install_prep/${kind}"
|
||||
"${test}" "-DCMAKE_INSTALL_PREFIX=${prefix}")
|
||||
|
||||
set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/${test}-build")
|
||||
set(RunCMake_TEST_NO_CLEAN 1)
|
||||
run_cmake_command("${test}-install" "${CMAKE_COMMAND}" --install . --config Debug)
|
||||
endfunction ()
|
||||
|
||||
if (RunCMake_GENERATOR MATCHES "Ninja")
|
||||
if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
|
||||
set(ninja_cmp0154_target "CMakeFiles/ninja_cmp0154.dir/Debug/unrelated.cxx${CMAKE_CXX_OUTPUT_EXTENSION}")
|
||||
@@ -380,6 +393,17 @@ endif ()
|
||||
# All of the following tests perform installation.
|
||||
set(RunCMake_CXXModules_INSTALL 1)
|
||||
|
||||
if (RunCMake_GENERATOR MATCHES "Ninja" AND
|
||||
NOT CMake_TEST_MODULE_VARIANT MATCHES "^Build")
|
||||
if ("install_bmi" IN_LIST CMake_TEST_MODULE_COMPILATION)
|
||||
run_cxx_module_install_prep_test(BMI)
|
||||
endif ()
|
||||
if ("export_bmi" IN_LIST CMake_TEST_MODULE_COMPILATION)
|
||||
run_cxx_module_install_prep_test(Metadata)
|
||||
endif ()
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/install-prep.cmake")
|
||||
endif ()
|
||||
|
||||
# Tests which install BMIs
|
||||
if ("install_bmi" IN_LIST CMake_TEST_MODULE_COMPILATION)
|
||||
run_cxx_module_test(install-bmi)
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
set_property(TARGET "export_interfaces"
|
||||
PROPERTY IMPORTED_CXX_MODULES_DEBUG
|
||||
"importable=${_IMPORT_PREFIX}/lib/cxx/miu/importable.cxx"
|
||||
)
|
||||
@@ -0,0 +1,4 @@
|
||||
set_property(TARGET "export_interfaces"
|
||||
PROPERTY IMPORTED_CXX_MODULES_RELEASE
|
||||
"importable=${_IMPORT_PREFIX}/lib/cxx/miu/importable.cxx"
|
||||
)
|
||||
@@ -0,0 +1,12 @@
|
||||
set(bmi)
|
||||
foreach (ext IN ITEMS gcm ifc pcm)
|
||||
set(path "${prefix}/lib/cxx/bmi/importable.${ext}")
|
||||
if (EXISTS "${path}" AND NOT IS_DIRECTORY "${path}")
|
||||
set(bmi "${path}")
|
||||
break ()
|
||||
endif ()
|
||||
endforeach ()
|
||||
|
||||
if (NOT bmi)
|
||||
list(APPEND RunCMake_TEST_FAILED "The prepared BMI was not installed.")
|
||||
endif ()
|
||||
@@ -0,0 +1,40 @@
|
||||
cmake_minimum_required(VERSION 4.4)
|
||||
project(cxx_modules_install_prep_bmi CXX)
|
||||
|
||||
include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
|
||||
|
||||
add_library(install_bmi STATIC)
|
||||
target_sources(install_bmi
|
||||
PUBLIC
|
||||
FILE_SET CXX_MODULES
|
||||
BASE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
FILES importable.cxx)
|
||||
target_compile_features(install_bmi PUBLIC cxx_std_20)
|
||||
|
||||
set(install_targets install_bmi)
|
||||
set(archive_destination "lib")
|
||||
if (prep_test)
|
||||
set_property(TARGET install_bmi PROPERTY EXCLUDE_FROM_ALL 1)
|
||||
add_library(no_modules STATIC ../install-prep-never-build.cxx)
|
||||
add_library(unrelated STATIC ../install-prep-never-build.cxx)
|
||||
|
||||
# Private module file sets have no installable BMIs.
|
||||
add_library(private_module STATIC EXCLUDE_FROM_ALL)
|
||||
target_sources(private_module PRIVATE FILE_SET CXX_MODULES FILES private.cxx)
|
||||
target_compile_features(private_module PRIVATE cxx_std_20)
|
||||
|
||||
list(APPEND install_targets no_modules private_module)
|
||||
set(archive_destination "artifacts")
|
||||
set(archive_options COMPONENT Artifacts EXCLUDE_FROM_ALL)
|
||||
set(source_options FILE_SET CXX_MODULES DESTINATION "sources"
|
||||
COMPONENT Sources EXCLUDE_FROM_ALL)
|
||||
endif ()
|
||||
|
||||
set(bmi_destination "lib/cxx/bmi")
|
||||
if (prep_empty_destination)
|
||||
set(bmi_destination "$<0:lib/cxx/bmi>")
|
||||
endif ()
|
||||
install(TARGETS ${install_targets}
|
||||
ARCHIVE DESTINATION "${archive_destination}" ${archive_options}
|
||||
${source_options}
|
||||
CXX_MODULES_BMI DESTINATION "${bmi_destination}" COMPONENT BMI ${prep_rule_options})
|
||||
@@ -0,0 +1,6 @@
|
||||
export module importable;
|
||||
|
||||
export int from_import()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export module private_module;
|
||||
|
||||
static_assert(false,
|
||||
"install_prep must not build an uninstalled private module");
|
||||
@@ -0,0 +1,14 @@
|
||||
set(metadata "${prefix}/lib/cmake/export_interfaces/cxx-modules/target-export__interfaces-Debug.cmake")
|
||||
if (NOT EXISTS "${metadata}")
|
||||
list(APPEND RunCMake_TEST_FAILED "The prepared module export metadata was not installed.")
|
||||
return ()
|
||||
endif ()
|
||||
|
||||
execute_process(
|
||||
COMMAND "${CMAKE_COMMAND}" -E compare_files --ignore-eol
|
||||
"${CMAKE_CURRENT_LIST_DIR}/expect/install-prep-export-interfaces-Debug.cmake"
|
||||
"${metadata}"
|
||||
RESULT_VARIABLE result)
|
||||
if (NOT result EQUAL 0)
|
||||
list(APPEND RunCMake_TEST_FAILED "Installed module export metadata does not match the expected file.")
|
||||
endif ()
|
||||
@@ -0,0 +1,36 @@
|
||||
cmake_minimum_required(VERSION 4.4)
|
||||
project(cxx_modules_install_prep_metadata CXX)
|
||||
|
||||
include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
|
||||
|
||||
add_library(export_interfaces STATIC)
|
||||
target_sources(export_interfaces PUBLIC FILE_SET CXX_MODULES FILES importable.cxx)
|
||||
target_compile_features(export_interfaces PUBLIC cxx_std_20)
|
||||
|
||||
set(install_targets export_interfaces)
|
||||
set(archive_destination "lib")
|
||||
if (prep_test)
|
||||
set_property(TARGET export_interfaces PROPERTY EXCLUDE_FROM_ALL 1)
|
||||
# Exporting a target without modules must not build it for module metadata.
|
||||
add_library(no_modules STATIC ../install-prep-never-build.cxx)
|
||||
add_library(unrelated STATIC ../install-prep-never-build.cxx)
|
||||
list(APPEND install_targets no_modules)
|
||||
set(archive_destination "artifacts")
|
||||
set(archive_options COMPONENT Artifacts EXCLUDE_FROM_ALL)
|
||||
set(source_options COMPONENT Sources EXCLUDE_FROM_ALL)
|
||||
endif ()
|
||||
|
||||
install(TARGETS ${install_targets}
|
||||
EXPORT CXXModules
|
||||
ARCHIVE DESTINATION "${archive_destination}" ${archive_options}
|
||||
FILE_SET CXX_MODULES DESTINATION "lib/cxx/miu" ${source_options})
|
||||
|
||||
set(module_options CXX_MODULES_DIRECTORY "cxx-modules")
|
||||
if (prep_no_module_directory)
|
||||
set(module_options)
|
||||
endif ()
|
||||
install(EXPORT CXXModules
|
||||
DESTINATION "lib/cmake/export_interfaces"
|
||||
COMPONENT Metadata
|
||||
${module_options}
|
||||
${prep_rule_options})
|
||||
@@ -0,0 +1,6 @@
|
||||
export module importable;
|
||||
|
||||
export int from_import()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
if (EXISTS "${prefix}")
|
||||
list(APPEND RunCMake_TEST_FAILED "Preparation ran installation.")
|
||||
return ()
|
||||
endif ()
|
||||
|
||||
if (kind STREQUAL "GeneratedSource" AND
|
||||
NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/generated.cxx")
|
||||
list(APPEND RunCMake_TEST_FAILED "Preparation did not generate the module source.")
|
||||
return ()
|
||||
endif ()
|
||||
|
||||
if (expect_build)
|
||||
set(bmi_dir "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/${module_target}.dir")
|
||||
if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
|
||||
string(APPEND bmi_dir "/${config}")
|
||||
endif ()
|
||||
set(bmi)
|
||||
foreach (ext IN ITEMS gcm ifc pcm)
|
||||
set(path "${bmi_dir}/importable.${ext}")
|
||||
if (EXISTS "${path}" AND NOT IS_DIRECTORY "${path}")
|
||||
set(bmi "${path}")
|
||||
break ()
|
||||
endif ()
|
||||
endforeach ()
|
||||
if (NOT bmi)
|
||||
list(APPEND RunCMake_TEST_FAILED "Preparation did not build the module BMI.")
|
||||
return ()
|
||||
endif ()
|
||||
if (kind STREQUAL "BMI")
|
||||
set(script "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/${module_target}.dir/install-cxx-module-bmi-${config}.cmake")
|
||||
if (NOT EXISTS "${script}")
|
||||
list(APPEND RunCMake_TEST_FAILED "Preparation did not generate the BMI install script.")
|
||||
endif ()
|
||||
else ()
|
||||
file(GLOB metadata
|
||||
"${RunCMake_TEST_BINARY_DIR}/CMakeFiles/Export/*/cxx-modules/target-export__interfaces-${config}.cmake")
|
||||
if (NOT metadata)
|
||||
list(APPEND RunCMake_TEST_FAILED "Preparation did not generate module export metadata.")
|
||||
endif ()
|
||||
endif ()
|
||||
else ()
|
||||
file(GLOB_RECURSE bmis LIST_DIRECTORIES FALSE
|
||||
"${RunCMake_TEST_BINARY_DIR}/*.gcm"
|
||||
"${RunCMake_TEST_BINARY_DIR}/*.ifc"
|
||||
"${RunCMake_TEST_BINARY_DIR}/*.pcm")
|
||||
if (bmis)
|
||||
list(APPEND RunCMake_TEST_FAILED "Preparation built unneeded BMIs: ${bmis}")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
string(REPLACE ";" "\n " RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}")
|
||||
@@ -0,0 +1,50 @@
|
||||
if (EXISTS "${prefix}/artifacts")
|
||||
list(APPEND RunCMake_TEST_FAILED "Installation included an excluded archive.")
|
||||
endif ()
|
||||
|
||||
if (kind STREQUAL "GeneratedSource")
|
||||
execute_process(
|
||||
COMMAND "${CMAKE_COMMAND}" -E compare_files --ignore-eol
|
||||
"${RunCMake_TEST_SOURCE_DIR}/importable.cxx"
|
||||
"${prefix}/sources/generated.cxx"
|
||||
RESULT_VARIABLE result)
|
||||
if (NOT result EQUAL 0)
|
||||
list(APPEND RunCMake_TEST_FAILED "The installed generated module source does not match the input.")
|
||||
endif ()
|
||||
string(REPLACE ";" "\n " RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}")
|
||||
return ()
|
||||
endif ()
|
||||
|
||||
if (kind STREQUAL "BMI")
|
||||
set(bmi)
|
||||
foreach (ext IN ITEMS gcm ifc pcm)
|
||||
set(path "${prefix}/lib/cxx/bmi/importable.${ext}")
|
||||
if (EXISTS "${path}" AND NOT IS_DIRECTORY "${path}")
|
||||
set(bmi "${path}")
|
||||
break ()
|
||||
endif ()
|
||||
endforeach ()
|
||||
if (NOT bmi)
|
||||
list(APPEND RunCMake_TEST_FAILED "The prepared BMI was not installed.")
|
||||
endif ()
|
||||
else ()
|
||||
set(metadata "${prefix}/lib/cmake/export_interfaces/cxx-modules/target-export__interfaces-${config}.cmake")
|
||||
if (NOT EXISTS "${metadata}")
|
||||
list(APPEND RunCMake_TEST_FAILED "The prepared module export metadata was not installed.")
|
||||
return ()
|
||||
endif ()
|
||||
execute_process(
|
||||
COMMAND "${CMAKE_COMMAND}" -E compare_files --ignore-eol
|
||||
"${CMAKE_CURRENT_LIST_DIR}/expect/install-prep-export-interfaces-${config}.cmake"
|
||||
"${metadata}"
|
||||
RESULT_VARIABLE result)
|
||||
if (NOT result EQUAL 0)
|
||||
list(APPEND RunCMake_TEST_FAILED "Installed module export metadata does not match the expected file.")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (EXISTS "${prefix}/${source_destination}")
|
||||
list(APPEND RunCMake_TEST_FAILED "Installation included an excluded source file set.")
|
||||
endif ()
|
||||
|
||||
string(REPLACE ";" "\n " RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}")
|
||||
@@ -0,0 +1 @@
|
||||
#error "install_prep must not build this target"
|
||||
@@ -0,0 +1,90 @@
|
||||
function (run_cxx_module_install_prep kind case component config expect_build)
|
||||
cmake_parse_arguments(PARSE_ARGV 5 prep
|
||||
"EXCLUDE_FROM_ALL;EMPTY_DESTINATION;NO_MODULE_DIRECTORY" "CONFIGURATIONS" "")
|
||||
set(test "install-prep-${kind}-${case}")
|
||||
if (kind STREQUAL "GeneratedSource")
|
||||
set(directory install-prep)
|
||||
set(source_destination sources)
|
||||
elseif (kind STREQUAL "BMI")
|
||||
set(directory install-prep-BMI)
|
||||
set(module_target install_bmi)
|
||||
set(source_destination sources)
|
||||
else ()
|
||||
set(directory install-prep-Metadata)
|
||||
set(module_target export_interfaces)
|
||||
set(source_destination lib/cxx/miu)
|
||||
endif ()
|
||||
set(RunCMake_TEST_SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/${directory}")
|
||||
set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/${test}-build")
|
||||
set(prefix "${RunCMake_BINARY_DIR}/${test}-install")
|
||||
file(REMOVE_RECURSE "${prefix}")
|
||||
|
||||
set(rule_options)
|
||||
if (prep_EXCLUDE_FROM_ALL)
|
||||
list(APPEND rule_options EXCLUDE_FROM_ALL)
|
||||
endif ()
|
||||
if (prep_CONFIGURATIONS)
|
||||
list(APPEND rule_options CONFIGURATIONS "${prep_CONFIGURATIONS}")
|
||||
endif ()
|
||||
string(REPLACE ";" "\\;" rule_options "${rule_options}")
|
||||
set(RunCMake_TEST_OPTIONS
|
||||
"-DCMAKE_INSTALL_PREFIX=${prefix}"
|
||||
"-Dprep_test=ON"
|
||||
"-Dprep_rule_options=${rule_options}"
|
||||
"-Dprep_empty_destination=${prep_EMPTY_DESTINATION}"
|
||||
"-Dprep_no_module_directory=${prep_NO_MODULE_DIRECTORY}"
|
||||
"-DCMake_TEST_MODULE_COMPILATION_RULES=${CMake_TEST_MODULE_COMPILATION_RULES}"
|
||||
)
|
||||
if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
|
||||
list(APPEND RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=${config}")
|
||||
else ()
|
||||
list(APPEND RunCMake_TEST_OPTIONS "-DCMAKE_BUILD_TYPE=${config}")
|
||||
endif ()
|
||||
run_cmake("${test}")
|
||||
|
||||
set(RunCMake_TEST_NO_CLEAN 1)
|
||||
set(RunCMake-check-file "install-prep-build-check.cmake")
|
||||
run_cmake_command("${test}-build" "${CMAKE_COMMAND}"
|
||||
--build . --config "${config}" --target "install_prep/${component}")
|
||||
unset(RunCMake-check-file)
|
||||
|
||||
# Component-specific BMI installation has separate limitations. Check the
|
||||
# prepared BMI above; exercise installation with the full-install case.
|
||||
if ((expect_build AND (kind STREQUAL "Metadata" OR component STREQUAL "all"))
|
||||
OR kind STREQUAL "GeneratedSource")
|
||||
set(install_args)
|
||||
if (NOT component STREQUAL "all")
|
||||
list(APPEND install_args --component "${component}")
|
||||
endif ()
|
||||
set(RunCMake-check-file "install-prep-install-check.cmake")
|
||||
run_cmake_command("${test}-install" "${CMAKE_COMMAND}"
|
||||
--install . --config "${config}" ${install_args})
|
||||
endif ()
|
||||
endfunction ()
|
||||
|
||||
# Preparing a generated module source must not compile it to a BMI.
|
||||
if ("named" IN_LIST CMake_TEST_MODULE_COMPILATION)
|
||||
run_cxx_module_install_prep(GeneratedSource sources Sources Debug 0)
|
||||
endif ()
|
||||
|
||||
if ("install_bmi" IN_LIST CMake_TEST_MODULE_COMPILATION)
|
||||
run_cxx_module_install_prep(BMI all all Debug 1)
|
||||
run_cxx_module_install_prep(BMI component BMI Debug 1)
|
||||
run_cxx_module_install_prep(BMI excluded-all all Debug 0 EXCLUDE_FROM_ALL)
|
||||
run_cxx_module_install_prep(BMI excluded-component BMI Debug 1 EXCLUDE_FROM_ALL)
|
||||
run_cxx_module_install_prep(BMI config-inactive BMI Debug 0 CONFIGURATIONS Release)
|
||||
run_cxx_module_install_prep(BMI config-active BMI Release 1 CONFIGURATIONS Release)
|
||||
run_cxx_module_install_prep(BMI sources Sources Debug 0)
|
||||
run_cxx_module_install_prep(BMI empty-destination BMI Debug 0 EMPTY_DESTINATION)
|
||||
endif ()
|
||||
|
||||
if ("export_bmi" IN_LIST CMake_TEST_MODULE_COMPILATION)
|
||||
run_cxx_module_install_prep(Metadata all all Debug 1)
|
||||
run_cxx_module_install_prep(Metadata component Metadata Debug 1)
|
||||
run_cxx_module_install_prep(Metadata excluded-all all Debug 0 EXCLUDE_FROM_ALL)
|
||||
run_cxx_module_install_prep(Metadata excluded-component Metadata Debug 1 EXCLUDE_FROM_ALL)
|
||||
run_cxx_module_install_prep(Metadata config-inactive Metadata Debug 0 CONFIGURATIONS Release)
|
||||
run_cxx_module_install_prep(Metadata config-active Metadata Release 1 CONFIGURATIONS Release)
|
||||
run_cxx_module_install_prep(Metadata sources Sources Debug 0)
|
||||
run_cxx_module_install_prep(Metadata no-module-directory Metadata Debug 0 NO_MODULE_DIRECTORY)
|
||||
endif ()
|
||||
@@ -0,0 +1,26 @@
|
||||
cmake_minimum_required(VERSION 4.4)
|
||||
project(cxx_modules_install_prep_sources CXX)
|
||||
|
||||
include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/generated.cxx"
|
||||
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/importable.cxx"
|
||||
COMMAND "${CMAKE_COMMAND}"
|
||||
-E copy
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/importable.cxx"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/generated.cxx")
|
||||
|
||||
add_library(generated_module STATIC EXCLUDE_FROM_ALL)
|
||||
target_sources(generated_module
|
||||
PUBLIC
|
||||
FILE_SET CXX_MODULES
|
||||
BASE_DIRS
|
||||
"${CMAKE_CURRENT_BINARY_DIR}"
|
||||
FILES
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/generated.cxx")
|
||||
target_compile_features(generated_module PUBLIC cxx_std_20)
|
||||
|
||||
install(TARGETS generated_module
|
||||
ARCHIVE DESTINATION "artifacts" COMPONENT Artifacts EXCLUDE_FROM_ALL
|
||||
FILE_SET CXX_MODULES DESTINATION "sources" COMPONENT Sources)
|
||||
@@ -0,0 +1,6 @@
|
||||
export module importable;
|
||||
|
||||
export int from_import()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
set(_check_files
|
||||
[[bin]]
|
||||
[[bin/imported-tool(\.exe)?]]
|
||||
[[bin/runtime(\.exe)?]]
|
||||
[[lib]]
|
||||
[[lib/(lib)?default_component\.(a|lib|l)]]
|
||||
[[lib/(lib)?development\.(a|lib|l)]]
|
||||
[[share]]
|
||||
[[share/install-prep]]
|
||||
[[share/install-prep/lib\.c]])
|
||||
check_installed("^${_check_files}$")
|
||||
|
||||
foreach(program IN ITEMS runtime imported-tool)
|
||||
execute_process(COMMAND "${CMAKE_INSTALL_PREFIX}/bin/${program}${CMAKE_HOST_EXECUTABLE_SUFFIX}"
|
||||
RESULT_VARIABLE result)
|
||||
if(NOT result EQUAL 0)
|
||||
set(RunCMake_TEST_FAILED "Installed ${program} failed: ${result}")
|
||||
endif()
|
||||
endforeach()
|
||||
@@ -0,0 +1,65 @@
|
||||
enable_language(C)
|
||||
|
||||
set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME DefaultComponent)
|
||||
|
||||
add_library(runtime_helper STATIC lib.c)
|
||||
add_executable(runtime EXCLUDE_FROM_ALL runtime.c)
|
||||
target_link_libraries(runtime PRIVATE runtime_helper)
|
||||
install(TARGETS runtime
|
||||
RUNTIME DESTINATION bin
|
||||
COMPONENT Runtime
|
||||
)
|
||||
|
||||
add_library(default_component STATIC lib.c)
|
||||
install(TARGETS default_component
|
||||
ARCHIVE DESTINATION lib
|
||||
)
|
||||
|
||||
add_library(hidden STATIC neverbuild.c)
|
||||
install(TARGETS hidden
|
||||
ARCHIVE DESTINATION lib
|
||||
COMPONENT Hidden
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
||||
|
||||
add_executable(imported_producer EXCLUDE_FROM_ALL runtime_main.c)
|
||||
set_target_properties(imported_producer PROPERTIES
|
||||
OUTPUT_NAME imported-tool
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
|
||||
RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}"
|
||||
)
|
||||
|
||||
set(imported_location "${CMAKE_BINARY_DIR}/imported-tool${CMAKE_EXECUTABLE_SUFFIX}")
|
||||
add_executable(imported_tool IMPORTED)
|
||||
set_target_properties(imported_tool PROPERTIES
|
||||
IMPORTED_LOCATION "${imported_location}"
|
||||
)
|
||||
add_dependencies(imported_tool imported_producer)
|
||||
|
||||
install(IMPORTED_RUNTIME_ARTIFACTS imported_tool
|
||||
RUNTIME DESTINATION bin
|
||||
COMPONENT Imported
|
||||
)
|
||||
|
||||
install(FILES lib.c
|
||||
DESTINATION share/install-prep
|
||||
COMPONENT Documentation
|
||||
)
|
||||
|
||||
install(FILES lib.c
|
||||
DESTINATION share/install-prep
|
||||
COMPONENT "Unsafe/../Runtime"
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
||||
|
||||
string(ASCII 9 component_tab)
|
||||
install(FILES lib.c
|
||||
DESTINATION share/install-prep
|
||||
COMPONENT "Unsafe${component_tab}Component"
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
||||
|
||||
add_library(unit_tests STATIC neverbuild.c)
|
||||
|
||||
add_subdirectory(subdir)
|
||||
add_subdirectory(excluded EXCLUDE_FROM_ALL)
|
||||
@@ -0,0 +1,3 @@
|
||||
cmake_minimum_required(VERSION 4.4)
|
||||
project(${RunCMake_TEST} NONE)
|
||||
include(${RunCMake_TEST}.cmake)
|
||||
@@ -0,0 +1 @@
|
||||
check_prepared(all_component_included)
|
||||
@@ -0,0 +1 @@
|
||||
[^0]
|
||||
@@ -0,0 +1 @@
|
||||
[^0]
|
||||
@@ -0,0 +1 @@
|
||||
[^0]
|
||||
@@ -0,0 +1,36 @@
|
||||
^CMake Warning \(author\) at ComponentNames\.cmake:[0-9]+ \(install\):
|
||||
The install component "Unsafe/\.\./Name" has build dependencies, but its name
|
||||
cannot be used in a build target name with this generator\. No
|
||||
"install_prep/" target will be generated for it\. Rename the component to
|
||||
build its dependencies with an "install_prep/" target\.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists\.txt:[0-9]+ \(include\)
|
||||
This warning is for project developers\. Use -Wno-author to suppress it\.
|
||||
+
|
||||
CMake Warning \(author\) at ComponentNames\.cmake:[0-9]+ \(install\):
|
||||
The install component "Empty//Segment" has build dependencies, but its name
|
||||
cannot be used in a build target name with this generator\. No
|
||||
"install_prep/" target will be generated for it\. Rename the component to
|
||||
build its dependencies with an "install_prep/" target\.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists\.txt:[0-9]+ \(include\)
|
||||
This warning is for project developers\. Use -Wno-author to suppress it\.
|
||||
+
|
||||
CMake Warning \(author\) at ComponentNames\.cmake:[0-9]+ \(install\):
|
||||
The install component "\./Dot" has build dependencies, but its name cannot
|
||||
be used in a build target name with this generator\. No "install_prep/"
|
||||
target will be generated for it\. Rename the component to build its
|
||||
dependencies with an "install_prep/" target\.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists\.txt:[0-9]+ \(include\)
|
||||
This warning is for project developers\. Use -Wno-author to suppress it\.
|
||||
+
|
||||
CMake Warning \(author\) at ComponentNames\.cmake:[0-9]+ \(install\):
|
||||
An install rule in the component named "all" uses EXCLUDE_FROM_ALL and has
|
||||
build dependencies, but no install_prep/ target builds them:
|
||||
install_prep/all omits EXCLUDE_FROM_ALL rules, and the "all" component has
|
||||
no preparation target of its own\. Rename the component or remove
|
||||
EXCLUDE_FROM_ALL\.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists\.txt:[0-9]+ \(include\)
|
||||
This warning is for project developers\. Use -Wno-author to suppress it\.$
|
||||
@@ -0,0 +1,37 @@
|
||||
enable_language(C)
|
||||
|
||||
add_library(colon_dependency STATIC EXCLUDE_FROM_ALL lib.c)
|
||||
install(TARGETS colon_dependency
|
||||
ARCHIVE DESTINATION lib
|
||||
COMPONENT "Colon:Name"
|
||||
)
|
||||
|
||||
# Components whose names are not representable get no preparation target,
|
||||
# which is diagnosed when they have build dependencies.
|
||||
add_library(unsafe_dependency STATIC EXCLUDE_FROM_ALL lib.c)
|
||||
foreach(component IN ITEMS "Unsafe/../Name" "Empty//Segment" "./Dot")
|
||||
install(TARGETS unsafe_dependency
|
||||
ARCHIVE DESTINATION lib
|
||||
COMPONENT "${component}"
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
||||
endforeach()
|
||||
|
||||
# Rules in a component named "all" contribute to install_prep/all only when
|
||||
# they are part of a full installation.
|
||||
add_library(all_component_included STATIC EXCLUDE_FROM_ALL lib.c)
|
||||
install(TARGETS all_component_included
|
||||
ARCHIVE DESTINATION lib
|
||||
COMPONENT all
|
||||
)
|
||||
|
||||
# An excluded rule in a component named "all" is prepared by nothing, which
|
||||
# is diagnosed.
|
||||
add_library(all_component_excluded STATIC EXCLUDE_FROM_ALL neverbuild.c)
|
||||
install(TARGETS all_component_excluded
|
||||
ARCHIVE DESTINATION lib
|
||||
COMPONENT all
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
||||
|
||||
add_library(unit_tests STATIC neverbuild.c)
|
||||
@@ -0,0 +1 @@
|
||||
check_installed([[^lib;lib/(lib)?debug_only\.(a|lib|l)$]])
|
||||
@@ -0,0 +1,17 @@
|
||||
enable_language(C)
|
||||
|
||||
add_library(debug_only STATIC EXCLUDE_FROM_ALL lib.c)
|
||||
install(TARGETS debug_only
|
||||
ARCHIVE DESTINATION lib
|
||||
COMPONENT Configured
|
||||
CONFIGURATIONS Debug
|
||||
)
|
||||
|
||||
add_library(release_only STATIC EXCLUDE_FROM_ALL neverbuild.c)
|
||||
install(TARGETS release_only
|
||||
ARCHIVE DESTINATION lib
|
||||
COMPONENT Configured
|
||||
CONFIGURATIONS Release
|
||||
)
|
||||
|
||||
add_library(unit_tests STATIC neverbuild.c)
|
||||
@@ -0,0 +1,2 @@
|
||||
check_prepared(debug_only)
|
||||
check_not_prepared(release_only)
|
||||
@@ -0,0 +1 @@
|
||||
check_prepared(release_only)
|
||||
@@ -0,0 +1,17 @@
|
||||
enable_language(C)
|
||||
|
||||
add_library(debug_only STATIC EXCLUDE_FROM_ALL lib.c)
|
||||
install(TARGETS debug_only
|
||||
ARCHIVE DESTINATION lib
|
||||
COMPONENT Configured
|
||||
CONFIGURATIONS Debug
|
||||
)
|
||||
|
||||
add_library(release_only STATIC EXCLUDE_FROM_ALL lib.c)
|
||||
install(TARGETS release_only
|
||||
ARCHIVE DESTINATION lib
|
||||
COMPONENT Configured
|
||||
CONFIGURATIONS Release
|
||||
)
|
||||
|
||||
add_library(unit_tests STATIC neverbuild.c)
|
||||
@@ -0,0 +1 @@
|
||||
check_installed([[^lib;lib/(lib)?release_only\.(a|lib|l)$]])
|
||||
@@ -0,0 +1,17 @@
|
||||
enable_language(C)
|
||||
|
||||
add_library(debug_only STATIC EXCLUDE_FROM_ALL neverbuild.c)
|
||||
install(TARGETS debug_only
|
||||
ARCHIVE DESTINATION lib
|
||||
COMPONENT Configured
|
||||
CONFIGURATIONS Debug
|
||||
)
|
||||
|
||||
add_library(release_only STATIC EXCLUDE_FROM_ALL lib.c)
|
||||
install(TARGETS release_only
|
||||
ARCHIVE DESTINATION lib
|
||||
COMPONENT Configured
|
||||
CONFIGURATIONS Release
|
||||
)
|
||||
|
||||
add_library(unit_tests STATIC neverbuild.c)
|
||||
@@ -0,0 +1 @@
|
||||
check_installed([[^lib;lib/(lib)?default_component\.(a|lib|l)$]])
|
||||
@@ -0,0 +1,16 @@
|
||||
enable_language(C)
|
||||
|
||||
set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME DefaultComponent)
|
||||
|
||||
add_library(default_component STATIC lib.c)
|
||||
install(TARGETS default_component
|
||||
ARCHIVE DESTINATION lib
|
||||
)
|
||||
|
||||
add_library(other_component STATIC neverbuild.c)
|
||||
install(TARGETS other_component
|
||||
ARCHIVE DESTINATION lib
|
||||
COMPONENT Other
|
||||
)
|
||||
|
||||
add_library(unit_tests STATIC neverbuild.c)
|
||||
@@ -0,0 +1 @@
|
||||
check_installed([[^lib;lib/(lib)?development\.(a|lib|l)$]])
|
||||
@@ -0,0 +1,4 @@
|
||||
enable_language(C)
|
||||
|
||||
add_subdirectory(subdir)
|
||||
add_library(unit_tests STATIC neverbuild.c)
|
||||
@@ -0,0 +1 @@
|
||||
check_installed([[^share;share/install-prep;share/install-prep/lib\.c$]])
|
||||
@@ -0,0 +1,8 @@
|
||||
enable_language(C)
|
||||
|
||||
install(FILES lib.c
|
||||
DESTINATION share/install-prep
|
||||
COMPONENT Documentation
|
||||
)
|
||||
|
||||
add_library(unit_tests STATIC neverbuild.c)
|
||||
@@ -0,0 +1 @@
|
||||
check_installed([[^$]])
|
||||
@@ -0,0 +1,4 @@
|
||||
enable_language(C)
|
||||
|
||||
add_subdirectory(excluded EXCLUDE_FROM_ALL)
|
||||
add_library(unit_tests STATIC neverbuild.c)
|
||||
@@ -0,0 +1,33 @@
|
||||
enable_language(C)
|
||||
|
||||
# A generated header that is not the output of a custom command attached to
|
||||
# a single target is prepared by depending on the file itself, which runs its
|
||||
# producer. Generators that cannot do so instead build the installing target,
|
||||
# which builds the producer through its dependencies, so its sources must
|
||||
# compile there.
|
||||
if(CMAKE_GENERATOR MATCHES "Ninja")
|
||||
set(generated_target_source neverbuild.c)
|
||||
else()
|
||||
set(generated_target_source lib.c)
|
||||
endif()
|
||||
|
||||
set(generated_header "${CMAKE_CURRENT_BINARY_DIR}/generated.h")
|
||||
add_custom_target(produce_header
|
||||
COMMAND ${CMAKE_COMMAND} -E touch "${generated_header}"
|
||||
BYPRODUCTS "${generated_header}"
|
||||
)
|
||||
|
||||
add_library(generated_headers STATIC EXCLUDE_FROM_ALL
|
||||
${generated_target_source})
|
||||
add_dependencies(generated_headers produce_header)
|
||||
set_property(TARGET generated_headers
|
||||
PROPERTY PUBLIC_HEADER "${generated_header}")
|
||||
install(TARGETS generated_headers
|
||||
ARCHIVE DESTINATION lib
|
||||
COMPONENT Archive
|
||||
EXCLUDE_FROM_ALL
|
||||
PUBLIC_HEADER DESTINATION include
|
||||
COMPONENT Headers
|
||||
)
|
||||
|
||||
add_library(unit_tests STATIC neverbuild.c)
|
||||
@@ -0,0 +1,22 @@
|
||||
enable_language(C)
|
||||
|
||||
# A generated header produced by a custom command attached to another target
|
||||
# is prepared by running that command, without building the installing target.
|
||||
set(generated_header "${CMAKE_CURRENT_BINARY_DIR}/generated.h")
|
||||
add_custom_command(OUTPUT "${generated_header}"
|
||||
COMMAND ${CMAKE_COMMAND} -E touch "${generated_header}"
|
||||
)
|
||||
add_custom_target(produce_header DEPENDS "${generated_header}")
|
||||
|
||||
add_library(generated_headers STATIC EXCLUDE_FROM_ALL neverbuild.c)
|
||||
set_property(TARGET generated_headers
|
||||
PROPERTY PUBLIC_HEADER "${generated_header}")
|
||||
install(TARGETS generated_headers
|
||||
ARCHIVE DESTINATION lib
|
||||
COMPONENT Archive
|
||||
EXCLUDE_FROM_ALL
|
||||
PUBLIC_HEADER DESTINATION include
|
||||
COMPONENT Headers
|
||||
)
|
||||
|
||||
add_library(unit_tests STATIC neverbuild.c)
|
||||
@@ -0,0 +1,15 @@
|
||||
enable_language(C)
|
||||
|
||||
# Generators that can depend on individual files prepare a generated file by
|
||||
# running only the custom command that produces it.
|
||||
set(generated_target_source "${CMAKE_CURRENT_LIST_DIR}/neverbuild.c")
|
||||
|
||||
# Add a custom command that generates the named file in the current binary
|
||||
# directory and store its full path in the given variable.
|
||||
function(add_generated_file var name)
|
||||
set(file "${CMAKE_CURRENT_BINARY_DIR}/${name}")
|
||||
add_custom_command(OUTPUT "${file}"
|
||||
COMMAND ${CMAKE_COMMAND} -E touch "${file}"
|
||||
)
|
||||
set(${var} "${file}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
@@ -0,0 +1,33 @@
|
||||
include(GeneratedCommon.cmake)
|
||||
|
||||
add_generated_file(generated_header generated.h)
|
||||
add_library(generated_headers STATIC EXCLUDE_FROM_ALL
|
||||
"${generated_target_source}")
|
||||
target_sources(generated_headers PUBLIC
|
||||
FILE_SET HEADERS
|
||||
BASE_DIRS "${CMAKE_CURRENT_BINARY_DIR}"
|
||||
FILES "${generated_header}"
|
||||
)
|
||||
install(TARGETS generated_headers
|
||||
ARCHIVE DESTINATION lib
|
||||
COMPONENT Archive
|
||||
EXCLUDE_FROM_ALL
|
||||
FILE_SET HEADERS DESTINATION include
|
||||
COMPONENT Headers
|
||||
)
|
||||
|
||||
# A file set without generated files does not need its target built.
|
||||
add_library(plain_headers STATIC EXCLUDE_FROM_ALL neverbuild.c)
|
||||
target_sources(plain_headers PUBLIC
|
||||
FILE_SET HEADERS
|
||||
FILES plain.h
|
||||
)
|
||||
install(TARGETS plain_headers
|
||||
ARCHIVE DESTINATION lib
|
||||
COMPONENT Archive
|
||||
EXCLUDE_FROM_ALL
|
||||
FILE_SET HEADERS DESTINATION include
|
||||
COMPONENT Headers
|
||||
)
|
||||
|
||||
add_library(unit_tests STATIC neverbuild.c)
|
||||
@@ -0,0 +1,19 @@
|
||||
include(GeneratedCommon.cmake)
|
||||
|
||||
# install(FILES) and install(PROGRAMS) imply build dependencies only for files
|
||||
# that the build generates. A file produced by a custom command attached to
|
||||
# a single target is prepared by running only that command.
|
||||
add_generated_file(generated_file generated.txt)
|
||||
add_generated_file(generated_program generated.sh)
|
||||
add_library(generated_files STATIC EXCLUDE_FROM_ALL
|
||||
"${generated_target_source}" "${generated_file}" "${generated_program}")
|
||||
install(FILES "${generated_file}" lib.c
|
||||
DESTINATION share/install-prep
|
||||
COMPONENT Files
|
||||
)
|
||||
install(PROGRAMS "${generated_program}"
|
||||
DESTINATION bin
|
||||
COMPONENT Files
|
||||
)
|
||||
|
||||
add_library(unit_tests STATIC neverbuild.c)
|
||||
@@ -0,0 +1,16 @@
|
||||
enable_language(C)
|
||||
|
||||
# A generated file installed by install(FILES) that is not the unique output
|
||||
# of a target is prepared by depending on the file itself. Generators that
|
||||
# cannot do so diagnose it.
|
||||
set(byproduct "${CMAKE_CURRENT_BINARY_DIR}/byproduct.txt")
|
||||
add_custom_target(produce_byproduct
|
||||
COMMAND ${CMAKE_COMMAND} -E touch "${byproduct}"
|
||||
BYPRODUCTS "${byproduct}"
|
||||
)
|
||||
install(FILES "${byproduct}"
|
||||
DESTINATION share/install-prep
|
||||
COMPONENT Byproduct
|
||||
)
|
||||
|
||||
add_library(unit_tests STATIC neverbuild.c)
|
||||
@@ -0,0 +1,18 @@
|
||||
include(GeneratedCommon.cmake)
|
||||
|
||||
# The target and its generated headers are defined in a subdirectory but
|
||||
# installed from here, so the generated files must be found in the target's
|
||||
# directory rather than the directory of the install rule.
|
||||
add_subdirectory(generated)
|
||||
|
||||
install(TARGETS subdirectory_headers
|
||||
ARCHIVE DESTINATION lib
|
||||
COMPONENT Archive
|
||||
EXCLUDE_FROM_ALL
|
||||
FILE_SET HEADERS DESTINATION include
|
||||
COMPONENT Headers
|
||||
PUBLIC_HEADER DESTINATION include/public
|
||||
COMPONENT Headers
|
||||
)
|
||||
|
||||
add_library(unit_tests STATIC neverbuild.c)
|
||||
@@ -0,0 +1,32 @@
|
||||
include(GeneratedCommon.cmake)
|
||||
|
||||
# Each property uses its own target so that preparing one file cannot
|
||||
# produce another as a side effect.
|
||||
foreach(property IN ITEMS PUBLIC_HEADER PRIVATE_HEADER RESOURCE)
|
||||
string(TOLOWER "${property}" name)
|
||||
add_generated_file(generated_file "generated_${name}.h")
|
||||
add_library(generated_${name} STATIC EXCLUDE_FROM_ALL
|
||||
"${generated_target_source}" "${generated_file}")
|
||||
set_property(TARGET generated_${name}
|
||||
PROPERTY ${property} "${generated_file}")
|
||||
install(TARGETS generated_${name}
|
||||
ARCHIVE DESTINATION lib
|
||||
COMPONENT Archive
|
||||
EXCLUDE_FROM_ALL
|
||||
${property} DESTINATION include/${name}
|
||||
COMPONENT Headers
|
||||
)
|
||||
endforeach()
|
||||
|
||||
# Public headers that are not generated do not need their target built.
|
||||
add_library(plain_headers STATIC EXCLUDE_FROM_ALL neverbuild.c plain.h)
|
||||
set_property(TARGET plain_headers PROPERTY PUBLIC_HEADER plain.h)
|
||||
install(TARGETS plain_headers
|
||||
ARCHIVE DESTINATION lib
|
||||
COMPONENT Archive
|
||||
EXCLUDE_FROM_ALL
|
||||
PUBLIC_HEADER DESTINATION include
|
||||
COMPONENT Headers
|
||||
)
|
||||
|
||||
add_library(unit_tests STATIC neverbuild.c)
|
||||
@@ -0,0 +1 @@
|
||||
check_installed([[^lib;lib/(lib)?hidden\.(a|lib|l)$]])
|
||||
@@ -0,0 +1,10 @@
|
||||
enable_language(C)
|
||||
|
||||
add_library(hidden STATIC lib.c)
|
||||
install(TARGETS hidden
|
||||
ARCHIVE DESTINATION lib
|
||||
COMPONENT Hidden
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
||||
|
||||
add_library(unit_tests STATIC neverbuild.c)
|
||||
@@ -0,0 +1,7 @@
|
||||
check_installed([[^bin;bin/imported-tool(\.exe)?$]])
|
||||
|
||||
execute_process(COMMAND "${CMAKE_INSTALL_PREFIX}/bin/imported-tool${CMAKE_HOST_EXECUTABLE_SUFFIX}"
|
||||
RESULT_VARIABLE result)
|
||||
if(NOT result EQUAL 0)
|
||||
set(RunCMake_TEST_FAILED "Installed imported-tool failed: ${result}")
|
||||
endif()
|
||||
@@ -0,0 +1,22 @@
|
||||
enable_language(C)
|
||||
|
||||
add_executable(imported_producer EXCLUDE_FROM_ALL runtime_main.c)
|
||||
set_target_properties(imported_producer PROPERTIES
|
||||
OUTPUT_NAME imported-tool
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
|
||||
RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}"
|
||||
)
|
||||
|
||||
set(imported_location "${CMAKE_BINARY_DIR}/imported-tool${CMAKE_EXECUTABLE_SUFFIX}")
|
||||
add_executable(imported_tool IMPORTED)
|
||||
set_target_properties(imported_tool PROPERTIES
|
||||
IMPORTED_LOCATION "${imported_location}"
|
||||
)
|
||||
add_dependencies(imported_tool imported_producer)
|
||||
|
||||
install(IMPORTED_RUNTIME_ARTIFACTS imported_tool
|
||||
RUNTIME DESTINATION bin
|
||||
COMPONENT Imported
|
||||
)
|
||||
|
||||
add_library(unit_tests STATIC neverbuild.c)
|
||||
@@ -0,0 +1 @@
|
||||
[^0]
|
||||
@@ -0,0 +1,8 @@
|
||||
set(CMAKE_SKIP_INSTALL_PREP_TARGETS ON)
|
||||
|
||||
enable_language(C)
|
||||
|
||||
add_library(install_prep_gate_on STATIC lib.c)
|
||||
install(TARGETS install_prep_gate_on
|
||||
ARCHIVE DESTINATION lib
|
||||
)
|
||||
@@ -0,0 +1,17 @@
|
||||
check_installed([[^lib;lib/libnamelink\.(so|dylib)$]])
|
||||
|
||||
if(APPLE)
|
||||
set(namelink "${CMAKE_INSTALL_PREFIX}/lib/libnamelink.dylib")
|
||||
set(expected libnamelink.1.dylib)
|
||||
else()
|
||||
set(namelink "${CMAKE_INSTALL_PREFIX}/lib/libnamelink.so")
|
||||
set(expected libnamelink.so.1)
|
||||
endif()
|
||||
if(NOT IS_SYMLINK "${namelink}")
|
||||
set(RunCMake_TEST_FAILED "The installed namelink is not a symlink.")
|
||||
return()
|
||||
endif()
|
||||
file(READ_SYMLINK "${namelink}" actual)
|
||||
if(NOT actual STREQUAL expected)
|
||||
set(RunCMake_TEST_FAILED "Namelink points to ${actual}, expected ${expected}.")
|
||||
endif()
|
||||
@@ -0,0 +1,12 @@
|
||||
enable_language(C)
|
||||
|
||||
add_library(namelink SHARED EXCLUDE_FROM_ALL lib.c)
|
||||
set_target_properties(namelink PROPERTIES
|
||||
VERSION 1.0
|
||||
SOVERSION 1
|
||||
)
|
||||
install(TARGETS namelink
|
||||
LIBRARY DESTINATION lib
|
||||
COMPONENT Runtime
|
||||
NAMELINK_COMPONENT Namelink
|
||||
)
|
||||
@@ -0,0 +1 @@
|
||||
check_installed([[^lib;lib/(lib)?nested\.(a|lib|l)$]])
|
||||
@@ -0,0 +1,9 @@
|
||||
enable_language(C)
|
||||
|
||||
add_library(nested STATIC lib.c)
|
||||
install(TARGETS nested
|
||||
ARCHIVE DESTINATION lib
|
||||
COMPONENT Nested/Runtime_1.2+dbg
|
||||
)
|
||||
|
||||
add_library(unit_tests STATIC neverbuild.c)
|
||||
@@ -0,0 +1 @@
|
||||
[^0]
|
||||
Whitespace-only changes.
@@ -0,0 +1,183 @@
|
||||
include(RunCMake)
|
||||
|
||||
# Function called in *-check.cmake scripts to check installed files.
|
||||
function(check_installed expect)
|
||||
file(GLOB_RECURSE actual
|
||||
LIST_DIRECTORIES TRUE
|
||||
RELATIVE ${CMAKE_INSTALL_PREFIX}
|
||||
${CMAKE_INSTALL_PREFIX}/*
|
||||
)
|
||||
if(actual)
|
||||
list(SORT actual)
|
||||
endif()
|
||||
if(NOT "${actual}" MATCHES "${expect}")
|
||||
set(RunCMake_TEST_FAILED "Installed files:
|
||||
${actual}
|
||||
do not match what we expected:
|
||||
${expect}
|
||||
in directory:
|
||||
${CMAKE_INSTALL_PREFIX}\n" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Functions called in *-check.cmake scripts to check whether preparing for
|
||||
# installation built the given static library targets.
|
||||
function(check_prepared)
|
||||
foreach(target IN LISTS ARGN)
|
||||
if(NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/${RunCMake_TEST_CONFIG}/lib${target}.a" AND
|
||||
NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/${RunCMake_TEST_CONFIG}/${target}.lib" AND
|
||||
NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/${RunCMake_TEST_CONFIG}/${target}.l")
|
||||
set(RunCMake_TEST_FAILED "Preparation did not build ${target}." PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
function(check_not_prepared)
|
||||
foreach(target IN LISTS ARGN)
|
||||
file(GLOB_RECURSE artifacts LIST_DIRECTORIES FALSE
|
||||
"${RunCMake_TEST_BINARY_DIR}/lib${target}.a"
|
||||
"${RunCMake_TEST_BINARY_DIR}/${target}.lib"
|
||||
)
|
||||
if(artifacts)
|
||||
set(RunCMake_TEST_FAILED "Preparation built ${target}: ${artifacts}" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
# Configure a test project. Callers set RunCMake_TEST_NO_CLEAN afterward to
|
||||
# run further commands in the same build tree.
|
||||
macro(configure_install_prep test config)
|
||||
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build)
|
||||
set(CMAKE_INSTALL_PREFIX ${RunCMake_BINARY_DIR}/${test}-install)
|
||||
file(REMOVE_RECURSE "${CMAKE_INSTALL_PREFIX}")
|
||||
set(RunCMake_TEST_CONFIG "")
|
||||
if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
|
||||
set(RunCMake_TEST_CONFIG "${config}")
|
||||
endif()
|
||||
set(RunCMake_TEST_OPTIONS
|
||||
-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX})
|
||||
if(NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
|
||||
list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=${config})
|
||||
endif()
|
||||
run_cmake(${test})
|
||||
set(RunCMake_TEST_NO_CLEAN TRUE)
|
||||
endmacro()
|
||||
|
||||
# Build a preparation target that is expected not to exist.
|
||||
function(run_missing_install_prep test prep_target)
|
||||
set(RunCMake_TEST_OUTPUT_MERGE TRUE)
|
||||
run_cmake_command(${test}-build ${CMAKE_COMMAND}
|
||||
--build . --config Debug --target ${prep_target})
|
||||
endfunction()
|
||||
|
||||
# Build a preparation target and then install the matching component.
|
||||
function(run_install_prep test prep_target install_component)
|
||||
configure_install_prep(${test} Debug)
|
||||
run_cmake_command(${test}-prep ${CMAKE_COMMAND}
|
||||
--build . --config Debug --target ${prep_target})
|
||||
if(EXISTS "${CMAKE_INSTALL_PREFIX}")
|
||||
message(SEND_ERROR "${test}: preparation ran installation.")
|
||||
endif()
|
||||
|
||||
set(install_args --install . --config Debug)
|
||||
if(NOT install_component STREQUAL "ALL")
|
||||
list(APPEND install_args --component ${install_component})
|
||||
endif()
|
||||
set(RunCMake-check-file ${test}-install-check.cmake)
|
||||
run_cmake_command(${test}-install ${CMAKE_COMMAND} ${install_args})
|
||||
endfunction()
|
||||
|
||||
block()
|
||||
configure_install_prep(InstallPrepGate-ON Debug)
|
||||
run_missing_install_prep(InstallPrepGate-ON install_prep/all)
|
||||
endblock()
|
||||
|
||||
block()
|
||||
configure_install_prep(NoInstallRules Debug)
|
||||
run_missing_install_prep(NoInstallRules install_prep/all)
|
||||
endblock()
|
||||
|
||||
run_install_prep(All install_prep/all ALL)
|
||||
run_install_prep(Runtime install_prep/Runtime Runtime)
|
||||
run_install_prep(Development install_prep/Development Development)
|
||||
run_install_prep(Nested
|
||||
install_prep/Nested/Runtime_1.2+dbg Nested/Runtime_1.2+dbg)
|
||||
run_install_prep(Default install_prep/DefaultComponent DefaultComponent)
|
||||
run_install_prep(Hidden install_prep/Hidden Hidden)
|
||||
run_install_prep(Imported install_prep/Imported Imported)
|
||||
run_install_prep(Documentation install_prep/Documentation Documentation)
|
||||
run_install_prep(ExcludedSubdirectory
|
||||
install_prep/ExcludedSubdirectory ExcludedSubdirectory)
|
||||
run_install_prep(GeneratedFileSetHeaders install_prep/Headers Headers)
|
||||
run_install_prep(GeneratedTargetProperties install_prep/Headers Headers)
|
||||
run_install_prep(GeneratedByOtherTarget install_prep/Headers Headers)
|
||||
run_install_prep(GeneratedByDependency install_prep/Headers Headers)
|
||||
run_install_prep(GeneratedSubdirectory install_prep/Headers Headers)
|
||||
run_install_prep(GeneratedFiles install_prep/Files Files)
|
||||
run_install_prep(TargetFileArtifact install_prep/Artifacts Artifacts)
|
||||
if(RunCMake_GENERATOR MATCHES "Ninja")
|
||||
run_install_prep(GeneratedFilesByproduct install_prep/Byproduct Byproduct)
|
||||
else()
|
||||
# The byproduct cannot be prepared, which is diagnosed.
|
||||
block()
|
||||
configure_install_prep(GeneratedFilesByproduct Debug)
|
||||
endblock()
|
||||
endif()
|
||||
|
||||
block()
|
||||
configure_install_prep(ComponentNames Debug)
|
||||
run_cmake_command(ComponentNames-all-build ${CMAKE_COMMAND}
|
||||
--build . --config Debug --target install_prep/all)
|
||||
run_cmake_command(ComponentNames-colon-build ${CMAKE_COMMAND}
|
||||
--build . --config Debug --target install_prep/Colon:Name)
|
||||
run_missing_install_prep(ComponentNames-dotdot install_prep/Unsafe/../Name)
|
||||
run_missing_install_prep(ComponentNames-empty-segment
|
||||
install_prep/Empty//Segment)
|
||||
run_missing_install_prep(ComponentNames-dot install_prep/./Dot)
|
||||
endblock()
|
||||
|
||||
function(run_configured_install_prep test config)
|
||||
configure_install_prep(${test} ${config})
|
||||
run_cmake_command(${test}-prep ${CMAKE_COMMAND}
|
||||
--build . --config ${config} --target install_prep/Configured)
|
||||
if(EXISTS "${CMAKE_INSTALL_PREFIX}")
|
||||
message(SEND_ERROR "${test}: preparation ran installation.")
|
||||
endif()
|
||||
set(RunCMake-check-file ${test}-install-check.cmake)
|
||||
run_cmake_command(${test}-install ${CMAKE_COMMAND}
|
||||
--install . --config ${config} --component Configured)
|
||||
endfunction()
|
||||
|
||||
run_configured_install_prep(ConfigurationsDebug Debug)
|
||||
run_configured_install_prep(ConfigurationsRelease Release)
|
||||
|
||||
if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
|
||||
block()
|
||||
configure_install_prep(ConfigurationsMulti Debug)
|
||||
foreach(config IN ITEMS Debug Release)
|
||||
set(RunCMake_TEST_CONFIG "${config}")
|
||||
run_cmake_command(ConfigurationsMulti-prep-${config} ${CMAKE_COMMAND}
|
||||
--build . --config ${config} --target install_prep/Configured)
|
||||
run_cmake_command(ConfigurationsMulti-install-${config} ${CMAKE_COMMAND}
|
||||
--install . --config ${config} --component Configured)
|
||||
endforeach()
|
||||
endblock()
|
||||
endif()
|
||||
|
||||
if(CMAKE_HOST_SYSTEM_NAME MATCHES "^(Windows|Linux|Darwin|FreeBSD)$")
|
||||
run_install_prep(RuntimeDependencySet
|
||||
install_prep/RuntimeDependencySet RuntimeDependencySet)
|
||||
run_install_prep(RuntimeDependencies
|
||||
install_prep/RuntimeDependencies RuntimeDependencies)
|
||||
endif()
|
||||
|
||||
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
|
||||
run_install_prep(RuntimeDependencyFramework
|
||||
install_prep/FrameworkDependencies FrameworkDependencies)
|
||||
endif()
|
||||
|
||||
if(CMAKE_HOST_SYSTEM_NAME MATCHES "^(Linux|Darwin)$")
|
||||
run_install_prep(Namelink install_prep/Namelink Namelink)
|
||||
endif()
|
||||
@@ -0,0 +1,7 @@
|
||||
check_installed([[^bin;bin/runtime(\.exe)?$]])
|
||||
|
||||
execute_process(COMMAND "${CMAKE_INSTALL_PREFIX}/bin/runtime${CMAKE_HOST_EXECUTABLE_SUFFIX}"
|
||||
RESULT_VARIABLE result)
|
||||
if(NOT result EQUAL 0)
|
||||
set(RunCMake_TEST_FAILED "Installed runtime failed: ${result}")
|
||||
endif()
|
||||
@@ -0,0 +1,17 @@
|
||||
enable_language(C)
|
||||
|
||||
add_library(runtime_helper STATIC lib.c)
|
||||
add_executable(runtime EXCLUDE_FROM_ALL runtime.c)
|
||||
target_link_libraries(runtime PRIVATE runtime_helper)
|
||||
install(TARGETS runtime
|
||||
RUNTIME DESTINATION bin
|
||||
COMPONENT Runtime
|
||||
)
|
||||
|
||||
add_library(other_component STATIC neverbuild.c)
|
||||
install(TARGETS other_component
|
||||
ARCHIVE DESTINATION lib
|
||||
COMPONENT Other
|
||||
)
|
||||
|
||||
add_library(unit_tests STATIC neverbuild.c)
|
||||
@@ -0,0 +1,14 @@
|
||||
check_installed([[^$]])
|
||||
|
||||
if(WIN32)
|
||||
if(NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/${RunCMake_TEST_CONFIG}/runtime_dependencies_root.dll" AND
|
||||
NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/${RunCMake_TEST_CONFIG}/libruntime_dependencies_root.dll")
|
||||
set(RunCMake_TEST_FAILED "Preparation did not build the module to scan.")
|
||||
endif()
|
||||
else()
|
||||
execute_process(COMMAND "${RunCMake_TEST_BINARY_DIR}/${RunCMake_TEST_CONFIG}/runtime_dependencies_root${CMAKE_HOST_EXECUTABLE_SUFFIX}"
|
||||
RESULT_VARIABLE result)
|
||||
if(NOT result EQUAL 0)
|
||||
set(RunCMake_TEST_FAILED "Prepared runtime dependency root failed: ${result}")
|
||||
endif()
|
||||
endif()
|
||||
@@ -0,0 +1,24 @@
|
||||
enable_language(C)
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
add_library(runtime_dependencies_root MODULE EXCLUDE_FROM_ALL lib.c)
|
||||
set(runtime_component RuntimeDependencies)
|
||||
set(library_component RuntimeDependenciesSeed)
|
||||
else()
|
||||
add_executable(runtime_dependencies_root EXCLUDE_FROM_ALL runtime_main.c)
|
||||
set(runtime_component RuntimeDependenciesSeed)
|
||||
set(library_component RuntimeDependencies)
|
||||
endif()
|
||||
|
||||
install(TARGETS runtime_dependencies_root
|
||||
RUNTIME_DEPENDENCIES
|
||||
PRE_EXCLUDE_REGEXES ".*"
|
||||
RUNTIME DESTINATION bin
|
||||
COMPONENT ${runtime_component}
|
||||
LIBRARY DESTINATION lib
|
||||
COMPONENT ${library_component}
|
||||
FRAMEWORK DESTINATION Frameworks
|
||||
COMPONENT RuntimeDependencies
|
||||
)
|
||||
|
||||
add_library(unit_tests STATIC neverbuild.c)
|
||||
@@ -0,0 +1,7 @@
|
||||
check_installed([[^$]])
|
||||
|
||||
execute_process(COMMAND "${RunCMake_TEST_BINARY_DIR}/${RunCMake_TEST_CONFIG}/runtime_dependency_framework_root"
|
||||
RESULT_VARIABLE result)
|
||||
if(NOT result EQUAL 0)
|
||||
set(RunCMake_TEST_FAILED "Prepared framework dependency root failed: ${result}")
|
||||
endif()
|
||||
@@ -0,0 +1,20 @@
|
||||
enable_language(C)
|
||||
|
||||
add_executable(runtime_dependency_framework_root EXCLUDE_FROM_ALL
|
||||
runtime_main.c)
|
||||
install(TARGETS runtime_dependency_framework_root
|
||||
RUNTIME_DEPENDENCY_SET runtime_dependency_framework_set
|
||||
RUNTIME DESTINATION bin
|
||||
COMPONENT RuntimeDependencySeed
|
||||
)
|
||||
install(RUNTIME_DEPENDENCY_SET runtime_dependency_framework_set
|
||||
PRE_EXCLUDE_REGEXES ".*"
|
||||
RUNTIME DESTINATION bin
|
||||
COMPONENT RuntimeDependencies
|
||||
LIBRARY DESTINATION lib
|
||||
COMPONENT RuntimeDependencies
|
||||
FRAMEWORK DESTINATION Frameworks
|
||||
COMPONENT FrameworkDependencies
|
||||
)
|
||||
|
||||
add_library(unit_tests STATIC neverbuild.c)
|
||||
@@ -0,0 +1,20 @@
|
||||
if(WIN32)
|
||||
check_installed([[^bin;bin/(lib)?runtime_dependency_support\.dll$]])
|
||||
else()
|
||||
check_installed([[^lib;lib/libruntime_dependency_support\.(so|dylib)$]])
|
||||
endif()
|
||||
|
||||
foreach(target IN ITEMS runtime_dependency_shared runtime_dependency_module)
|
||||
if(NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/${RunCMake_TEST_CONFIG}/lib${target}.so" AND
|
||||
NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/${RunCMake_TEST_CONFIG}/lib${target}.dylib" AND
|
||||
NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/${RunCMake_TEST_CONFIG}/lib${target}.dll" AND
|
||||
NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/${RunCMake_TEST_CONFIG}/${target}.dll")
|
||||
set(RunCMake_TEST_FAILED "Preparation did not build ${target} for scanning.")
|
||||
return()
|
||||
endif()
|
||||
endforeach()
|
||||
execute_process(COMMAND "${RunCMake_TEST_BINARY_DIR}/runtime-dependency-imported${CMAKE_HOST_EXECUTABLE_SUFFIX}"
|
||||
RESULT_VARIABLE result)
|
||||
if(NOT result EQUAL 0)
|
||||
set(RunCMake_TEST_FAILED "Prepared imported runtime dependency root failed: ${result}")
|
||||
endif()
|
||||
@@ -0,0 +1,49 @@
|
||||
enable_language(C)
|
||||
|
||||
add_library(runtime_dependency_shared SHARED EXCLUDE_FROM_ALL lib.c)
|
||||
add_library(runtime_dependency_module MODULE EXCLUDE_FROM_ALL lib.c)
|
||||
|
||||
add_library(runtime_dependency_support SHARED EXCLUDE_FROM_ALL lib.c)
|
||||
set_target_properties(runtime_dependency_support PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
|
||||
RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}")
|
||||
add_executable(runtime_dependency_producer EXCLUDE_FROM_ALL runtime.c)
|
||||
target_link_libraries(runtime_dependency_producer PRIVATE runtime_dependency_support)
|
||||
set_target_properties(runtime_dependency_producer PROPERTIES
|
||||
OUTPUT_NAME runtime-dependency-imported
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
|
||||
RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}"
|
||||
)
|
||||
|
||||
set(imported_location
|
||||
"${CMAKE_BINARY_DIR}/runtime-dependency-imported${CMAKE_EXECUTABLE_SUFFIX}")
|
||||
add_executable(runtime_dependency_imported IMPORTED)
|
||||
set_target_properties(runtime_dependency_imported PROPERTIES
|
||||
IMPORTED_LOCATION "${imported_location}"
|
||||
)
|
||||
add_dependencies(runtime_dependency_imported runtime_dependency_producer)
|
||||
|
||||
install(TARGETS runtime_dependency_shared runtime_dependency_module
|
||||
RUNTIME_DEPENDENCY_SET runtime_dependency_set
|
||||
RUNTIME DESTINATION bin
|
||||
COMPONENT RuntimeDependencySeeds
|
||||
LIBRARY DESTINATION lib
|
||||
COMPONENT RuntimeDependencySeeds
|
||||
)
|
||||
install(IMPORTED_RUNTIME_ARTIFACTS runtime_dependency_imported
|
||||
RUNTIME_DEPENDENCY_SET runtime_dependency_set
|
||||
RUNTIME DESTINATION bin
|
||||
COMPONENT RuntimeDependencySeeds
|
||||
)
|
||||
install(RUNTIME_DEPENDENCY_SET runtime_dependency_set
|
||||
PRE_INCLUDE_REGEXES "runtime_dependency_support"
|
||||
PRE_EXCLUDE_REGEXES ".*"
|
||||
RUNTIME DESTINATION bin
|
||||
COMPONENT RuntimeDependencySet
|
||||
LIBRARY DESTINATION lib
|
||||
COMPONENT RuntimeDependencySet
|
||||
FRAMEWORK DESTINATION Frameworks
|
||||
COMPONENT RuntimeDependencySet
|
||||
)
|
||||
|
||||
add_library(unit_tests STATIC neverbuild.c)
|
||||
@@ -0,0 +1 @@
|
||||
check_installed([[^lib;lib/(lib)?file_artifact\.(a|lib|l)$]])
|
||||
Loaded 100 of 109 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user