From 239ac841538be536e70cbddb2b04bef2b342a2e5 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Wed, 12 Sep 2012 04:23:31 +0200 Subject: [PATCH] Add a generator expression for target properties. There are two overloads, so that it can use the operational target when a target property is being evaluated, and a target can alternatively be specified by name. At this point, the generators don't chain. That comes later. --- Source/cmAddTestCommand.h | 2 +- Source/cmDocumentGeneratorExpressions.h | 11 +++++- Source/cmGeneratorExpression.cxx | 4 ++- Source/cmGeneratorExpression.h | 4 ++- Source/cmGeneratorExpressionEvaluator.cxx | 43 +++++++++++++++++++++++ Source/cmGeneratorExpressionEvaluator.h | 7 +++- 6 files changed, 66 insertions(+), 5 deletions(-) diff --git a/Source/cmAddTestCommand.h b/Source/cmAddTestCommand.h index b11bff9679..6a0cd9d2e0 100644 --- a/Source/cmAddTestCommand.h +++ b/Source/cmAddTestCommand.h @@ -81,7 +81,7 @@ public: "\n" "Arguments after COMMAND may use \"generator expressions\" with the " "syntax \"$<...>\". " - CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS + CM_DOCUMENT_ADD_TEST_GENERATOR_EXPRESSIONS "Example usage:\n" " add_test(NAME mytest\n" " COMMAND testDriver --config $\n" diff --git a/Source/cmDocumentGeneratorExpressions.h b/Source/cmDocumentGeneratorExpressions.h index 5622da0934..6b0cf49148 100644 --- a/Source/cmDocumentGeneratorExpressions.h +++ b/Source/cmDocumentGeneratorExpressions.h @@ -12,7 +12,7 @@ #ifndef cmDocumentGeneratorExpressions_h #define cmDocumentGeneratorExpressions_h -#define CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS \ +#define CM_DOCUMENT_ADD_TEST_GENERATOR_EXPRESSIONS \ "Generator expressions are evaluted during build system generation " \ "to produce information specific to each build configuration. " \ "Valid expressions are:\n" \ @@ -35,11 +35,20 @@ " $/$\n" \ " $/$\n" \ " $/$\n" \ + " $ = The value of the property prop\n" \ + "the target tgt. Note that tgt is not added as a dependency of the " \ + "target this expression is evaluated on.\n" \ "Boolean expressions:\n" \ " $ = '1' if all '?' are '1', else '0'\n" \ " $ = '0' if all '?' are '0', else '1'\n" \ " $ = '0' if '?' is '1', else '1'\n" \ "where '?' is always either '0' or '1'.\n" \ + +#define CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS \ + CM_DOCUMENT_ADD_TEST_GENERATOR_EXPRESSIONS \ + "Expressions with an implicit 'this' target:" \ + " $ = The value of the property prop on\n" \ + "the target on which the generator expression is evaluated.\n" \ "" #endif diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx index 0885616ade..55a1e3e7d9 100644 --- a/Source/cmGeneratorExpression.cxx +++ b/Source/cmGeneratorExpression.cxx @@ -65,7 +65,8 @@ cmGeneratorExpression::~cmGeneratorExpression() //---------------------------------------------------------------------------- const char *cmCompiledGeneratorExpression::Evaluate( - cmMakefile* mf, const char* config, bool quiet) const + cmMakefile* mf, const char* config, bool quiet, + cmGeneratorTarget *target) const { if (!this->NeedsParsing) { @@ -84,6 +85,7 @@ const char *cmCompiledGeneratorExpression::Evaluate( context.Config = config; context.Quiet = quiet; context.HadError = false; + context.Target = target; context.Backtrace = this->Backtrace; for ( ; it != end; ++it) diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h index 780ccfcaf6..fdf45a1938 100644 --- a/Source/cmGeneratorExpression.h +++ b/Source/cmGeneratorExpression.h @@ -20,6 +20,7 @@ #include class cmTarget; +class cmGeneratorTarget; class cmMakefile; class cmListFileBacktrace; @@ -58,7 +59,8 @@ class cmCompiledGeneratorExpression { public: const char* Evaluate(cmMakefile* mf, const char* config, - bool quiet = false) const; + bool quiet = false, + cmGeneratorTarget *target = 0) const; /** Get set of targets found during evaluations. */ std::set const& GetTargets() const diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index 8573273a9c..1583270ea5 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -239,6 +239,46 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode } } configurationTestNode; +//---------------------------------------------------------------------------- +static const struct TargetPropertyNode: public cmGeneratorExpressionNode +{ + TargetPropertyNode() {} + + // This node handles errors on parameter count itself. + virtual int NumExpectedParameters() const { return -1; } + + std::string Evaluate(const std::vector ¶meters, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content) const + { + if (parameters.size() != 1 && parameters.size() != 2) + { + reportError(context, content->GetOriginalExpression(), + "$ expression requires one or two parameters"); + return std::string(); + } + cmGeneratorTarget* target = context->Target; + std::string propertyName = *parameters.begin(); + if (parameters.size() == 2) + { + target = context->Makefile->FindGeneratorTargetToUse( + parameters.begin()->c_str()); + + if (!target) + { + cmOStringStream e; + e << "Target \"" + << target + << "\" not found."; + reportError(context, content->GetOriginalExpression(), e.str()); + } + propertyName = parameters.at(1); + } + const char *prop = target->GetProperty(propertyName.c_str()); + return prop ? prop : ""; + } +} targetPropertyNode; + //---------------------------------------------------------------------------- template struct TargetFilesystemArtifactResultCreator @@ -460,7 +500,10 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier) return &angle_rNode; else if (identifier == "COMMA") return &commaNode; + else if (identifier == "TARGET_PROPERTY") + return &targetPropertyNode; return 0; + } //---------------------------------------------------------------------------- diff --git a/Source/cmGeneratorExpressionEvaluator.h b/Source/cmGeneratorExpressionEvaluator.h index 5163ca002d..4086e8e2ac 100644 --- a/Source/cmGeneratorExpressionEvaluator.h +++ b/Source/cmGeneratorExpressionEvaluator.h @@ -15,6 +15,11 @@ #include #include +#include "cmListFileCache.h" + +class cmTarget; +class cmGeneratorTarget; + //---------------------------------------------------------------------------- struct cmGeneratorExpressionContext { @@ -22,7 +27,7 @@ struct cmGeneratorExpressionContext std::set Targets; cmMakefile *Makefile; const char *Config; - cmTarget *Target; + cmGeneratorTarget *Target; bool Quiet; bool HadError; };