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:
parent
0a8fbac19a
commit
8cb9105431
|
@ -799,72 +799,51 @@ 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.
|
||||||
|
// Don't follow such link interface entries so as not to create a
|
||||||
|
// self-referencing loop.
|
||||||
|
if (it->Target && it->Target != target)
|
||||||
{
|
{
|
||||||
// Broken code can have a target in its own link interface.
|
depString +=
|
||||||
// Don't follow such link interface entries so as not to create a
|
sep + "$<TARGET_PROPERTY:" +
|
||||||
// self-referencing loop.
|
it->Target->GetName() + "," + interfacePropertyName + ">";
|
||||||
continue;
|
sep = ";";
|
||||||
}
|
}
|
||||||
depString +=
|
|
||||||
sep + "$<TARGET_PROPERTY:" +
|
|
||||||
(*it)->GetName() + "," + interfacePropertyName + ">";
|
|
||||||
sep = ";";
|
|
||||||
}
|
}
|
||||||
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(depString);
|
if(!depString.empty())
|
||||||
std::string linkedTargetsContent = cge->Evaluate(target->GetMakefile(),
|
|
||||||
context->Config,
|
|
||||||
context->Quiet,
|
|
||||||
headTarget,
|
|
||||||
target,
|
|
||||||
dagChecker);
|
|
||||||
if (cge->GetHadContextSensitiveCondition())
|
|
||||||
{
|
{
|
||||||
context->HadContextSensitiveCondition = true;
|
cmGeneratorExpression ge(&context->Backtrace);
|
||||||
|
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(depString);
|
||||||
|
linkedTargetsContent = cge->Evaluate(target->GetMakefile(),
|
||||||
|
context->Config,
|
||||||
|
context->Quiet,
|
||||||
|
headTarget,
|
||||||
|
target,
|
||||||
|
dagChecker);
|
||||||
|
if (cge->GetHadContextSensitiveCondition())
|
||||||
|
{
|
||||||
|
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,27 +1077,14 @@ 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (std::find_if(transBegin, transEnd,
|
else if (std::find_if(transBegin, transEnd,
|
||||||
|
|
Loading…
Reference in New Issue