summaryrefslogtreecommitdiffstats
path: root/Source/cmGeneratorExpressionEvaluator.cxx
diff options
context:
space:
mode:
authorStephen Kelly <steveire@gmail.com>2013-01-30 22:38:04 (GMT)
committerStephen Kelly <steveire@gmail.com>2013-01-31 16:34:20 (GMT)
commit0b92602b816e2584db3781b120a1e5200da72ada (patch)
treeccf0d78b89d14d2bc317725b81ff3281d8b83ed1 /Source/cmGeneratorExpressionEvaluator.cxx
parent0fa7f69c0e2cdcd8b7ece400651ee7821b2ede4b (diff)
downloadCMake-0b92602b816e2584db3781b120a1e5200da72ada.zip
CMake-0b92602b816e2584db3781b120a1e5200da72ada.tar.gz
CMake-0b92602b816e2584db3781b120a1e5200da72ada.tar.bz2
Add the $<LINKED:...> generator expression.
This is both a short form of using a TARGET_DEFINED expression together with a TARGET_PROPERTY definition, and a way to strip non-target content from interface properties when exporting.
Diffstat (limited to 'Source/cmGeneratorExpressionEvaluator.cxx')
-rw-r--r--Source/cmGeneratorExpressionEvaluator.cxx85
1 files changed, 85 insertions, 0 deletions
diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx
index fff7dab..cbea1d9 100644
--- a/Source/cmGeneratorExpressionEvaluator.cxx
+++ b/Source/cmGeneratorExpressionEvaluator.cxx
@@ -638,6 +638,89 @@ static const struct InstallPrefixNode : public cmGeneratorExpressionNode
} installPrefixNode;
//----------------------------------------------------------------------------
+static const struct LinkedNode : public cmGeneratorExpressionNode
+{
+ LinkedNode() {}
+
+ virtual bool GeneratesContent() const { return true; }
+ virtual int NumExpectedParameters() const { return 1; }
+ virtual bool RequiresLiteralInput() const { return true; }
+
+ std::string Evaluate(const std::vector<std::string> &parameters,
+ cmGeneratorExpressionContext *context,
+ const GeneratorExpressionContent *content,
+ cmGeneratorExpressionDAGChecker *dagChecker) const
+ {
+ if (dagChecker->EvaluatingIncludeDirectories())
+ {
+ return this->GetInterfaceProperty(parameters.front(),
+ "INCLUDE_DIRECTORIES",
+ context, content, dagChecker);
+ }
+ if (dagChecker->EvaluatingCompileDefinitions())
+ {
+ return this->GetInterfaceProperty(parameters.front(),
+ "COMPILE_DEFINITIONS",
+ context, content, dagChecker);
+ }
+
+ reportError(context, content->GetOriginalExpression(),
+ "$<LINKED:...> may only be used in INCLUDE_DIRECTORIES and "
+ "COMPILE_DEFINITIONS properties.");
+
+ return std::string();
+ }
+
+private:
+ std::string GetInterfaceProperty(const std::string &item,
+ const std::string &prop,
+ cmGeneratorExpressionContext *context,
+ const GeneratorExpressionContent *content,
+ cmGeneratorExpressionDAGChecker *dagCheckerParent) const
+ {
+ cmTarget *target = context->CurrentTarget
+ ->GetMakefile()->FindTargetToUse(item.c_str());
+ if (!target)
+ {
+ return std::string();
+ }
+ std::string propertyName = "INTERFACE_" + prop;
+ const char *propContent = target->GetProperty(propertyName.c_str());
+ if (!propContent)
+ {
+ return std::string();
+ }
+
+ 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::DAG:
+ break;
+ }
+
+ cmGeneratorExpression ge(context->Backtrace);
+ return ge.Parse(propContent)->Evaluate(context->Makefile,
+ context->Config,
+ context->Quiet,
+ context->HeadTarget,
+ target,
+ &dagChecker);
+ }
+
+} linkedNode;
+
+//----------------------------------------------------------------------------
template<bool linker, bool soname>
struct TargetFilesystemArtifactResultCreator
{
@@ -874,6 +957,8 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier)
return &targetDefinedNode;
else if (identifier == "INSTALL_PREFIX")
return &installPrefixNode;
+ else if (identifier == "LINKED")
+ return &linkedNode;
return 0;
}