summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorJoerg Bornemann <joerg.bornemann@qt.io>2020-07-16 08:15:04 (GMT)
committerJoerg Bornemann <joerg.bornemann@qt.io>2020-07-21 15:16:26 (GMT)
commit2cdaf43d966f8407f0fb75ceb131fdca16617915 (patch)
tree15e3284091c62ca73b22fa15ea1a93770c97305d /Source
parentc7b7547d8da6b9a4225d111440d0cf6c2f55914d (diff)
downloadCMake-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.cxx32
-rw-r--r--Source/cmGlobalCommonGenerator.h4
-rw-r--r--Source/cmGlobalGenerator.cxx31
-rw-r--r--Source/cmGlobalGenerator.h3
-rw-r--r--Source/cmGlobalGhsMultiGenerator.cxx2
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx2
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.cxx4
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;
}