Keep track of properties used to determine linker libraries.

Those properties can't later be implicitly defined by the interface
of those link libraries.
This commit is contained in:
Stephen Kelly 2012-11-05 14:48:42 +01:00
parent a9f1bf4380
commit bf5ece51c3
6 changed files with 73 additions and 2 deletions

View File

@ -94,7 +94,15 @@ const char *cmCompiledGeneratorExpression::Evaluate(
for ( ; it != end; ++it) 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) if (context.HadError)
{ {
this->Output = ""; this->Output = "";

View File

@ -83,6 +83,9 @@ public:
std::set<cmTarget*> const& GetTargets() const std::set<cmTarget*> const& GetTargets() const
{ return this->Targets; } { return this->Targets; }
std::map<cmStdString, cmStdString> const& GetSeenTargetProperties() const
{ return this->SeenTargetProperties; }
~cmCompiledGeneratorExpression(); ~cmCompiledGeneratorExpression();
std::string GetInput() const std::string GetInput() const
@ -110,6 +113,7 @@ private:
bool NeedsParsing; bool NeedsParsing;
mutable std::set<cmTarget*> Targets; mutable std::set<cmTarget*> Targets;
mutable std::map<cmStdString, cmStdString> SeenTargetProperties;
mutable std::string Output; mutable std::string Output;
}; };

View File

@ -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()) if (propertyName.empty())
{ {
reportError(context, content->GetOriginalExpression(), reportError(context, content->GetOriginalExpression(),

View File

@ -24,6 +24,7 @@ struct cmGeneratorExpressionContext
{ {
cmListFileBacktrace Backtrace; cmListFileBacktrace Backtrace;
std::set<cmTarget*> Targets; std::set<cmTarget*> Targets;
std::set<cmStdString> SeenTargetProperties;
cmMakefile *Makefile; cmMakefile *Makefile;
const char *Config; const char *Config;
cmTarget *HeadTarget; // The target whose property is being evaluated. cmTarget *HeadTarget; // The target whose property is being evaluated.

View File

@ -2164,16 +2164,19 @@ void cmTarget::GetDirectLinkLibraries(const char *config,
{ {
cmListFileBacktrace lfbt; cmListFileBacktrace lfbt;
cmGeneratorExpression ge(lfbt); cmGeneratorExpression ge(lfbt);
const cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
cmGeneratorExpressionDAGChecker dagChecker(lfbt, cmGeneratorExpressionDAGChecker dagChecker(lfbt,
this->GetName(), this->GetName(),
"LINK_LIBRARIES", 0, 0); "LINK_LIBRARIES", 0, 0);
cmSystemTools::ExpandListArgument(ge.Parse(prop)->Evaluate(this->Makefile, cmSystemTools::ExpandListArgument(cge->Evaluate(this->Makefile,
config, config,
false, false,
head, head,
&dagChecker), &dagChecker),
libs); libs);
this->AddLinkDependentTargetsForProperties(cge->GetSeenTargetProperties());
} }
} }
@ -4376,6 +4379,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 void cmTarget::GetLanguages(std::set<cmStdString>& languages) const
{ {

View File

@ -487,6 +487,13 @@ public:
std::vector<std::string> GetIncludeDirectories(const char *config); std::vector<std::string> GetIncludeDirectories(const char *config);
void InsertInclude(const cmMakefileIncludeDirectoriesEntry &entry, void InsertInclude(const cmMakefileIncludeDirectoriesEntry &entry,
bool before = false); 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: private:
/** /**
* A list of direct dependencies. Use in conjunction with DependencyMap. * A list of direct dependencies. Use in conjunction with DependencyMap.
@ -596,6 +603,9 @@ private:
bool DLLPlatform; bool DLLPlatform;
bool IsApple; bool IsApple;
bool IsImportedTarget; bool IsImportedTarget;
mutable std::map<cmStdString, std::set<std::string> >
LinkDependentProperties;
mutable std::set<std::string> LinkImplicitNullProperties;
// Cache target output paths for each configuration. // Cache target output paths for each configuration.
struct OutputInfo; struct OutputInfo;