summaryrefslogtreecommitdiff
path: root/Source/cmGeneratorExpressionEvaluator.cxx
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2015-03-12 15:26:45 -0400
committerCMake Topic Stage <kwrobot@kitware.com>2015-03-12 15:26:45 -0400
commit6390d5f5cb107dcc4a0bc6124ab5f17370dcadcd (patch)
tree63a42b18d2e151f28d69915cdd85955039e3999a /Source/cmGeneratorExpressionEvaluator.cxx
parent0d58b082d00b8dc0fc678911e6e3c489c0bd5a9a (diff)
parentec428fafcf9f50c54b163dd16f68063cc387f779 (diff)
downloadcmake-6390d5f5cb107dcc4a0bc6124ab5f17370dcadcd.tar.gz
Merge topic 'refactor-cmGeneratorExpression'
ec428faf Genex: Extend cmGeneratorExpressionContext constructor. 082b6a9d Genex: Split cmGeneratorExpressionContext into own file. 9df1f0fc Genex: Split cmGeneratorExpressionNode into own file. 80b9f0cb Genex: Extract an evaluateWithContext method. 642048ce Help: Move docs of $<0:...> and $<1:...> to output section.
Diffstat (limited to 'Source/cmGeneratorExpressionEvaluator.cxx')
-rw-r--r--Source/cmGeneratorExpressionEvaluator.cxx1892
1 files changed, 3 insertions, 1889 deletions
diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx
index cd0e9829a0..af94bcc695 100644
--- a/Source/cmGeneratorExpressionEvaluator.cxx
+++ b/Source/cmGeneratorExpressionEvaluator.cxx
@@ -25,1894 +25,7 @@
#include <assert.h>
#include <errno.h>
-//----------------------------------------------------------------------------
-static void reportError(cmGeneratorExpressionContext *context,
- const std::string &expr, const std::string &result)
-{
- context->HadError = true;
- if (context->Quiet)
- {
- return;
- }
-
- std::ostringstream e;
- e << "Error evaluating generator expression:\n"
- << " " << expr << "\n"
- << result;
- context->Makefile->GetCMakeInstance()
- ->IssueMessage(cmake::FATAL_ERROR, e.str(),
- context->Backtrace);
-}
-
-//----------------------------------------------------------------------------
-struct cmGeneratorExpressionNode
-{
- enum {
- DynamicParameters = 0,
- OneOrMoreParameters = -1,
- OneOrZeroParameters = -2
- };
- virtual ~cmGeneratorExpressionNode() {}
-
- virtual bool GeneratesContent() const { return true; }
-
- virtual bool RequiresLiteralInput() const { return false; }
-
- virtual bool AcceptsArbitraryContentParameter() const
- { return false; }
-
- virtual int NumExpectedParameters() const { return 1; }
-
- virtual std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *context,
- const GeneratorExpressionContent *content,
- cmGeneratorExpressionDAGChecker *dagChecker
- ) const = 0;
-
- static std::string EvaluateDependentExpression(
- std::string const& prop, cmMakefile *makefile,
- cmGeneratorExpressionContext *context,
- cmTarget const* headTarget, cmTarget const* currentTarget,
- cmGeneratorExpressionDAGChecker *dagChecker);
-};
-
-//----------------------------------------------------------------------------
-std::string cmGeneratorExpressionNode::EvaluateDependentExpression(
- std::string const& prop, cmMakefile *makefile,
- cmGeneratorExpressionContext *context,
- cmTarget const* headTarget, cmTarget const* currentTarget,
- cmGeneratorExpressionDAGChecker *dagChecker)
-{
- cmGeneratorExpression ge(&context->Backtrace);
- cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
- cge->SetEvaluateForBuildsystem(context->EvaluateForBuildsystem);
- std::string result = cge->Evaluate(makefile,
- context->Config,
- context->Quiet,
- headTarget,
- currentTarget,
- dagChecker,
- context->Language);
- if (cge->GetHadContextSensitiveCondition())
- {
- context->HadContextSensitiveCondition = true;
- }
- if (cge->GetHadHeadSensitiveCondition())
- {
- context->HadHeadSensitiveCondition = true;
- }
- return result;
-}
-
-//----------------------------------------------------------------------------
-static const struct ZeroNode : public cmGeneratorExpressionNode
-{
- ZeroNode() {}
-
- virtual bool GeneratesContent() const { return false; }
-
- virtual bool AcceptsArbitraryContentParameter() const { return true; }
-
- std::string Evaluate(const std::vector<std::string> &,
- cmGeneratorExpressionContext *,
- const GeneratorExpressionContent *,
- cmGeneratorExpressionDAGChecker *) const
- {
- return std::string();
- }
-} zeroNode;
-
-//----------------------------------------------------------------------------
-static const struct OneNode : public cmGeneratorExpressionNode
-{
- OneNode() {}
-
- virtual bool AcceptsArbitraryContentParameter() const { return true; }
-
- std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *,
- const GeneratorExpressionContent *,
- cmGeneratorExpressionDAGChecker *) const
- {
- return parameters.front();
- }
-} 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 \
-{ \
- OP ## Node () {} \
- virtual int NumExpectedParameters() const { return OneOrMoreParameters; } \
- \
- std::string Evaluate(const std::vector<std::string> &parameters, \
- cmGeneratorExpressionContext *context, \
- const GeneratorExpressionContent *content, \
- cmGeneratorExpressionDAGChecker *) const \
- { \
- std::vector<std::string>::const_iterator it = parameters.begin(); \
- const std::vector<std::string>::const_iterator end = parameters.end(); \
- for ( ; it != end; ++it) \
- { \
- if (*it == #FAILURE_VALUE) \
- { \
- return #FAILURE_VALUE; \
- } \
- else if (*it != #SUCCESS_VALUE) \
- { \
- reportError(context, content->GetOriginalExpression(), \
- "Parameters to $<" #OP "> must resolve to either '0' or '1'."); \
- return std::string(); \
- } \
- } \
- return #SUCCESS_VALUE; \
- } \
-} OPNAME;
-
-BOOLEAN_OP_NODE(andNode, AND, 1, 0)
-BOOLEAN_OP_NODE(orNode, OR, 0, 1)
-
-#undef BOOLEAN_OP_NODE
-
-//----------------------------------------------------------------------------
-static const struct NotNode : public cmGeneratorExpressionNode
-{
- NotNode() {}
-
- std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *context,
- const GeneratorExpressionContent *content,
- cmGeneratorExpressionDAGChecker *) const
- {
- if (*parameters.begin() != "0" && *parameters.begin() != "1")
- {
- reportError(context, content->GetOriginalExpression(),
- "$<NOT> parameter must resolve to exactly one '0' or '1' value.");
- return std::string();
- }
- return *parameters.begin() == "0" ? "1" : "0";
- }
-} notNode;
-
-//----------------------------------------------------------------------------
-static const struct BoolNode : public cmGeneratorExpressionNode
-{
- BoolNode() {}
-
- virtual int NumExpectedParameters() const { return 1; }
-
- std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *,
- const GeneratorExpressionContent *,
- cmGeneratorExpressionDAGChecker *) const
- {
- return !cmSystemTools::IsOff(parameters.begin()->c_str()) ? "1" : "0";
- }
-} boolNode;
-
-//----------------------------------------------------------------------------
-static const struct StrEqualNode : public cmGeneratorExpressionNode
-{
- StrEqualNode() {}
-
- virtual int NumExpectedParameters() const { return 2; }
-
- std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *,
- const GeneratorExpressionContent *,
- cmGeneratorExpressionDAGChecker *) const
- {
- return *parameters.begin() == parameters[1] ? "1" : "0";
- }
-} strEqualNode;
-
-//----------------------------------------------------------------------------
-static const struct EqualNode : public cmGeneratorExpressionNode
-{
- EqualNode() {}
-
- virtual int NumExpectedParameters() const { return 2; }
-
- std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *context,
- const GeneratorExpressionContent *content,
- cmGeneratorExpressionDAGChecker *) const
- {
- char *pEnd;
-
- int base = 0;
- bool flipSign = false;
-
- const char *lhs = parameters[0].c_str();
- if (cmHasLiteralPrefix(lhs, "0b") || cmHasLiteralPrefix(lhs, "0B"))
- {
- base = 2;
- lhs += 2;
- }
- if (cmHasLiteralPrefix(lhs, "-0b") || cmHasLiteralPrefix(lhs, "-0B"))
- {
- base = 2;
- lhs += 3;
- flipSign = true;
- }
- if (cmHasLiteralPrefix(lhs, "+0b") || cmHasLiteralPrefix(lhs, "+0B"))
- {
- base = 2;
- lhs += 3;
- }
-
- long lnum = strtol(lhs, &pEnd, base);
- if (pEnd == lhs || *pEnd != '\0' || errno == ERANGE)
- {
- reportError(context, content->GetOriginalExpression(),
- "$<EQUAL> parameter " + parameters[0] + " is not a valid integer.");
- return std::string();
- }
-
- if (flipSign)
- {
- lnum = -lnum;
- }
-
- base = 0;
- flipSign = false;
-
- const char *rhs = parameters[1].c_str();
- if (cmHasLiteralPrefix(rhs, "0b") || cmHasLiteralPrefix(rhs, "0B"))
- {
- base = 2;
- rhs += 2;
- }
- if (cmHasLiteralPrefix(rhs, "-0b") || cmHasLiteralPrefix(rhs, "-0B"))
- {
- base = 2;
- rhs += 3;
- flipSign = true;
- }
- if (cmHasLiteralPrefix(rhs, "+0b") || cmHasLiteralPrefix(rhs, "+0B"))
- {
- base = 2;
- rhs += 3;
- }
-
- long rnum = strtol(rhs, &pEnd, base);
- if (pEnd == rhs || *pEnd != '\0' || errno == ERANGE)
- {
- reportError(context, content->GetOriginalExpression(),
- "$<EQUAL> parameter " + parameters[1] + " is not a valid integer.");
- return std::string();
- }
-
- if (flipSign)
- {
- rnum = -rnum;
- }
-
- return lnum == rnum ? "1" : "0";
- }
-} equalNode;
-
-//----------------------------------------------------------------------------
-static const struct LowerCaseNode : public cmGeneratorExpressionNode
-{
- LowerCaseNode() {}
-
- bool AcceptsArbitraryContentParameter() const { return true; }
-
- std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *,
- const GeneratorExpressionContent *,
- cmGeneratorExpressionDAGChecker *) const
- {
- return cmSystemTools::LowerCase(parameters.front());
- }
-} lowerCaseNode;
-
-//----------------------------------------------------------------------------
-static const struct UpperCaseNode : public cmGeneratorExpressionNode
-{
- UpperCaseNode() {}
-
- bool AcceptsArbitraryContentParameter() const { return true; }
-
- std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *,
- const GeneratorExpressionContent *,
- cmGeneratorExpressionDAGChecker *) const
- {
- return cmSystemTools::UpperCase(parameters.front());
- }
-} upperCaseNode;
-
-//----------------------------------------------------------------------------
-static const struct MakeCIdentifierNode : public cmGeneratorExpressionNode
-{
- MakeCIdentifierNode() {}
-
- bool AcceptsArbitraryContentParameter() const { return true; }
-
- std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *,
- const GeneratorExpressionContent *,
- cmGeneratorExpressionDAGChecker *) const
- {
- return cmSystemTools::MakeCidentifier(parameters.front());
- }
-} makeCIdentifierNode;
-
-//----------------------------------------------------------------------------
-static const struct Angle_RNode : public cmGeneratorExpressionNode
-{
- Angle_RNode() {}
-
- virtual int NumExpectedParameters() const { return 0; }
-
- std::string Evaluate(const std::vector<std::string> &,
- cmGeneratorExpressionContext *,
- const GeneratorExpressionContent *,
- cmGeneratorExpressionDAGChecker *) const
- {
- return ">";
- }
-} angle_rNode;
-
-//----------------------------------------------------------------------------
-static const struct CommaNode : public cmGeneratorExpressionNode
-{
- CommaNode() {}
-
- virtual int NumExpectedParameters() const { return 0; }
-
- std::string Evaluate(const std::vector<std::string> &,
- cmGeneratorExpressionContext *,
- const GeneratorExpressionContent *,
- cmGeneratorExpressionDAGChecker *) const
- {
- return ",";
- }
-} commaNode;
-
-//----------------------------------------------------------------------------
-static const struct SemicolonNode : public cmGeneratorExpressionNode
-{
- SemicolonNode() {}
-
- virtual int NumExpectedParameters() const { return 0; }
-
- std::string Evaluate(const std::vector<std::string> &,
- cmGeneratorExpressionContext *,
- const GeneratorExpressionContent *,
- cmGeneratorExpressionDAGChecker *) const
- {
- return ";";
- }
-} semicolonNode;
-
-//----------------------------------------------------------------------------
-struct CompilerIdNode : public cmGeneratorExpressionNode
-{
- CompilerIdNode() {}
-
- virtual int NumExpectedParameters() const { return OneOrZeroParameters; }
-
- std::string EvaluateWithLanguage(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *context,
- const GeneratorExpressionContent *content,
- cmGeneratorExpressionDAGChecker *,
- const std::string &lang) const
- {
- const char *compilerId =
- context->Makefile->GetSafeDefinition("CMAKE_" + lang + "_COMPILER_ID");
- if (parameters.empty())
- {
- return compilerId ? compilerId : "";
- }
- static cmsys::RegularExpression compilerIdValidator("^[A-Za-z0-9_]*$");
- if (!compilerIdValidator.find(*parameters.begin()))
- {
- reportError(context, content->GetOriginalExpression(),
- "Expression syntax not recognized.");
- return std::string();
- }
- if (!compilerId)
- {
- return parameters.front().empty() ? "1" : "0";
- }
-
- if (strcmp(parameters.begin()->c_str(), compilerId) == 0)
- {
- return "1";
- }
-
- if (cmsysString_strcasecmp(parameters.begin()->c_str(), compilerId) == 0)
- {
- switch(context->Makefile->GetPolicyStatus(cmPolicies::CMP0044))
- {
- case cmPolicies::WARN:
- {
- std::ostringstream e;
- e << context->Makefile->GetPolicies()
- ->GetPolicyWarning(cmPolicies::CMP0044);
- context->Makefile->GetCMakeInstance()
- ->IssueMessage(cmake::AUTHOR_WARNING,
- e.str(), context->Backtrace);
- }
- case cmPolicies::OLD:
- return "1";
- case cmPolicies::NEW:
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::REQUIRED_IF_USED:
- break;
- }
- }
- return "0";
- }
-};
-
-//----------------------------------------------------------------------------
-static const struct CCompilerIdNode : public CompilerIdNode
-{
- CCompilerIdNode() {}
-
- std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *context,
- const GeneratorExpressionContent *content,
- cmGeneratorExpressionDAGChecker *dagChecker) const
- {
- if (!context->HeadTarget)
- {
- reportError(context, content->GetOriginalExpression(),
- "$<C_COMPILER_ID> may only be used with binary targets. It may "
- "not be used with add_custom_command or add_custom_target.");
- return std::string();
- }
- return this->EvaluateWithLanguage(parameters, context, content,
- dagChecker, "C");
- }
-} cCompilerIdNode;
-
-//----------------------------------------------------------------------------
-static const struct CXXCompilerIdNode : public CompilerIdNode
-{
- CXXCompilerIdNode() {}
-
- std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *context,
- const GeneratorExpressionContent *content,
- cmGeneratorExpressionDAGChecker *dagChecker) const
- {
- if (!context->HeadTarget)
- {
- reportError(context, content->GetOriginalExpression(),
- "$<CXX_COMPILER_ID> may only be used with binary targets. It may "
- "not be used with add_custom_command or add_custom_target.");
- return std::string();
- }
- return this->EvaluateWithLanguage(parameters, context, content,
- dagChecker, "CXX");
- }
-} cxxCompilerIdNode;
-
-//----------------------------------------------------------------------------
-struct CompilerVersionNode : public cmGeneratorExpressionNode
-{
- CompilerVersionNode() {}
-
- virtual int NumExpectedParameters() const { return OneOrZeroParameters; }
-
- std::string EvaluateWithLanguage(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *context,
- const GeneratorExpressionContent *content,
- cmGeneratorExpressionDAGChecker *,
- const std::string &lang) const
- {
- const char *compilerVersion = context->Makefile->GetSafeDefinition(
- "CMAKE_" + lang + "_COMPILER_VERSION");
- if (parameters.empty())
- {
- return compilerVersion ? compilerVersion : "";
- }
-
- static cmsys::RegularExpression compilerIdValidator("^[0-9\\.]*$");
- if (!compilerIdValidator.find(*parameters.begin()))
- {
- reportError(context, content->GetOriginalExpression(),
- "Expression syntax not recognized.");
- return std::string();
- }
- if (!compilerVersion)
- {
- return parameters.front().empty() ? "1" : "0";
- }
-
- return cmSystemTools::VersionCompare(cmSystemTools::OP_EQUAL,
- parameters.begin()->c_str(),
- compilerVersion) ? "1" : "0";
- }
-};
-
-//----------------------------------------------------------------------------
-static const struct CCompilerVersionNode : public CompilerVersionNode
-{
- CCompilerVersionNode() {}
-
- std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *context,
- const GeneratorExpressionContent *content,
- cmGeneratorExpressionDAGChecker *dagChecker) const
- {
- if (!context->HeadTarget)
- {
- reportError(context, content->GetOriginalExpression(),
- "$<C_COMPILER_VERSION> may only be used with binary targets. It "
- "may not be used with add_custom_command or add_custom_target.");
- return std::string();
- }
- return this->EvaluateWithLanguage(parameters, context, content,
- dagChecker, "C");
- }
-} cCompilerVersionNode;
-
-//----------------------------------------------------------------------------
-static const struct CxxCompilerVersionNode : public CompilerVersionNode
-{
- CxxCompilerVersionNode() {}
-
- std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *context,
- const GeneratorExpressionContent *content,
- cmGeneratorExpressionDAGChecker *dagChecker) const
- {
- if (!context->HeadTarget)
- {
- reportError(context, content->GetOriginalExpression(),
- "$<CXX_COMPILER_VERSION> may only be used with binary targets. It "
- "may not be used with add_custom_command or add_custom_target.");
- return std::string();
- }
- return this->EvaluateWithLanguage(parameters, context, content,
- dagChecker, "CXX");
- }
-} cxxCompilerVersionNode;
-
-
-//----------------------------------------------------------------------------
-struct PlatformIdNode : public cmGeneratorExpressionNode
-{
- PlatformIdNode() {}
-
- virtual int NumExpectedParameters() const { return OneOrZeroParameters; }
-
- std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *context,
- const GeneratorExpressionContent *,
- cmGeneratorExpressionDAGChecker *) const
- {
- const char *platformId =
- context->Makefile->GetSafeDefinition("CMAKE_SYSTEM_NAME");
- if (parameters.empty())
- {
- return platformId ? platformId : "";
- }
-
- if (!platformId)
- {
- return parameters.front().empty() ? "1" : "0";
- }
-
- if (strcmp(parameters.begin()->c_str(), platformId) == 0)
- {
- return "1";
- }
- return "0";
- }
-} platformIdNode;
-
-//----------------------------------------------------------------------------
-static const struct VersionGreaterNode : public cmGeneratorExpressionNode
-{
- VersionGreaterNode() {}
-
- virtual int NumExpectedParameters() const { return 2; }
-
- std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *,
- const GeneratorExpressionContent *,
- cmGeneratorExpressionDAGChecker *) const
- {
- return cmSystemTools::VersionCompare(cmSystemTools::OP_GREATER,
- parameters.front().c_str(),
- parameters[1].c_str()) ? "1" : "0";
- }
-} versionGreaterNode;
-
-//----------------------------------------------------------------------------
-static const struct VersionLessNode : public cmGeneratorExpressionNode
-{
- VersionLessNode() {}
-
- virtual int NumExpectedParameters() const { return 2; }
-
- std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *,
- const GeneratorExpressionContent *,
- cmGeneratorExpressionDAGChecker *) const
- {
- return cmSystemTools::VersionCompare(cmSystemTools::OP_LESS,
- parameters.front().c_str(),
- parameters[1].c_str()) ? "1" : "0";
- }
-} versionLessNode;
-
-//----------------------------------------------------------------------------
-static const struct VersionEqualNode : public cmGeneratorExpressionNode
-{
- VersionEqualNode() {}
-
- virtual int NumExpectedParameters() const { return 2; }
-
- std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *,
- const GeneratorExpressionContent *,
- cmGeneratorExpressionDAGChecker *) const
- {
- return cmSystemTools::VersionCompare(cmSystemTools::OP_EQUAL,
- parameters.front().c_str(),
- parameters[1].c_str()) ? "1" : "0";
- }
-} versionEqualNode;
-
-//----------------------------------------------------------------------------
-static const struct LinkOnlyNode : public cmGeneratorExpressionNode
-{
- LinkOnlyNode() {}
-
- std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *,
- const GeneratorExpressionContent *,
- cmGeneratorExpressionDAGChecker *dagChecker) const
- {
- if(!dagChecker->GetTransitivePropertiesOnly())
- {
- return parameters.front();
- }
- return "";
- }
-} linkOnlyNode;
-
-//----------------------------------------------------------------------------
-static const struct ConfigurationNode : public cmGeneratorExpressionNode
-{
- ConfigurationNode() {}
-
- virtual int NumExpectedParameters() const { return 0; }
-
- std::string Evaluate(const std::vector<std::string> &,
- cmGeneratorExpressionContext *context,
- const GeneratorExpressionContent *,
- cmGeneratorExpressionDAGChecker *) const
- {
- context->HadContextSensitiveCondition = true;
- return context->Config;
- }
-} configurationNode;
-
-//----------------------------------------------------------------------------
-static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
-{
- ConfigurationTestNode() {}
-
- virtual int NumExpectedParameters() const { return OneOrZeroParameters; }
-
- std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *context,
- const GeneratorExpressionContent *content,
- cmGeneratorExpressionDAGChecker *) const
- {
- if (parameters.empty())
- {
- return configurationNode.Evaluate(parameters, context, content, 0);
- }
- static cmsys::RegularExpression configValidator("^[A-Za-z0-9_]*$");
- if (!configValidator.find(*parameters.begin()))
- {
- reportError(context, content->GetOriginalExpression(),
- "Expression syntax not recognized.");
- return std::string();
- }
- context->HadContextSensitiveCondition = true;
- if (context->Config.empty())
- {
- return parameters.front().empty() ? "1" : "0";
- }
-
- if (cmsysString_strcasecmp(parameters.begin()->c_str(),
- context->Config.c_str()) == 0)
- {
- return "1";
- }
-
- if (context->CurrentTarget
- && context->CurrentTarget->IsImported())
- {
- const char* loc = 0;
- const char* imp = 0;
- std::string suffix;
- if (context->CurrentTarget->GetMappedConfig(context->Config,
- &loc,
- &imp,
- suffix))
- {
- // This imported target has an appropriate location
- // for this (possibly mapped) config.
- // Check if there is a proper config mapping for the tested config.
- std::vector<std::string> mappedConfigs;
- std::string mapProp = "MAP_IMPORTED_CONFIG_";
- mapProp += cmSystemTools::UpperCase(context->Config);
- if(const char* mapValue =
- context->CurrentTarget->GetProperty(mapProp))
- {
- cmSystemTools::ExpandListArgument(cmSystemTools::UpperCase(mapValue),
- mappedConfigs);
- return std::find(mappedConfigs.begin(), mappedConfigs.end(),
- cmSystemTools::UpperCase(parameters.front()))
- != mappedConfigs.end() ? "1" : "0";
- }
- }
- }
- return "0";
- }
-} configurationTestNode;
-
-static const struct JoinNode : public cmGeneratorExpressionNode
-{
- JoinNode() {}
-
- virtual int NumExpectedParameters() const { return 2; }
-
- virtual bool AcceptsArbitraryContentParameter() const { return true; }
-
- std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *,
- const GeneratorExpressionContent *,
- cmGeneratorExpressionDAGChecker *) const
- {
- std::vector<std::string> list;
- cmSystemTools::ExpandListArgument(parameters.front(), list);
- return cmJoin(list, parameters[1]);
- }
-} joinNode;
-
-static const struct CompileLanguageNode : public cmGeneratorExpressionNode
-{
- CompileLanguageNode() {}
-
- virtual int NumExpectedParameters() const { return OneOrZeroParameters; }
-
- std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *context,
- const GeneratorExpressionContent *content,
- cmGeneratorExpressionDAGChecker *dagChecker) const
- {
- if(context->Language.empty())
- {
- reportError(context, content->GetOriginalExpression(),
- "$<COMPILE_LANGUAGE:...> may only be used to specify include "
- "directories compile definitions, compile options and to evaluate "
- "components of the file(GENERATE) command.");
- return std::string();
- }
-
- std::vector<std::string> enabledLanguages;
- cmGlobalGenerator* gg
- = context->Makefile->GetLocalGenerator()->GetGlobalGenerator();
- gg->GetEnabledLanguages(enabledLanguages);
- if (!parameters.empty() &&
- std::find(enabledLanguages.begin(), enabledLanguages.end(),
- parameters.front()) == enabledLanguages.end())
- {
- reportError(context, content->GetOriginalExpression(),
- "$<COMPILE_LANGUAGE:...> Unknown language.");
- return std::string();
- }
-
- std::string genName = gg->GetName();
- if (genName.find("Visual Studio") != std::string::npos)
- {
- reportError(context, content->GetOriginalExpression(),
- "$<COMPILE_LANGUAGE:...> may not be used with Visual Studio "
- "generators.");
- return std::string();
- }
- else if (genName.find("Xcode") != std::string::npos)
- {
- if (dagChecker && (dagChecker->EvaluatingCompileDefinitions()
- || dagChecker->EvaluatingIncludeDirectories()))
- {
- reportError(context, content->GetOriginalExpression(),
- "$<COMPILE_LANGUAGE:...> may only be used with COMPILE_OPTIONS "
- "with the Xcode generator.");
- return std::string();
- }
- }
- else
- {
- if(genName.find("Makefiles") == std::string::npos &&
- genName.find("Ninja") == std::string::npos &&
- genName.find("Watcom WMake") == std::string::npos)
- {
- reportError(context, content->GetOriginalExpression(),
- "$<COMPILE_LANGUAGE:...> not supported for this generator.");
- return std::string();
- }
- }
- if (parameters.empty())
- {
- return context->Language;
- }
- return context->Language == parameters.front() ? "1" : "0";
- }
-} languageNode;
-
-#define TRANSITIVE_PROPERTY_NAME(PROPERTY) \
- , "INTERFACE_" #PROPERTY
-
-//----------------------------------------------------------------------------
-static const char* targetPropertyTransitiveWhitelist[] = {
- 0
- CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(TRANSITIVE_PROPERTY_NAME)
-};
-
-#undef TRANSITIVE_PROPERTY_NAME
-
-template <typename T>
-std::string
-getLinkedTargetsContent(
- std::vector<T> const &libraries,
- cmTarget const* target,
- cmTarget const* headTarget,
- cmGeneratorExpressionContext *context,
- cmGeneratorExpressionDAGChecker *dagChecker,
- const std::string &interfacePropertyName)
-{
- std::string linkedTargetsContent;
- std::string sep;
- std::string depString;
- for (typename std::vector<T>::const_iterator it = libraries.begin();
- it != libraries.end(); ++it)
- {
- // Broken code can have a target in its own link interface.
- // Don't follow such link interface entries so as not to create a
- // self-referencing loop.
- if (it->Target && it->Target != target)
- {
- depString +=
- sep + "$<TARGET_PROPERTY:" +
- it->Target->GetName() + "," + interfacePropertyName + ">";
- sep = ";";
- }
- }
- if(!depString.empty())
- {
- linkedTargetsContent =
- cmGeneratorExpressionNode::EvaluateDependentExpression(depString,
- target->GetMakefile(), context,
- headTarget, target, dagChecker);
- }
- linkedTargetsContent =
- cmGeneratorExpression::StripEmptyListElements(linkedTargetsContent);
- return linkedTargetsContent;
-}
-
-//----------------------------------------------------------------------------
-static const struct TargetPropertyNode : public cmGeneratorExpressionNode
-{
- TargetPropertyNode() {}
-
- // This node handles errors on parameter count itself.
- virtual int NumExpectedParameters() const { return OneOrMoreParameters; }
-
- std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *context,
- const GeneratorExpressionContent *content,
- cmGeneratorExpressionDAGChecker *dagCheckerParent
- ) const
- {
- if (parameters.size() != 1 && parameters.size() != 2)
- {
- reportError(context, content->GetOriginalExpression(),
- "$<TARGET_PROPERTY:...> expression requires one or two parameters");
- return std::string();
- }
- static cmsys::RegularExpression propertyNameValidator("^[A-Za-z0-9_]+$");
-
- cmTarget const* target = context->HeadTarget;
- std::string propertyName = *parameters.begin();
-
- if (parameters.size() == 1)
- {
- context->HadHeadSensitiveCondition = true;
- }
- if (!target && parameters.size() == 1)
- {
- reportError(context, content->GetOriginalExpression(),
- "$<TARGET_PROPERTY:prop> may only be used with binary targets. "
- "It may not be used with add_custom_command or add_custom_target. "
- "Specify the target to read a property from using the "
- "$<TARGET_PROPERTY:tgt,prop> signature instead.");
- return std::string();
- }
-
- if (parameters.size() == 2)
- {
- if (parameters.begin()->empty() && parameters[1].empty())
- {
- reportError(context, content->GetOriginalExpression(),
- "$<TARGET_PROPERTY:tgt,prop> expression requires a non-empty "
- "target name and property name.");
- return std::string();
- }
- if (parameters.begin()->empty())
- {
- reportError(context, content->GetOriginalExpression(),
- "$<TARGET_PROPERTY:tgt,prop> expression requires a non-empty "
- "target name.");
- return std::string();
- }
-
- std::string targetName = parameters.front();
- propertyName = parameters[1];
- if (!cmGeneratorExpression::IsValidTargetName(targetName))
- {
- if (!propertyNameValidator.find(propertyName.c_str()))
- {
- ::reportError(context, content->GetOriginalExpression(),
- "Target name and property name not supported.");
- return std::string();
- }
- ::reportError(context, content->GetOriginalExpression(),
- "Target name not supported.");
- return std::string();
- }
- if(propertyName == "ALIASED_TARGET")
- {
- if(context->Makefile->IsAlias(targetName))
- {
- if(cmTarget* tgt = context->Makefile->FindTargetToUse(targetName))
- {
- return tgt->GetName();
- }
- }
- return "";
- }
- target = context->Makefile->FindTargetToUse(targetName);
-
- if (!target)
- {
- std::ostringstream e;
- e << "Target \""
- << targetName
- << "\" not found.";
- reportError(context, content->GetOriginalExpression(), e.str());
- return std::string();
- }
- context->AllTargets.insert(target);
- }
-
- if (target == context->HeadTarget)
- {
- // Keep track of the properties seen while processing.
- // The evaluation of the LINK_LIBRARIES generator expressions
- // will check this to ensure that properties have one consistent
- // value for all evaluations.
- context->SeenTargetProperties.insert(propertyName);
- }
- if (propertyName == "SOURCES")
- {
- context->SourceSensitiveTargets.insert(target);
- }
-
- if (propertyName.empty())
- {
- reportError(context, content->GetOriginalExpression(),
- "$<TARGET_PROPERTY:...> expression requires a non-empty property "
- "name.");
- return std::string();
- }
-
- if (!propertyNameValidator.find(propertyName))
- {
- ::reportError(context, content->GetOriginalExpression(),
- "Property name not supported.");
- return std::string();
- }
-
- assert(target);
-
- if (propertyName == "LINKER_LANGUAGE")
- {
- if (target->LinkLanguagePropagatesToDependents() &&
- dagCheckerParent && (dagCheckerParent->EvaluatingLinkLibraries()
- || dagCheckerParent->EvaluatingSources()))
- {
- reportError(context, content->GetOriginalExpression(),
- "LINKER_LANGUAGE target property can not be used while evaluating "
- "link libraries for a static library");
- return std::string();
- }
- return target->GetLinkerLanguage(context->Config);
- }
-
- cmGeneratorExpressionDAGChecker dagChecker(context->Backtrace,
- target->GetName(),
- propertyName,
- content,
- dagCheckerParent);
-
- 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::ALREADY_SEEN:
- for (size_t i = 1;
- i < cmArraySize(targetPropertyTransitiveWhitelist);
- ++i)
- {
- if (targetPropertyTransitiveWhitelist[i] == propertyName)
- {
- // No error. We're not going to find anything new here.
- return std::string();
- }
- }
- case cmGeneratorExpressionDAGChecker::DAG:
- break;
- }
-
- const char *prop = target->GetProperty(propertyName);
-
- if (dagCheckerParent)
- {
- if (dagCheckerParent->EvaluatingLinkLibraries())
- {
-#define TRANSITIVE_PROPERTY_COMPARE(PROPERTY) \
- (#PROPERTY == propertyName || "INTERFACE_" #PROPERTY == propertyName) ||
- if (CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(TRANSITIVE_PROPERTY_COMPARE)
- false)
- {
- reportError(context, content->GetOriginalExpression(),
- "$<TARGET_PROPERTY:...> expression in link libraries "
- "evaluation depends on target property which is transitive "
- "over the link libraries, creating a recursion.");
- return std::string();
- }
-#undef TRANSITIVE_PROPERTY_COMPARE
-
- if(!prop)
- {
- return std::string();
- }
- }
- else
- {
-#define ASSERT_TRANSITIVE_PROPERTY_METHOD(METHOD) \
- dagCheckerParent->METHOD () ||
-
- assert(
- CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(
- ASSERT_TRANSITIVE_PROPERTY_METHOD)
- false);
-#undef ASSERT_TRANSITIVE_PROPERTY_METHOD
- }
- }
-
- std::string linkedTargetsContent;
-
- std::string interfacePropertyName;
- bool isInterfaceProperty = false;
-
-#define POPULATE_INTERFACE_PROPERTY_NAME(prop) \
- if (propertyName == #prop) \
- { \
- interfacePropertyName = "INTERFACE_" #prop; \
- } \
- else if (propertyName == "INTERFACE_" #prop) \
- { \
- interfacePropertyName = "INTERFACE_" #prop; \
- isInterfaceProperty = true; \
- } \
- else
-
- CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(POPULATE_INTERFACE_PROPERTY_NAME)
- // Note that the above macro terminates with an else
- /* else */ if (cmHasLiteralPrefix(propertyName.c_str(),
- "COMPILE_DEFINITIONS_"))
- {
- cmPolicies::PolicyStatus polSt =
- context->Makefile->GetPolicyStatus(cmPolicies::CMP0043);
- if (polSt == cmPolicies::WARN || polSt == cmPolicies::OLD)
- {
- interfacePropertyName = "INTERFACE_COMPILE_DEFINITIONS";
- }
- }
-#undef POPULATE_INTERFACE_PROPERTY_NAME
- cmTarget const* headTarget = context->HeadTarget && isInterfaceProperty
- ? context->HeadTarget : target;
-
- if(isInterfaceProperty)
- {
- if(cmTarget::LinkInterfaceLibraries const* iface =
- target->GetLinkInterfaceLibraries(context->Config, headTarget, true))
- {
- linkedTargetsContent =
- getLinkedTargetsContent(iface->Libraries, target,
- headTarget,
- context, &dagChecker,
- interfacePropertyName);
- }
- }
- else if(!interfacePropertyName.empty())
- {
- if(cmTarget::LinkImplementationLibraries const* impl =
- target->GetLinkImplementationLibraries(context->Config))
- {
- linkedTargetsContent =
- getLinkedTargetsContent(impl->Libraries, target,
- target,
- context, &dagChecker,
- interfacePropertyName);
- }
- }
-
- if (!prop)
- {
- if (target->IsImported()
- || target->GetType() == cmTarget::INTERFACE_LIBRARY)
- {
- return linkedTargetsContent;
- }
- if (target->IsLinkInterfaceDependentBoolProperty(propertyName,
- context->Config))
- {
- context->HadContextSensitiveCondition = true;
- return target->GetLinkInterfaceDependentBoolProperty(
- propertyName,
- context->Config) ? "1" : "0";
- }
- if (target->IsLinkInterfaceDependentStringProperty(propertyName,
- context->Config))
- {
- context->HadContextSensitiveCondition = true;
- const char *propContent =
- target->GetLinkInterfaceDependentStringProperty(
- propertyName,
- context->Config);
- return propContent ? propContent : "";
- }
- if (target->IsLinkInterfaceDependentNumberMinProperty(propertyName,
- context->Config))
- {
- context->HadContextSensitiveCondition = true;
- const char *propContent =
- target->GetLinkInterfaceDependentNumberMinProperty(
- propertyName,
- context->Config);
- return propContent ? propContent : "";
- }
- if (target->IsLinkInterfaceDependentNumberMaxProperty(propertyName,
- context->Config))
- {
- context->HadContextSensitiveCondition = true;
- const char *propContent =
- target->GetLinkInterfaceDependentNumberMaxProperty(
- propertyName,
- context->Config);
- return propContent ? propContent : "";
- }
-
- return linkedTargetsContent;
- }
-
- if (!target->IsImported()
- && dagCheckerParent && !dagCheckerParent->EvaluatingLinkLibraries())
- {
- if (target->IsLinkInterfaceDependentNumberMinProperty(propertyName,
- context->Config))
- {
- context->HadContextSensitiveCondition = true;
- const char *propContent =
- target->GetLinkInterfaceDependentNumberMinProperty(
- propertyName,
- context->Config);
- return propContent ? propContent : "";
- }
- if (target->IsLinkInterfaceDependentNumberMaxProperty(propertyName,
- context->Config))
- {
- context->HadContextSensitiveCondition = true;
- const char *propContent =
- target->GetLinkInterfaceDependentNumberMaxProperty(
- propertyName,
- context->Config);
- return propContent ? propContent : "";
- }
- }
- if(!interfacePropertyName.empty())
- {
- std::string result = this->EvaluateDependentExpression(prop,
- context->Makefile, context,
- headTarget, target, &dagChecker);
- if (!linkedTargetsContent.empty())
- {
- result += (result.empty() ? "" : ";") + linkedTargetsContent;
- }
- return result;
- }
- return prop;
- }
-} targetPropertyNode;
-
-//----------------------------------------------------------------------------
-static const struct TargetNameNode : public cmGeneratorExpressionNode
-{
- TargetNameNode() {}
-
- virtual bool GeneratesContent() const { return true; }
-
- virtual bool AcceptsArbitraryContentParameter() 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;
-
-//----------------------------------------------------------------------------
-static const struct TargetObjectsNode : public cmGeneratorExpressionNode
-{
- TargetObjectsNode() {}
-
- std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *context,
- const GeneratorExpressionContent *content,
- cmGeneratorExpressionDAGChecker *) const
- {
- if (!context->EvaluateForBuildsystem)
- {
- std::ostringstream e;
- e << "The evaluation of the TARGET_OBJECTS generator expression "
- "is only suitable for consumption by CMake. It is not suitable "
- "for writing out elsewhere.";
- reportError(context, content->GetOriginalExpression(), e.str());
- return std::string();
- }
-
- std::string tgtName = parameters.front();
- cmGeneratorTarget* gt =
- context->Makefile->FindGeneratorTargetToUse(tgtName);
- if (!gt)
- {
- std::ostringstream e;
- e << "Objects of target \"" << tgtName
- << "\" referenced but no such target exists.";
- reportError(context, content->GetOriginalExpression(), e.str());
- return std::string();
- }
- if (gt->GetType() != cmTarget::OBJECT_LIBRARY)
- {
- std::ostringstream e;
- e << "Objects of target \"" << tgtName
- << "\" referenced but is not an OBJECT library.";
- reportError(context, content->GetOriginalExpression(), e.str());
- return std::string();
- }
-
- std::vector<cmSourceFile const*> objectSources;
- gt->GetObjectSources(objectSources, context->Config);
- std::map<cmSourceFile const*, std::string> mapping;
-
- for(std::vector<cmSourceFile const*>::const_iterator it
- = objectSources.begin(); it != objectSources.end(); ++it)
- {
- mapping[*it];
- }
-
- gt->LocalGenerator->ComputeObjectFilenames(mapping, gt);
-
- std::string obj_dir = gt->ObjectDirectory;
- std::string result;
- const char* sep = "";
- for(std::vector<cmSourceFile const*>::const_iterator it
- = objectSources.begin(); it != objectSources.end(); ++it)
- {
- // Find the object file name corresponding to this source file.
- std::map<cmSourceFile const*, std::string>::const_iterator
- map_it = mapping.find(*it);
- // It must exist because we populated the mapping just above.
- assert(!map_it->second.empty());
- result += sep;
- std::string objFile = obj_dir + map_it->second;
- cmSourceFile* sf = context->Makefile->GetOrCreateSource(objFile, true);
- sf->SetObjectLibrary(tgtName);
- sf->SetProperty("EXTERNAL_OBJECT", "1");
- result += objFile;
- sep = ";";
- }
- return result;
- }
-} targetObjectsNode;
-
-//----------------------------------------------------------------------------
-static const struct CompileFeaturesNode : public cmGeneratorExpressionNode
-{
- CompileFeaturesNode() {}
-
- virtual int NumExpectedParameters() const { return OneOrMoreParameters; }
-
- std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *context,
- const GeneratorExpressionContent *content,
- cmGeneratorExpressionDAGChecker *dagChecker) const
- {
- cmTarget const* target = context->HeadTarget;
- if (!target)
- {
- reportError(context, content->GetOriginalExpression(),
- "$<COMPILE_FEATURE> may only be used with binary targets. It may "
- "not be used with add_custom_command or add_custom_target.");
- return std::string();
- }
- context->HadHeadSensitiveCondition = true;
-
- typedef std::map<std::string, std::vector<std::string> > LangMap;
- static LangMap availableFeatures;
-
- LangMap testedFeatures;
-
- for (std::vector<std::string>::const_iterator it = parameters.begin();
- it != parameters.end(); ++it)
- {
- std::string error;
- std::string lang;
- if (!context->Makefile->CompileFeatureKnown(context->HeadTarget,
- *it, lang, &error))
- {
- reportError(context, content->GetOriginalExpression(), error);
- return std::string();
- }
- testedFeatures[lang].push_back(*it);
-
- if (availableFeatures.find(lang) == availableFeatures.end())
- {
- const char* featuresKnown
- = context->Makefile->CompileFeaturesAvailable(lang, &error);
- if (!featuresKnown)
- {
- reportError(context, content->GetOriginalExpression(), error);
- return std::string();
- }
- cmSystemTools::ExpandListArgument(featuresKnown,
- availableFeatures[lang]);
- }
- }
-
- bool evalLL = dagChecker && dagChecker->EvaluatingLinkLibraries();
-
- std::string result;
-
- for (LangMap::const_iterator lit = testedFeatures.begin();
- lit != testedFeatures.end(); ++lit)
- {
- std::vector<std::string> const& langAvailable
- = availableFeatures[lit->first];
- const char* standardDefault = context->Makefile
- ->GetDefinition("CMAKE_" + lit->first + "_STANDARD_DEFAULT");
- for (std::vector<std::string>::const_iterator it = lit->second.begin();
- it != lit->second.end(); ++it)
- {
- if (std::find(langAvailable.begin(), langAvailable.end(), *it)
- == langAvailable.end())
- {
- return "0";
- }
- if (standardDefault && !*standardDefault)
- {
- // This compiler has no notion of language standard levels.
- // All features known for the language are always available.
- continue;
- }
- if (!context->Makefile->HaveStandardAvailable(target,
- lit->first, *it))
- {
- if (evalLL)
- {
- const char* l = target->GetProperty(lit->first + "_STANDARD");
- if (!l)
- {
- l = standardDefault;
- }
- assert(l);
- context->MaxLanguageStandard[target][lit->first] = l;
- }
- else
- {
- return "0";
- }
- }
- }
- }
- return "1";
- }
-} compileFeaturesNode;
-
-//----------------------------------------------------------------------------
-static const char* targetPolicyWhitelist[] = {
- 0
-#define TARGET_POLICY_STRING(POLICY) \
- , #POLICY
-
- CM_FOR_EACH_TARGET_POLICY(TARGET_POLICY_STRING)
-
-#undef TARGET_POLICY_STRING
-};
-
-cmPolicies::PolicyStatus statusForTarget(cmTarget const* tgt,
- const char *policy)
-{
-#define RETURN_POLICY(POLICY) \
- if (strcmp(policy, #POLICY) == 0) \
- { \
- return tgt->GetPolicyStatus ## POLICY (); \
- } \
-
- CM_FOR_EACH_TARGET_POLICY(RETURN_POLICY)
-
-#undef RETURN_POLICY
-
- assert(0 && "Unreachable code. Not a valid policy");
- return cmPolicies::WARN;
-}
-
-cmPolicies::PolicyID policyForString(const char *policy_id)
-{
-#define RETURN_POLICY_ID(POLICY_ID) \
- if (strcmp(policy_id, #POLICY_ID) == 0) \
- { \
- return cmPolicies:: POLICY_ID; \
- } \
-
- CM_FOR_EACH_TARGET_POLICY(RETURN_POLICY_ID)
-
-#undef RETURN_POLICY_ID
-
- assert(0 && "Unreachable code. Not a valid policy");
- return cmPolicies::CMP0002;
-}
-
-//----------------------------------------------------------------------------
-static const struct TargetPolicyNode : public cmGeneratorExpressionNode
-{
- TargetPolicyNode() {}
-
- virtual int NumExpectedParameters() const { return 1; }
-
- std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *context ,
- const GeneratorExpressionContent *content,
- cmGeneratorExpressionDAGChecker *) const
- {
- if (!context->HeadTarget)
- {
- reportError(context, content->GetOriginalExpression(),
- "$<TARGET_POLICY:prop> may only be used with binary targets. It "
- "may not be used with add_custom_command or add_custom_target.");
- return std::string();
- }
-
- context->HadContextSensitiveCondition = true;
- context->HadHeadSensitiveCondition = true;
-
- for (size_t i = 1; i < cmArraySize(targetPolicyWhitelist); ++i)
- {
- const char *policy = targetPolicyWhitelist[i];
- if (parameters.front() == policy)
- {
- cmMakefile *mf = context->HeadTarget->GetMakefile();
- switch(statusForTarget(context->HeadTarget, policy))
- {
- case cmPolicies::WARN:
- mf->IssueMessage(cmake::AUTHOR_WARNING,
- mf->GetPolicies()->
- GetPolicyWarning(policyForString(policy)));
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::OLD:
- return "0";
- case cmPolicies::NEW:
- return "1";
- }
- }
- }
- reportError(context, content->GetOriginalExpression(),
- "$<TARGET_POLICY:prop> may only be used with a limited number of "
- "policies. Currently it may be used with the following policies:\n"
-
-#define STRINGIFY_HELPER(X) #X
-#define STRINGIFY(X) STRINGIFY_HELPER(X)
-
-#define TARGET_POLICY_LIST_ITEM(POLICY) \
- " * " STRINGIFY(POLICY) "\n"
-
- CM_FOR_EACH_TARGET_POLICY(TARGET_POLICY_LIST_ITEM)
-
-#undef TARGET_POLICY_LIST_ITEM
- );
- return std::string();
- }
-
-} targetPolicyNode;
-
-//----------------------------------------------------------------------------
-static const struct InstallPrefixNode : public cmGeneratorExpressionNode
-{
- InstallPrefixNode() {}
-
- virtual bool GeneratesContent() const { return true; }
- virtual int NumExpectedParameters() const { return 0; }
-
- std::string Evaluate(const std::vector<std::string> &,
- cmGeneratorExpressionContext *context,
- const GeneratorExpressionContent *content,
- cmGeneratorExpressionDAGChecker *) const
- {
- reportError(context, content->GetOriginalExpression(),
- "INSTALL_PREFIX is a marker for install(EXPORT) only. It "
- "should never be evaluated.");
- return std::string();
- }
-
-} installPrefixNode;
-
-//----------------------------------------------------------------------------
-class ArtifactNameTag;
-class ArtifactLinkerTag;
-class ArtifactSonameTag;
-class ArtifactPdbTag;
-
-class ArtifactPathTag;
-class ArtifactDirTag;
-class ArtifactNameTag;
-
-//----------------------------------------------------------------------------
-template<typename ArtifactT>
-struct TargetFilesystemArtifactResultCreator
-{
- static std::string Create(cmTarget* target,
- cmGeneratorExpressionContext *context,
- const GeneratorExpressionContent *content);
-};
-
-//----------------------------------------------------------------------------
-template<>
-struct TargetFilesystemArtifactResultCreator<ArtifactSonameTag>
-{
- static std::string Create(cmTarget* target,
- cmGeneratorExpressionContext *context,
- const GeneratorExpressionContent *content)
- {
- // The target soname file (.so.1).
- if(target->IsDLLPlatform())
- {
- ::reportError(context, content->GetOriginalExpression(),
- "TARGET_SONAME_FILE is not allowed "
- "for DLL target platforms.");
- return std::string();
- }
- if(target->GetType() != cmTarget::SHARED_LIBRARY)
- {
- ::reportError(context, content->GetOriginalExpression(),
- "TARGET_SONAME_FILE is allowed only for "
- "SHARED libraries.");
- return std::string();
- }
- std::string result = target->GetDirectory(context->Config);
- result += "/";
- result += target->GetSOName(context->Config);
- return result;
- }
-};
-
-//----------------------------------------------------------------------------
-template<>
-struct TargetFilesystemArtifactResultCreator<ArtifactPdbTag>
-{
- static std::string Create(cmTarget* target,
- cmGeneratorExpressionContext *context,
- const GeneratorExpressionContent *content)
- {
- std::string language = target->GetLinkerLanguage(context->Config);
-
- std::string pdbSupportVar = "CMAKE_" + language + "_LINKER_SUPPORTS_PDB";
-
- if(!context->Makefile->IsOn(pdbSupportVar))
- {
- ::reportError(context, content->GetOriginalExpression(),
- "TARGET_PDB_FILE is not supported by the target linker.");
- return std::string();
- }
-
- cmTarget::TargetType targetType = target->GetType();
-
- if(targetType != cmTarget::SHARED_LIBRARY &&
- targetType != cmTarget::MODULE_LIBRARY &&
- targetType != cmTarget::EXECUTABLE)
- {
- ::reportError(context, content->GetOriginalExpression(),
- "TARGET_PDB_FILE is allowed only for "
- "targets with linker created artifacts.");
- return std::string();
- }
-
- std::string result = target->GetPDBDirectory(context->Config);
- result += "/";
- result += target->GetPDBName(context->Config);
- return result;
- }
-};
-
-//----------------------------------------------------------------------------
-template<>
-struct TargetFilesystemArtifactResultCreator<ArtifactLinkerTag>
-{
- static std::string Create(cmTarget* target,
- cmGeneratorExpressionContext *context,
- const GeneratorExpressionContent *content)
- {
- // The file used to link to the target (.so, .lib, .a).
- if(!target->IsLinkable())
- {
- ::reportError(context, content->GetOriginalExpression(),
- "TARGET_LINKER_FILE is allowed only for libraries and "
- "executables with ENABLE_EXPORTS.");
- return std::string();
- }
- return target->GetFullPath(context->Config,
- target->HasImportLibrary());
- }
-};
-
-//----------------------------------------------------------------------------
-template<>
-struct TargetFilesystemArtifactResultCreator<ArtifactNameTag>
-{
- static std::string Create(cmTarget* target,
- cmGeneratorExpressionContext *context,
- const GeneratorExpressionContent *)
- {
- return target->GetFullPath(context->Config, false, true);
- }
-};
-
-
-//----------------------------------------------------------------------------
-template<typename ArtifactT>
-struct TargetFilesystemArtifactResultGetter
-{
- static std::string Get(const std::string &result);
-};
-
-//----------------------------------------------------------------------------
-template<>
-struct TargetFilesystemArtifactResultGetter<ArtifactNameTag>
-{
- static std::string Get(const std::string &result)
- { return cmSystemTools::GetFilenameName(result); }
-};
-
-//----------------------------------------------------------------------------
-template<>
-struct TargetFilesystemArtifactResultGetter<ArtifactDirTag>
-{
- static std::string Get(const std::string &result)
- { return cmSystemTools::GetFilenamePath(result); }
-};
-
-//----------------------------------------------------------------------------
-template<>
-struct TargetFilesystemArtifactResultGetter<ArtifactPathTag>
-{
- static std::string Get(const std::string &result)
- { return result; }
-};
-
-//----------------------------------------------------------------------------
-template<typename ArtifactT, typename ComponentT>
-struct TargetFilesystemArtifact : public cmGeneratorExpressionNode
-{
- TargetFilesystemArtifact() {}
-
- virtual int NumExpectedParameters() const { return 1; }
-
- std::string Evaluate(const std::vector<std::string> &parameters,
- cmGeneratorExpressionContext *context,
- const GeneratorExpressionContent *content,
- cmGeneratorExpressionDAGChecker *dagChecker) const
- {
- // Lookup the referenced target.
- std::string name = *parameters.begin();
-
- if (!cmGeneratorExpression::IsValidTargetName(name))
- {
- ::reportError(context, content->GetOriginalExpression(),
- "Expression syntax not recognized.");
- return std::string();
- }
- cmTarget* target = context->Makefile->FindTargetToUse(name);
- if(!target)
- {
- ::reportError(context, content->GetOriginalExpression(),
- "No target \"" + name + "\"");
- return std::string();
- }
- if(target->GetType() >= cmTarget::OBJECT_LIBRARY &&
- target->GetType() != cmTarget::UNKNOWN_LIBRARY)
- {
- ::reportError(context, content->GetOriginalExpression(),
- "Target \"" + name + "\" is not an executable or library.");
- return std::string();
- }
- if (dagChecker && (dagChecker->EvaluatingLinkLibraries(name.c_str())
- || (dagChecker->EvaluatingSources()
- && name == dagChecker->TopTarget())))
- {
- ::reportError(context, content->GetOriginalExpression(),
- "Expressions which require the linker language may not "
- "be used while evaluating link libraries");
- return std::string();
- }
- context->DependTargets.insert(target);
- context->AllTargets.insert(target);
-
- std::string result =
- TargetFilesystemArtifactResultCreator<ArtifactT>::Create(
- target,
- context,
- content);
- if (context->HadError)
- {
- return std::string();
- }
- return
- TargetFilesystemArtifactResultGetter<ComponentT>::Get(result);
- }
-};
-
-//----------------------------------------------------------------------------
-template<typename ArtifactT>
-struct TargetFilesystemArtifactNodeGroup
-{
- TargetFilesystemArtifactNodeGroup()
- {
- }
-
- TargetFilesystemArtifact<ArtifactT, ArtifactPathTag> File;
- TargetFilesystemArtifact<ArtifactT, ArtifactNameTag> FileName;
- TargetFilesystemArtifact<ArtifactT, ArtifactDirTag> FileDir;
-};
-
-//----------------------------------------------------------------------------
-static const
-TargetFilesystemArtifactNodeGroup<ArtifactNameTag> targetNodeGroup;
-
-static const
-TargetFilesystemArtifactNodeGroup<ArtifactLinkerTag> targetLinkerNodeGroup;
-
-static const
-TargetFilesystemArtifactNodeGroup<ArtifactSonameTag> targetSoNameNodeGroup;
-
-static const
-TargetFilesystemArtifactNodeGroup<ArtifactPdbTag> targetPdbNodeGroup;
-
-//----------------------------------------------------------------------------
-static const
-cmGeneratorExpressionNode* GetNode(const std::string &identifier)
-{
- typedef std::map<std::string, const cmGeneratorExpressionNode*> NodeMap;
- static NodeMap nodeMap;
- if (nodeMap.empty())
- {
- nodeMap["0"] = &zeroNode;
- nodeMap["1"] = &oneNode;
- nodeMap["AND"] = &andNode;
- nodeMap["OR"] = &orNode;
- nodeMap["NOT"] = &notNode;
- nodeMap["C_COMPILER_ID"] = &cCompilerIdNode;
- nodeMap["CXX_COMPILER_ID"] = &cxxCompilerIdNode;
- nodeMap["VERSION_GREATER"] = &versionGreaterNode;
- nodeMap["VERSION_LESS"] = &versionLessNode;
- nodeMap["VERSION_EQUAL"] = &versionEqualNode;
- nodeMap["C_COMPILER_VERSION"] = &cCompilerVersionNode;
- nodeMap["CXX_COMPILER_VERSION"] = &cxxCompilerVersionNode;
- nodeMap["PLATFORM_ID"] = &platformIdNode;
- nodeMap["COMPILE_FEATURES"] = &compileFeaturesNode;
- nodeMap["CONFIGURATION"] = &configurationNode;
- nodeMap["CONFIG"] = &configurationTestNode;
- nodeMap["TARGET_FILE"] = &targetNodeGroup.File;
- nodeMap["TARGET_LINKER_FILE"] = &targetLinkerNodeGroup.File;
- nodeMap["TARGET_SONAME_FILE"] = &targetSoNameNodeGroup.File;
- nodeMap["TARGET_PDB_FILE"] = &targetPdbNodeGroup.File;
- nodeMap["TARGET_FILE_NAME"] = &targetNodeGroup.FileName;
- nodeMap["TARGET_LINKER_FILE_NAME"] = &targetLinkerNodeGroup.FileName;
- nodeMap["TARGET_SONAME_FILE_NAME"] = &targetSoNameNodeGroup.FileName;
- nodeMap["TARGET_PDB_FILE_NAME"] = &targetPdbNodeGroup.FileName;
- nodeMap["TARGET_FILE_DIR"] = &targetNodeGroup.FileDir;
- nodeMap["TARGET_LINKER_FILE_DIR"] = &targetLinkerNodeGroup.FileDir;
- nodeMap["TARGET_SONAME_FILE_DIR"] = &targetSoNameNodeGroup.FileDir;
- nodeMap["TARGET_PDB_FILE_DIR"] = &targetPdbNodeGroup.FileDir;
- nodeMap["STREQUAL"] = &strEqualNode;
- nodeMap["EQUAL"] = &equalNode;
- nodeMap["LOWER_CASE"] = &lowerCaseNode;
- nodeMap["UPPER_CASE"] = &upperCaseNode;
- nodeMap["MAKE_C_IDENTIFIER"] = &makeCIdentifierNode;
- nodeMap["BOOL"] = &boolNode;
- nodeMap["ANGLE-R"] = &angle_rNode;
- nodeMap["COMMA"] = &commaNode;
- nodeMap["SEMICOLON"] = &semicolonNode;
- nodeMap["TARGET_PROPERTY"] = &targetPropertyNode;
- nodeMap["TARGET_NAME"] = &targetNameNode;
- nodeMap["TARGET_OBJECTS"] = &targetObjectsNode;
- nodeMap["TARGET_POLICY"] = &targetPolicyNode;
- nodeMap["BUILD_INTERFACE"] = &buildInterfaceNode;
- nodeMap["INSTALL_INTERFACE"] = &installInterfaceNode;
- nodeMap["INSTALL_PREFIX"] = &installPrefixNode;
- nodeMap["JOIN"] = &joinNode;
- nodeMap["LINK_ONLY"] = &linkOnlyNode;
- nodeMap["COMPILE_LANGUAGE"] = &languageNode;
- }
- NodeMap::const_iterator i = nodeMap.find(identifier);
- if (i == nodeMap.end())
- {
- return 0;
- }
- return i->second;
-
-}
+#include "cmGeneratorExpressionNode.h"
//----------------------------------------------------------------------------
GeneratorExpressionContent::GeneratorExpressionContent(
@@ -2001,7 +114,8 @@ std::string GeneratorExpressionContent::Evaluate(
}
}
- const cmGeneratorExpressionNode *node = GetNode(identifier);
+ const cmGeneratorExpressionNode *node =
+ cmGeneratorExpressionNode::GetNode(identifier);
if (!node)
{