diff options
author | Joerg Bornemann <joerg.bornemann@qt.io> | 2020-07-16 08:15:04 (GMT) |
---|---|---|
committer | Joerg Bornemann <joerg.bornemann@qt.io> | 2020-07-21 15:16:26 (GMT) |
commit | 2cdaf43d966f8407f0fb75ceb131fdca16617915 (patch) | |
tree | 15e3284091c62ca73b22fa15ea1a93770c97305d /Source | |
parent | c7b7547d8da6b9a4225d111440d0cf6c2f55914d (diff) | |
download | CMake-2cdaf43d966f8407f0fb75ceb131fdca16617915.zip CMake-2cdaf43d966f8407f0fb75ceb131fdca16617915.tar.gz CMake-2cdaf43d966f8407f0fb75ceb131fdca16617915.tar.bz2 |
Allow generator expressions in the EXCLUDE_FROM_ALL target property
This allows for setting EXCLUDE_FROM_ALL, conditional on the build
configuration. However, only the Ninja Multi-Config generator supports
different property values per config. All other multi-config
generators will yield an error in that situation.
Fixes: #20923
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmGlobalCommonGenerator.cxx | 32 | ||||
-rw-r--r-- | Source/cmGlobalCommonGenerator.h | 4 | ||||
-rw-r--r-- | Source/cmGlobalGenerator.cxx | 31 | ||||
-rw-r--r-- | Source/cmGlobalGenerator.h | 3 | ||||
-rw-r--r-- | Source/cmGlobalGhsMultiGenerator.cxx | 2 | ||||
-rw-r--r-- | Source/cmGlobalNinjaGenerator.cxx | 2 | ||||
-rw-r--r-- | Source/cmGlobalUnixMakefileGenerator3.cxx | 4 |
7 files changed, 64 insertions, 14 deletions
diff --git a/Source/cmGlobalCommonGenerator.cxx b/Source/cmGlobalCommonGenerator.cxx index 9dc86f4..5eff3b8 100644 --- a/Source/cmGlobalCommonGenerator.cxx +++ b/Source/cmGlobalCommonGenerator.cxx @@ -5,8 +5,12 @@ #include <memory> #include <utility> +#include <cmext/algorithm> + +#include "cmGeneratorExpression.h" #include "cmGeneratorTarget.h" #include "cmLocalGenerator.h" +#include "cmMakefile.h" #include "cmProperty.h" #include "cmStateDirectory.h" #include "cmStateSnapshot.h" @@ -31,6 +35,8 @@ cmGlobalCommonGenerator::ComputeDirectoryTargets() const lg->GetStateSnapshot().GetDirectory().GetCurrentBinary()); DirectoryTarget& dirTarget = dirTargets[currentBinaryDir]; dirTarget.LG = lg.get(); + const std::vector<std::string>& configs = + lg->GetMakefile()->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig); // The directory-level rule should depend on the target-level rules // for all targets in the directory. @@ -46,11 +52,18 @@ cmGlobalCommonGenerator::ComputeDirectoryTargets() const } DirectoryTarget::Target t; t.GT = gt.get(); - if (cmProp exclude = gt->GetProperty("EXCLUDE_FROM_ALL")) { - if (cmIsOn(*exclude)) { - // This target has been explicitly excluded. - t.ExcludeFromAll = true; - } else { + const std::string EXCLUDE_FROM_ALL("EXCLUDE_FROM_ALL"); + if (cmProp exclude = gt->GetProperty(EXCLUDE_FROM_ALL)) { + for (const std::string& config : configs) { + cmGeneratorExpressionInterpreter genexInterpreter(lg.get(), config, + gt.get()); + if (cmIsOn(genexInterpreter.Evaluate(*exclude, EXCLUDE_FROM_ALL))) { + // This target has been explicitly excluded. + t.ExcludedFromAllInConfigs.push_back(config); + } + } + + if (t.ExcludedFromAllInConfigs.empty()) { // This target has been explicitly un-excluded. The directory-level // rule for every directory between this and the root should depend // on the target-level rule for this target. @@ -78,3 +91,12 @@ cmGlobalCommonGenerator::ComputeDirectoryTargets() const return dirTargets; } + +bool cmGlobalCommonGenerator::IsExcludedFromAllInConfig( + const DirectoryTarget::Target& t, const std::string& config) +{ + if (this->IsMultiConfig()) { + return cm::contains(t.ExcludedFromAllInConfigs, config); + } + return !t.ExcludedFromAllInConfigs.empty(); +} diff --git a/Source/cmGlobalCommonGenerator.h b/Source/cmGlobalCommonGenerator.h index 7d16dac..f97b5f4 100644 --- a/Source/cmGlobalCommonGenerator.h +++ b/Source/cmGlobalCommonGenerator.h @@ -30,7 +30,7 @@ public: struct Target { cmGeneratorTarget const* GT = nullptr; - bool ExcludeFromAll = false; + std::vector<std::string> ExcludedFromAllInConfigs; }; std::vector<Target> Targets; struct Dir @@ -41,6 +41,8 @@ public: std::vector<Dir> Children; }; std::map<std::string, DirectoryTarget> ComputeDirectoryTargets() const; + bool IsExcludedFromAllInConfig(const DirectoryTarget::Target& t, + const std::string& config); }; #endif diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 49b73a8..d39fefa 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -2173,13 +2173,38 @@ bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root, } bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root, - cmGeneratorTarget* target) const + const cmGeneratorTarget* target) const { if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) { return true; } - if (cmProp exclude = target->GetProperty("EXCLUDE_FROM_ALL")) { - return cmIsOn(*exclude); + cmMakefile* mf = root->GetMakefile(); + const std::string EXCLUDE_FROM_ALL = "EXCLUDE_FROM_ALL"; + if (cmProp exclude = target->GetProperty(EXCLUDE_FROM_ALL)) { + // Expand the property value per configuration. + unsigned int trueCount = 0; + unsigned int falseCount = 0; + const std::vector<std::string>& configs = + mf->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig); + for (const std::string& config : configs) { + cmGeneratorExpressionInterpreter genexInterpreter(root, config, target); + if (cmIsOn(genexInterpreter.Evaluate(*exclude, EXCLUDE_FROM_ALL))) { + ++trueCount; + } else { + ++falseCount; + } + } + + // Check whether the genex expansion of the property agrees in all + // configurations. + if (trueCount && falseCount) { + std::ostringstream e; + e << "The EXCLUDED_FROM_ALL property of target \"" << target->GetName() + << "\" varies by configuration. This is not supported by the \"" + << root->GetGlobalGenerator()->GetName() << "\" generator."; + mf->IssueMessage(MessageType::FATAL_ERROR, e.str()); + } + return trueCount; } // This target is included in its directory. Check whether the // directory is excluded. diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 57c7808..c2c80c2 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -542,7 +542,8 @@ protected: bool IsExcluded(cmStateSnapshot const& root, cmStateSnapshot const& snp) const; bool IsExcluded(cmLocalGenerator* root, cmLocalGenerator* gen) const; - bool IsExcluded(cmLocalGenerator* root, cmGeneratorTarget* target) const; + bool IsExcluded(cmLocalGenerator* root, + const cmGeneratorTarget* target) const; virtual void InitializeProgressMarks() {} struct GlobalTargetInfo diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx index 2fcba9a..1664dd0 100644 --- a/Source/cmGlobalGhsMultiGenerator.cxx +++ b/Source/cmGlobalGhsMultiGenerator.cxx @@ -470,7 +470,7 @@ void cmGlobalGhsMultiGenerator::WriteAllTarget( if (t->GetType() == cmStateEnums::INTERFACE_LIBRARY) { continue; } - if (!cmIsOn(t->GetProperty("EXCLUDE_FROM_ALL"))) { + if (!IsExcluded(t->GetLocalGenerator(), t)) { defaultTargets.push_back(t); } } diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 48eb405..786cde7 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -1357,7 +1357,7 @@ void cmGlobalNinjaGenerator::WriteFolderTargets(std::ostream& os) build.Outputs.front() = this->BuildAlias(buildDirAllTarget, config); configDeps.emplace_back(build.Outputs.front()); for (DirectoryTarget::Target const& t : dt.Targets) { - if (!t.ExcludeFromAll) { + if (!IsExcludedFromAllInConfig(t, config)) { this->AppendTargetOutputs(t.GT, build.ExplicitDeps, config); } } diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index c31983b..d45fc01 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -416,7 +416,7 @@ void cmGlobalUnixMakefileGenerator3::WriteDirectoryRule2( std::vector<std::string> depends; for (DirectoryTarget::Target const& t : dt.Targets) { // Add this to the list of depends rules in this directory. - if ((!check_all || !t.ExcludeFromAll) && + if ((!check_all || t.ExcludedFromAllInConfigs.empty()) && (!check_relink || t.GT->NeedRelinkBeforeInstall(lg->GetConfigName()))) { // The target may be from a different directory; use its local gen. @@ -846,7 +846,7 @@ void cmGlobalUnixMakefileGenerator3::InitializeProgressMarks() cmLocalGenerator* tlg = gt->GetLocalGenerator(); if (gt->GetType() == cmStateEnums::INTERFACE_LIBRARY || - gt->GetPropertyAsBool("EXCLUDE_FROM_ALL")) { + IsExcluded(lg.get(), gt.get())) { continue; } |