summaryrefslogtreecommitdiffstats
path: root/Source/cmGeneratorExpressionEvaluator.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmGeneratorExpressionEvaluator.cxx')
-rw-r--r--Source/cmGeneratorExpressionEvaluator.cxx111
1 files changed, 106 insertions, 5 deletions
diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx
index d86ae54..82becaf 100644
--- a/Source/cmGeneratorExpressionEvaluator.cxx
+++ b/Source/cmGeneratorExpressionEvaluator.cxx
@@ -49,6 +49,8 @@ struct cmGeneratorExpressionNode
virtual bool GeneratesContent() const { return true; }
+ virtual bool RequiresLiteralInput() const { return false; }
+
virtual bool AcceptsSingleArbitraryContentParameter() const
{ return false; }
@@ -98,6 +100,12 @@ static const struct OneNode : public cmGeneratorExpressionNode
} oneNode;
//----------------------------------------------------------------------------
+static const struct OneNode buildInterfaceNode;
+
+//----------------------------------------------------------------------------
+static const struct ZeroNode installInterfaceNode;
+
+//----------------------------------------------------------------------------
#define BOOLEAN_OP_NODE(OPNAME, OP, SUCCESS_VALUE, FAILURE_VALUE) \
static const struct OP ## Node : public cmGeneratorExpressionNode \
{ \
@@ -259,11 +267,34 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
return parameters.front().empty() ? "1" : "0";
}
- return cmsysString_strcasecmp(parameters.begin()->c_str(),
- context->Config) == 0 ? "1" : "0";
+ if (cmsysString_strcasecmp(parameters.begin()->c_str(),
+ context->Config) == 0)
+ {
+ return "1";
+ }
+
+ if (context->CurrentTarget
+ && context->CurrentTarget->IsImported())
+ {
+ const char* loc = 0;
+ const char* imp = 0;
+ std::string suffix;
+ return context->CurrentTarget->GetMappedConfig(context->Config,
+ &loc,
+ &imp,
+ suffix) ? "1" : "0";
+ }
+ return "0";
}
} configurationTestNode;
+
+//----------------------------------------------------------------------------
+static const char* targetPropertyTransitiveWhitelist[] = {
+ "INTERFACE_INCLUDE_DIRECTORIES"
+ , "INTERFACE_COMPILE_DEFINITIONS"
+};
+
//----------------------------------------------------------------------------
static const struct TargetPropertyNode : public cmGeneratorExpressionNode
{
@@ -291,7 +322,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
cmsys::RegularExpression propertyNameValidator;
propertyNameValidator.compile("^[A-Za-z0-9_]+$");
- cmTarget* target = context->Target;
+ cmTarget* target = context->HeadTarget;
std::string propertyName = *parameters.begin();
if (!target && parameters.size() == 1)
@@ -372,18 +403,67 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
content,
dagCheckerParent);
- if (!dagChecker.check())
+ switch (dagChecker.check())
{
+ case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
dagChecker.reportError(context, content->GetOriginalExpression());
return std::string();
+ case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE:
+ // No error. We just skip cyclic references.
+ return std::string();
+ case cmGeneratorExpressionDAGChecker::DAG:
+ break;
}
const char *prop = target->GetProperty(propertyName.c_str());
- return prop ? prop : "";
+ if (!prop)
+ {
+ return std::string();
+ }
+
+ for (size_t i = 0;
+ i < (sizeof(targetPropertyTransitiveWhitelist) /
+ sizeof(*targetPropertyTransitiveWhitelist));
+ ++i)
+ {
+ if (targetPropertyTransitiveWhitelist[i] == propertyName)
+ {
+ cmGeneratorExpression ge(context->Backtrace);
+ return ge.Parse(prop)->Evaluate(context->Makefile,
+ context->Config,
+ context->Quiet,
+ context->HeadTarget,
+ target,
+ &dagChecker);
+ }
+ }
+ return prop;
}
} targetPropertyNode;
//----------------------------------------------------------------------------
+static const struct TargetNameNode : public cmGeneratorExpressionNode
+{
+ TargetNameNode() {}
+
+ virtual bool GeneratesContent() const { return true; }
+
+ virtual bool AcceptsSingleArbitraryContentParameter() const { return true; }
+ virtual bool RequiresLiteralInput() const { return true; }
+
+ std::string Evaluate(const std::vector<std::string> &parameters,
+ cmGeneratorExpressionContext *,
+ const GeneratorExpressionContent *,
+ cmGeneratorExpressionDAGChecker *) const
+ {
+ return parameters.front();
+ }
+
+ virtual int NumExpectedParameters() const { return 1; }
+
+} targetNameNode;
+
+//----------------------------------------------------------------------------
template<bool linker, bool soname>
struct TargetFilesystemArtifactResultCreator
{
@@ -608,6 +688,12 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier)
return &commaNode;
else if (identifier == "TARGET_PROPERTY")
return &targetPropertyNode;
+ else if (identifier == "TARGET_NAME")
+ return &targetNameNode;
+ else if (identifier == "BUILD_INTERFACE")
+ return &buildInterfaceNode;
+ else if (identifier == "INSTALL_INTERFACE")
+ return &installInterfaceNode;
return 0;
}
@@ -697,6 +783,15 @@ std::string GeneratorExpressionContent::Evaluate(
= pit->end();
for ( ; it != end; ++it)
{
+ if (node->RequiresLiteralInput())
+ {
+ if ((*it)->GetType() != cmGeneratorExpressionEvaluator::Text)
+ {
+ reportError(context, this->GetOriginalExpression(),
+ "$<" + identifier + "> expression requires literal input.");
+ return std::string();
+ }
+ }
result += (*it)->Evaluate(context, dagChecker);
if (context->HadError)
{
@@ -704,6 +799,12 @@ std::string GeneratorExpressionContent::Evaluate(
}
}
}
+ if (node->RequiresLiteralInput())
+ {
+ std::vector<std::string> parameters;
+ parameters.push_back(result);
+ return node->Evaluate(parameters, context, this, dagChecker);
+ }
return result;
}