Genex: Simplify TARGET_PROPERTY transitive lookup

In cmGeneratorExpressionEvaluator, make getLinkedTargetsContent a
template so it can traverse over either the Libraries in a cmTarget
LinkImplementationLibraries or a cmTarget LinkInterfaceLibraries.  This
also avoids creating a separate vector<cmTarget*>.
This commit is contained in:
Brad King 2014-07-15 11:50:32 -04:00
parent 0a8fbac19a
commit 8cb9105431

View File

@ -799,37 +799,38 @@ static const char* targetPropertyTransitiveWhitelist[] = {
#undef TRANSITIVE_PROPERTY_NAME #undef TRANSITIVE_PROPERTY_NAME
template <typename T>
std::string std::string
getLinkedTargetsContent( getLinkedTargetsContent(
std::vector<cmTarget const*> &targets, std::vector<T> const &libraries,
cmTarget const* target, cmTarget const* target,
cmTarget const* headTarget, cmTarget const* headTarget,
cmGeneratorExpressionContext *context, cmGeneratorExpressionContext *context,
cmGeneratorExpressionDAGChecker *dagChecker, cmGeneratorExpressionDAGChecker *dagChecker,
const std::string &interfacePropertyName) const std::string &interfacePropertyName)
{ {
cmGeneratorExpression ge(&context->Backtrace); std::string linkedTargetsContent;
std::string sep; std::string sep;
std::string depString; std::string depString;
for (std::vector<cmTarget const*>::const_iterator for (typename std::vector<T>::const_iterator it = libraries.begin();
it = targets.begin(); it != libraries.end(); ++it)
it != targets.end(); ++it)
{
if (*it == target)
{ {
// Broken code can have a target in its own link interface. // Broken code can have a target in its own link interface.
// Don't follow such link interface entries so as not to create a // Don't follow such link interface entries so as not to create a
// self-referencing loop. // self-referencing loop.
continue; if (it->Target && it->Target != target)
} {
depString += depString +=
sep + "$<TARGET_PROPERTY:" + sep + "$<TARGET_PROPERTY:" +
(*it)->GetName() + "," + interfacePropertyName + ">"; it->Target->GetName() + "," + interfacePropertyName + ">";
sep = ";"; sep = ";";
} }
}
if(!depString.empty())
{
cmGeneratorExpression ge(&context->Backtrace);
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(depString); cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(depString);
std::string linkedTargetsContent = cge->Evaluate(target->GetMakefile(), linkedTargetsContent = cge->Evaluate(target->GetMakefile(),
context->Config, context->Config,
context->Quiet, context->Quiet,
headTarget, headTarget,
@ -839,32 +840,10 @@ getLinkedTargetsContent(
{ {
context->HadContextSensitiveCondition = true; context->HadContextSensitiveCondition = true;
} }
}
return linkedTargetsContent; return linkedTargetsContent;
} }
std::string
getLinkedTargetsContent(
std::vector<cmLinkImplItem> const &libraries,
cmTarget const* target,
cmTarget const* headTarget,
cmGeneratorExpressionContext *context,
cmGeneratorExpressionDAGChecker *dagChecker,
const std::string &interfacePropertyName)
{
std::vector<cmTarget const*> tgts;
for (std::vector<cmLinkImplItem>::const_iterator
it = libraries.begin();
it != libraries.end(); ++it)
{
if (it->Target)
{
tgts.push_back(it->Target);
}
}
return getLinkedTargetsContent(tgts, target, headTarget, context,
dagChecker, interfacePropertyName);
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
static const struct TargetPropertyNode : public cmGeneratorExpressionNode static const struct TargetPropertyNode : public cmGeneratorExpressionNode
{ {
@ -1098,24 +1077,11 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
if (std::find_if(transBegin, transEnd, if (std::find_if(transBegin, transEnd,
cmStrCmp(propertyName)) != transEnd) cmStrCmp(propertyName)) != transEnd)
{ {
std::vector<cmTarget const*> tgts;
if(cmTarget::LinkInterfaceLibraries const* iface = if(cmTarget::LinkInterfaceLibraries const* iface =
target->GetLinkInterfaceLibraries(context->Config, headTarget, true)) target->GetLinkInterfaceLibraries(context->Config, headTarget, true))
{ {
for(std::vector<cmLinkItem>::const_iterator
it = iface->Libraries.begin();
it != iface->Libraries.end(); ++it)
{
if (it->Target)
{
tgts.push_back(it->Target);
}
}
}
if (!tgts.empty())
{
linkedTargetsContent = linkedTargetsContent =
getLinkedTargetsContent(tgts, target, getLinkedTargetsContent(iface->Libraries, target,
headTarget, headTarget,
context, &dagChecker, context, &dagChecker,
interfacePropertyName); interfacePropertyName);