diff options
author | Brad King <brad.king@kitware.com> | 2013-02-14 15:17:22 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2013-02-14 15:18:31 (GMT) |
commit | 95a9c80cacea50e2b5d52d67d0a7f5c9b50192dd (patch) | |
tree | 05d5e8dfb1b303549ba5f3570eb6ec903e95c97f /Source/cmGeneratorExpressionEvaluator.cxx | |
parent | baa33acbdaa3bf88fe1fc591562574ab43b056fe (diff) | |
parent | 765386279815f208c5f83b1ad2b66776e990feb9 (diff) | |
download | CMake-95a9c80cacea50e2b5d52d67d0a7f5c9b50192dd.zip CMake-95a9c80cacea50e2b5d52d67d0a7f5c9b50192dd.tar.gz CMake-95a9c80cacea50e2b5d52d67d0a7f5c9b50192dd.tar.bz2 |
Merge topic 'LINK_LIBRARIES-property' into rpath-use-implicit-link-dirs
Resolve a logical conflict in the signature of cmTarget::GetLinkClosure.
Diffstat (limited to 'Source/cmGeneratorExpressionEvaluator.cxx')
-rw-r--r-- | Source/cmGeneratorExpressionEvaluator.cxx | 158 |
1 files changed, 145 insertions, 13 deletions
diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index 2e123a4..b7ce155 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -47,6 +47,8 @@ struct cmGeneratorExpressionNode virtual bool GeneratesContent() const { return true; } + virtual bool RequiresLiteralInput() const { return false; } + virtual bool AcceptsSingleArbitraryContentParameter() const { return false; } @@ -66,6 +68,8 @@ static const struct ZeroNode : public cmGeneratorExpressionNode virtual bool GeneratesContent() const { return false; } + virtual bool AcceptsSingleArbitraryContentParameter() const { return true; } + std::string Evaluate(const std::vector<std::string> &, cmGeneratorExpressionContext *, const GeneratorExpressionContent *, @@ -94,6 +98,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 \ { \ @@ -255,11 +265,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 { @@ -287,7 +320,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode cmsys::RegularExpression propertyNameValidator; propertyNameValidator.compile("^[A-Za-z0-9_]+$"); - cmGeneratorTarget* target = context->Target; + cmTarget* target = context->HeadTarget; std::string propertyName = *parameters.begin(); if (parameters.size() == 2) { @@ -320,7 +353,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode "Target name not supported."); return std::string(); } - target = context->Makefile->FindGeneratorTargetToUse( + target = context->Makefile->FindTargetToUse( targetName.c_str()); if (!target) @@ -355,18 +388,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> ¶meters, + cmGeneratorExpressionContext *, + const GeneratorExpressionContent *, + cmGeneratorExpressionDAGChecker *) const + { + return parameters.front(); + } + + virtual int NumExpectedParameters() const { return 1; } + +} targetNameNode; + +//---------------------------------------------------------------------------- template<bool linker, bool soname> struct TargetFilesystemArtifactResultCreator { @@ -551,13 +633,13 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier) { if (identifier == "0") return &zeroNode; - if (identifier == "1") + else if (identifier == "1") return &oneNode; - if (identifier == "AND") + else if (identifier == "AND") return &andNode; - if (identifier == "OR") + else if (identifier == "OR") return &orNode; - if (identifier == "NOT") + else if (identifier == "NOT") return ¬Node; else if (identifier == "CONFIGURATION") return &configurationNode; @@ -591,6 +673,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; } @@ -642,6 +730,20 @@ std::string GeneratorExpressionContent::Evaluate( if (!node->GeneratesContent()) { + if (node->AcceptsSingleArbitraryContentParameter()) + { + if (this->ParamChildren.empty()) + { + reportError(context, this->GetOriginalExpression(), + "$<" + identifier + "> expression requires a parameter."); + } + } + else + { + std::vector<std::string> parameters; + this->EvaluateParameters(node, identifier, context, dagChecker, + parameters); + } return std::string(); } @@ -666,6 +768,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) { @@ -673,10 +784,33 @@ 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; } std::vector<std::string> parameters; + this->EvaluateParameters(node, identifier, context, dagChecker, parameters); + if (context->HadError) + { + return std::string(); + } + + return node->Evaluate(parameters, context, this, dagChecker); +} + +//---------------------------------------------------------------------------- +std::string GeneratorExpressionContent::EvaluateParameters( + const cmGeneratorExpressionNode *node, + const std::string &identifier, + cmGeneratorExpressionContext *context, + cmGeneratorExpressionDAGChecker *dagChecker, + std::vector<std::string> ¶meters) const +{ { std::vector<std::vector<cmGeneratorExpressionEvaluator*> >::const_iterator pit = this->ParamChildren.begin(); @@ -732,10 +866,8 @@ std::string GeneratorExpressionContent::Evaluate( { reportError(context, this->GetOriginalExpression(), "$<" + identifier + "> expression requires at least one parameter."); - return std::string(); } - - return node->Evaluate(parameters, context, this, dagChecker); + return std::string(); } //---------------------------------------------------------------------------- |