summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorMarc Chevrier <marc.chevrier@sap.com>2018-04-13 14:16:32 (GMT)
committerMarc Chevrier <marc.chevrier@sap.com>2018-04-23 09:13:52 (GMT)
commit4d15046eddcd6326fd7229adcb3bdb93717f3e06 (patch)
tree1703b6f342f434aea4c038587538f77dbeb806e6 /Source
parent1f372ac4e52ac7de65d3fc855b280388b70203f3 (diff)
downloadCMake-4d15046eddcd6326fd7229adcb3bdb93717f3e06.zip
CMake-4d15046eddcd6326fd7229adcb3bdb93717f3e06.tar.gz
CMake-4d15046eddcd6326fd7229adcb3bdb93717f3e06.tar.bz2
Genex: Add $<TARGET_GENEX_EVAL:...> and $<GENEX_EVAL:...>
Fixes: #17884
Diffstat (limited to 'Source')
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.cxx12
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.h1
-rw-r--r--Source/cmGeneratorExpressionNode.cxx113
3 files changed, 125 insertions, 1 deletions
diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx
index f0eafb4..face282 100644
--- a/Source/cmGeneratorExpressionDAGChecker.cxx
+++ b/Source/cmGeneratorExpressionDAGChecker.cxx
@@ -154,6 +154,18 @@ bool cmGeneratorExpressionDAGChecker::GetTransitivePropertiesOnly()
return top->TransitivePropertiesOnly;
}
+bool cmGeneratorExpressionDAGChecker::EvaluatingGenexExpression()
+{
+ const cmGeneratorExpressionDAGChecker* top = this;
+ const cmGeneratorExpressionDAGChecker* parent = this->Parent;
+ while (parent) {
+ top = parent;
+ parent = parent->Parent;
+ }
+
+ return top->Property == "TARGET_GENEX_EVAL" || top->Property == "GENEX_EVAL";
+}
+
bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries(const char* tgt)
{
const cmGeneratorExpressionDAGChecker* top = this;
diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h
index 3f73fca..a3a8f69 100644
--- a/Source/cmGeneratorExpressionDAGChecker.h
+++ b/Source/cmGeneratorExpressionDAGChecker.h
@@ -61,6 +61,7 @@ struct cmGeneratorExpressionDAGChecker
void ReportError(cmGeneratorExpressionContext* context,
const std::string& expr);
+ bool EvaluatingGenexExpression();
bool EvaluatingLinkLibraries(const char* tgt = nullptr);
#define DECLARE_TRANSITIVE_PROPERTY_METHOD(METHOD) bool METHOD() const;
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 89ed4f0..399e894 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -365,6 +365,113 @@ static const struct TargetNameIfExistsNode : public cmGeneratorExpressionNode
}
} targetNameIfExistsNode;
+struct GenexEvaluator : public cmGeneratorExpressionNode
+{
+ GenexEvaluator() {}
+
+protected:
+ std::string EvaluateExpression(
+ const std::string& genexOperator, const std::string& expression,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content,
+ cmGeneratorExpressionDAGChecker* dagCheckerParent) const
+ {
+ if (context->HeadTarget) {
+ cmGeneratorExpressionDAGChecker dagChecker(
+ context->Backtrace, context->HeadTarget->GetName(), genexOperator,
+ content, dagCheckerParent);
+ switch (dagChecker.Check()) {
+ case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
+ case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE: {
+ dagChecker.ReportError(context, content->GetOriginalExpression());
+ return std::string();
+ }
+ case cmGeneratorExpressionDAGChecker::ALREADY_SEEN:
+ case cmGeneratorExpressionDAGChecker::DAG:
+ break;
+ }
+
+ return this->EvaluateDependentExpression(
+ expression, context->LG, context, context->HeadTarget,
+ context->CurrentTarget, &dagChecker);
+ }
+
+ return this->EvaluateDependentExpression(
+ expression, context->LG, context, context->HeadTarget,
+ context->CurrentTarget, dagCheckerParent);
+ }
+};
+
+static const struct TargetGenexEvalNode : public GenexEvaluator
+{
+ TargetGenexEvalNode() {}
+
+ int NumExpectedParameters() const override { return 2; }
+
+ bool AcceptsArbitraryContentParameter() const override { return true; }
+
+ std::string Evaluate(
+ const std::vector<std::string>& parameters,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content,
+ cmGeneratorExpressionDAGChecker* dagCheckerParent) const override
+ {
+ const std::string& targetName = parameters.front();
+ if (targetName.empty() ||
+ !cmGeneratorExpression::IsValidTargetName(targetName)) {
+ reportError(context, content->GetOriginalExpression(),
+ "$<TARGET_GENEX_EVAL:tgt, ...> expression requires a "
+ "non-empty valid target name.");
+ return std::string();
+ }
+
+ const auto* target = context->LG->FindGeneratorTargetToUse(targetName);
+ if (!target) {
+ std::ostringstream e;
+ e << "$<TARGET_GENEX_EVAL:tgt, ...> target \"" << targetName
+ << "\" not found.";
+ reportError(context, content->GetOriginalExpression(), e.str());
+ return std::string();
+ }
+
+ const std::string& expression = parameters[1];
+ if (expression.empty()) {
+ return expression;
+ }
+
+ cmGeneratorExpressionContext targetContext(
+ context->LG, context->Config, context->Quiet, target, target,
+ context->EvaluateForBuildsystem, context->Backtrace, context->Language);
+
+ return this->EvaluateExpression("TARGET_GENEX_EVAL", expression,
+ &targetContext, content, dagCheckerParent);
+ }
+} targetGenexEvalNode;
+
+static const struct GenexEvalNode : public GenexEvaluator
+{
+ GenexEvalNode() {}
+
+ int NumExpectedParameters() const override { return 1; }
+
+ bool AcceptsArbitraryContentParameter() const override { return true; }
+
+ std::string Evaluate(
+ const std::vector<std::string>& parameters,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content,
+ cmGeneratorExpressionDAGChecker* dagCheckerParent) const override
+ {
+ const std::string& expression = parameters[0];
+ if (expression.empty()) {
+ return expression;
+ }
+
+ return this->EvaluateExpression("GENEX_EVAL", expression, context, content,
+ dagCheckerParent);
+ }
+} genexEvalNode;
+
static const struct LowerCaseNode : public cmGeneratorExpressionNode
{
LowerCaseNode() {}
@@ -1124,7 +1231,9 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
const char* prop = target->GetProperty(propertyName);
if (dagCheckerParent) {
- if (dagCheckerParent->EvaluatingLinkLibraries()) {
+ if (dagCheckerParent->EvaluatingGenexExpression()) {
+ // No check required.
+ } else if (dagCheckerParent->EvaluatingLinkLibraries()) {
#define TRANSITIVE_PROPERTY_COMPARE(PROPERTY) \
(#PROPERTY == propertyName || "INTERFACE_" #PROPERTY == propertyName) ||
if (CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(
@@ -1933,6 +2042,8 @@ const cmGeneratorExpressionNode* cmGeneratorExpressionNode::GetNode(
nodeMap["TARGET_POLICY"] = &targetPolicyNode;
nodeMap["TARGET_EXISTS"] = &targetExistsNode;
nodeMap["TARGET_NAME_IF_EXISTS"] = &targetNameIfExistsNode;
+ nodeMap["TARGET_GENEX_EVAL"] = &targetGenexEvalNode;
+ nodeMap["GENEX_EVAL"] = &genexEvalNode;
nodeMap["BUILD_INTERFACE"] = &buildInterfaceNode;
nodeMap["INSTALL_INTERFACE"] = &installInterfaceNode;
nodeMap["INSTALL_PREFIX"] = &installPrefixNode;