summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorStephen Kelly <steveire@gmail.com>2012-11-05 13:48:42 (GMT)
committerStephen Kelly <steveire@gmail.com>2013-01-08 19:38:16 (GMT)
commitbf5ece51c3827dc05018128fefe8270da88cfefb (patch)
tree1e12a12d0348c68446748e72fa5c49274b53cf9c /Source
parenta9f1bf438054227e989ad1706b785b978e18455c (diff)
downloadCMake-bf5ece51c3827dc05018128fefe8270da88cfefb.zip
CMake-bf5ece51c3827dc05018128fefe8270da88cfefb.tar.gz
CMake-bf5ece51c3827dc05018128fefe8270da88cfefb.tar.bz2
Keep track of properties used to determine linker libraries.
Those properties can't later be implicitly defined by the interface of those link libraries.
Diffstat (limited to 'Source')
-rw-r--r--Source/cmGeneratorExpression.cxx10
-rw-r--r--Source/cmGeneratorExpression.h4
-rw-r--r--Source/cmGeneratorExpressionEvaluator.cxx8
-rw-r--r--Source/cmGeneratorExpressionEvaluator.h1
-rw-r--r--Source/cmTarget.cxx42
-rw-r--r--Source/cmTarget.h10
6 files changed, 73 insertions, 2 deletions
diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx
index 6d003e1..4063697 100644
--- a/Source/cmGeneratorExpression.cxx
+++ b/Source/cmGeneratorExpression.cxx
@@ -94,7 +94,15 @@ const char *cmCompiledGeneratorExpression::Evaluate(
for ( ; it != end; ++it)
{
- this->Output += (*it)->Evaluate(&context, dagChecker);
+ const std::string result = (*it)->Evaluate(&context, dagChecker);
+ this->Output += result;
+
+ for(std::set<cmStdString>::const_iterator
+ p = context.SeenTargetProperties.begin();
+ p != context.SeenTargetProperties.end(); ++p)
+ {
+ this->SeenTargetProperties[*p] += result + ";";
+ }
if (context.HadError)
{
this->Output = "";
diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h
index dcdfefb..b58dde5 100644
--- a/Source/cmGeneratorExpression.h
+++ b/Source/cmGeneratorExpression.h
@@ -83,6 +83,9 @@ public:
std::set<cmTarget*> const& GetTargets() const
{ return this->Targets; }
+ std::map<cmStdString, cmStdString> const& GetSeenTargetProperties() const
+ { return this->SeenTargetProperties; }
+
~cmCompiledGeneratorExpression();
std::string GetInput() const
@@ -110,6 +113,7 @@ private:
bool NeedsParsing;
mutable std::set<cmTarget*> Targets;
+ mutable std::map<cmStdString, cmStdString> SeenTargetProperties;
mutable std::string Output;
};
diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx
index 82becaf..f4e4131 100644
--- a/Source/cmGeneratorExpressionEvaluator.cxx
+++ b/Source/cmGeneratorExpressionEvaluator.cxx
@@ -380,6 +380,14 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
}
}
+ 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 form a DAG.
+ context->SeenTargetProperties.insert(propertyName);
+ }
+
if (propertyName.empty())
{
reportError(context, content->GetOriginalExpression(),
diff --git a/Source/cmGeneratorExpressionEvaluator.h b/Source/cmGeneratorExpressionEvaluator.h
index 59804ff..fb6c7ee 100644
--- a/Source/cmGeneratorExpressionEvaluator.h
+++ b/Source/cmGeneratorExpressionEvaluator.h
@@ -24,6 +24,7 @@ struct cmGeneratorExpressionContext
{
cmListFileBacktrace Backtrace;
std::set<cmTarget*> Targets;
+ std::set<cmStdString> SeenTargetProperties;
cmMakefile *Makefile;
const char *Config;
cmTarget *HeadTarget; // The target whose property is being evaluated.
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 25054c5..e4adb09 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -2164,16 +2164,19 @@ void cmTarget::GetDirectLinkLibraries(const char *config,
{
cmListFileBacktrace lfbt;
cmGeneratorExpression ge(lfbt);
+ const cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
cmGeneratorExpressionDAGChecker dagChecker(lfbt,
this->GetName(),
"LINK_LIBRARIES", 0, 0);
- cmSystemTools::ExpandListArgument(ge.Parse(prop)->Evaluate(this->Makefile,
+ cmSystemTools::ExpandListArgument(cge->Evaluate(this->Makefile,
config,
false,
head,
&dagChecker),
libs);
+
+ this->AddLinkDependentTargetsForProperties(cge->GetSeenTargetProperties());
}
}
@@ -4377,6 +4380,43 @@ const char* cmTarget::GetExportMacro()
}
//----------------------------------------------------------------------------
+void cmTarget::GetLinkDependentTargetsForProperty(const std::string &p,
+ std::set<std::string> &targets)
+{
+ const std::map<cmStdString, std::set<std::string> >::const_iterator findIt
+ = this->LinkDependentProperties.find(p);
+ if (findIt != this->LinkDependentProperties.end())
+ {
+ targets = findIt->second;
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmTarget::IsNullImpliedByLinkLibraries(const std::string &p)
+{
+ return this->LinkImplicitNullProperties.find(p)
+ != this->LinkImplicitNullProperties.end();
+}
+
+//----------------------------------------------------------------------------
+void cmTarget::AddLinkDependentTargetsForProperties(
+ const std::map<cmStdString, cmStdString> &map)
+{
+ for (std::map<cmStdString, cmStdString>::const_iterator it = map.begin();
+ it != map.end(); ++it)
+ {
+ std::vector<std::string> targets;
+ cmSystemTools::ExpandListArgument(it->second.c_str(), targets);
+ this->LinkDependentProperties[it->first].insert(targets.begin(),
+ targets.end());
+ if (!this->GetProperty(it->first.c_str()))
+ {
+ this->LinkImplicitNullProperties.insert(it->first);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
void cmTarget::GetLanguages(std::set<cmStdString>& languages) const
{
for(std::vector<cmSourceFile*>::const_iterator
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index d4069fa..5ce7d53 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -487,6 +487,13 @@ public:
std::vector<std::string> GetIncludeDirectories(const char *config);
void InsertInclude(const cmMakefileIncludeDirectoriesEntry &entry,
bool before = false);
+
+ void GetLinkDependentTargetsForProperty(const std::string &p,
+ std::set<std::string> &targets);
+ bool IsNullImpliedByLinkLibraries(const std::string &p);
+
+ void AddLinkDependentTargetsForProperties(
+ const std::map<cmStdString, cmStdString> &map);
private:
/**
* A list of direct dependencies. Use in conjunction with DependencyMap.
@@ -596,6 +603,9 @@ private:
bool DLLPlatform;
bool IsApple;
bool IsImportedTarget;
+ mutable std::map<cmStdString, std::set<std::string> >
+ LinkDependentProperties;
+ mutable std::set<std::string> LinkImplicitNullProperties;
// Cache target output paths for each configuration.
struct OutputInfo;