Merge topic 'refactor-link-internals'

c45dd669 cmTarget: Cache compatible interface property sets
89095514 cmTarget: Refactor GetLinkImplementationClosure internals
9d72df45 Genex: Adjust code layout slightly
d5f0743d Genex: Refactor empty element strip
60bafeb6 Genex: Avoid repeated search of transitive property whitelist
8cb91054 Genex: Simplify TARGET_PROPERTY transitive lookup
0a8fbac1 cmTarget: Drop GetTransitivePropertyTargets method
fb3518dc Refactor system include annotation propagation
535fd6ce cmTarget: Make GetLink*Libraries methods safer to use
This commit is contained in:
Brad King 2014-07-17 09:43:01 -04:00 committed by CMake Topic Stage
commit e4510941a3
4 changed files with 164 additions and 228 deletions

View File

@ -799,72 +799,53 @@ 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;
}
} }
linkedTargetsContent =
cmGeneratorExpression::StripEmptyListElements(linkedTargetsContent);
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
{ {
@ -1058,19 +1039,25 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD( CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(
ASSERT_TRANSITIVE_PROPERTY_METHOD) ASSERT_TRANSITIVE_PROPERTY_METHOD)
false); false);
}
#undef ASSERT_TRANSITIVE_PROPERTY_METHOD #undef ASSERT_TRANSITIVE_PROPERTY_METHOD
}
} }
std::string linkedTargetsContent; std::string linkedTargetsContent;
std::string interfacePropertyName; std::string interfacePropertyName;
bool isInterfaceProperty = false;
#define POPULATE_INTERFACE_PROPERTY_NAME(prop) \ #define POPULATE_INTERFACE_PROPERTY_NAME(prop) \
if (propertyName == #prop || propertyName == "INTERFACE_" #prop) \ if (propertyName == #prop) \
{ \ { \
interfacePropertyName = "INTERFACE_" #prop; \ interfacePropertyName = "INTERFACE_" #prop; \
} \ } \
else if (propertyName == "INTERFACE_" #prop) \
{ \
interfacePropertyName = "INTERFACE_" #prop; \
isInterfaceProperty = true; \
} \
else else
CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(POPULATE_INTERFACE_PROPERTY_NAME) CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(POPULATE_INTERFACE_PROPERTY_NAME)
@ -1086,49 +1073,34 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
} }
} }
#undef POPULATE_INTERFACE_PROPERTY_NAME #undef POPULATE_INTERFACE_PROPERTY_NAME
cmTarget const* headTarget = context->HeadTarget cmTarget const* headTarget = context->HeadTarget
? context->HeadTarget : target; ? context->HeadTarget : target;
const char * const *transBegin = if(isInterfaceProperty)
cmArrayBegin(targetPropertyTransitiveWhitelist) + 1;
const char * const *transEnd =
cmArrayEnd(targetPropertyTransitiveWhitelist);
if (std::find_if(transBegin, transEnd,
cmStrCmp(propertyName)) != transEnd)
{ {
if(cmTarget::LinkInterfaceLibraries const* iface =
std::vector<cmTarget const*> tgts; target->GetLinkInterfaceLibraries(context->Config, headTarget, true))
target->GetTransitivePropertyTargets(context->Config,
headTarget, tgts);
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(!interfacePropertyName.empty())
cmStrCmp(interfacePropertyName)) != transEnd)
{ {
const cmTarget::LinkImplementation *impl if(cmTarget::LinkImplementationLibraries const* impl =
= target->GetLinkImplementationLibraries(context->Config); target->GetLinkImplementationLibraries(context->Config))
if(impl)
{ {
linkedTargetsContent = linkedTargetsContent =
getLinkedTargetsContent(impl->Libraries, target, getLinkedTargetsContent(impl->Libraries, target,
headTarget, headTarget,
context, &dagChecker, context, &dagChecker,
interfacePropertyName); interfacePropertyName);
} }
} }
linkedTargetsContent =
cmGeneratorExpression::StripEmptyListElements(linkedTargetsContent);
if (!prop) if (!prop)
{ {
if (target->IsImported() if (target->IsImported()
@ -1202,32 +1174,27 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
return propContent ? propContent : ""; return propContent ? propContent : "";
} }
} }
for (size_t i = 1; if(!interfacePropertyName.empty())
i < cmArraySize(targetPropertyTransitiveWhitelist);
++i)
{ {
if (targetPropertyTransitiveWhitelist[i] == interfacePropertyName) cmGeneratorExpression ge(&context->Backtrace);
{ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
cmGeneratorExpression ge(&context->Backtrace); cge->SetEvaluateForBuildsystem(context->EvaluateForBuildsystem);
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop); std::string result = cge->Evaluate(context->Makefile,
cge->SetEvaluateForBuildsystem(context->EvaluateForBuildsystem);
std::string result = cge->Evaluate(context->Makefile,
context->Config, context->Config,
context->Quiet, context->Quiet,
headTarget, headTarget,
target, target,
&dagChecker); &dagChecker);
if (cge->GetHadContextSensitiveCondition()) if (cge->GetHadContextSensitiveCondition())
{ {
context->HadContextSensitiveCondition = true; context->HadContextSensitiveCondition = true;
}
if (!linkedTargetsContent.empty())
{
result += (result.empty() ? "" : ";") + linkedTargetsContent;
}
return result;
} }
if (!linkedTargetsContent.empty())
{
result += (result.empty() ? "" : ";") + linkedTargetsContent;
}
return result;
} }
return prop; return prop;
} }

View File

@ -445,13 +445,6 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory(const std::string& dir,
if (iter == this->SystemIncludesCache.end()) if (iter == this->SystemIncludesCache.end())
{ {
cmTarget::LinkImplementation const* impl
= this->Target->GetLinkImplementation(config);
if(!impl)
{
return false;
}
cmGeneratorExpressionDAGChecker dagChecker( cmGeneratorExpressionDAGChecker dagChecker(
this->GetName(), this->GetName(),
"SYSTEM_INCLUDE_DIRECTORIES", 0, 0); "SYSTEM_INCLUDE_DIRECTORIES", 0, 0);
@ -471,35 +464,15 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory(const std::string& dir,
&dagChecker), result); &dagChecker), result);
} }
std::set<cmTarget const*> uniqueDeps; std::vector<cmTarget const*> const& deps =
for(std::vector<cmLinkImplItem>::const_iterator this->Target->GetLinkImplementationClosure(config);
li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li) for(std::vector<cmTarget const*>::const_iterator
li = deps.begin(), le = deps.end(); li != le; ++li)
{ {
cmTarget const* tgt = li->Target; handleSystemIncludesDep(this->Makefile, *li, config, this->Target,
if (!tgt) &dagChecker, result, excludeImported);
{
continue;
}
if (uniqueDeps.insert(tgt).second)
{
handleSystemIncludesDep(this->Makefile, tgt, config, this->Target,
&dagChecker, result, excludeImported);
std::vector<cmTarget const*> deps;
tgt->GetTransitivePropertyTargets(config, this->Target, deps);
for(std::vector<cmTarget const*>::const_iterator di = deps.begin();
di != deps.end(); ++di)
{
if (uniqueDeps.insert(*di).second)
{
handleSystemIncludesDep(this->Makefile, *di, config, this->Target,
&dagChecker, result, excludeImported);
}
}
}
} }
std::set<std::string> unique; std::set<std::string> unique;
for(std::vector<std::string>::iterator li = result.begin(); for(std::vector<std::string>::iterator li = result.begin();
li != result.end(); ++li) li != result.end(); ++li)

View File

@ -164,6 +164,20 @@ public:
typedef std::map<std::string, cmTarget::LinkClosure> LinkClosureMapType; typedef std::map<std::string, cmTarget::LinkClosure> LinkClosureMapType;
LinkClosureMapType LinkClosureMap; LinkClosureMapType LinkClosureMap;
struct LinkImplClosure: public std::vector<cmTarget const*>
{
LinkImplClosure(): Done(false) {}
bool Done;
};
std::map<std::string, LinkImplClosure> LinkImplClosureMap;
struct CompatibleInterfaces: public cmTarget::CompatibleInterfaces
{
CompatibleInterfaces(): Done(false) {}
bool Done;
};
std::map<std::string, CompatibleInterfaces> CompatibleInterfacesMap;
typedef std::map<std::string, std::vector<cmSourceFile*> > typedef std::map<std::string, std::vector<cmSourceFile*> >
SourceFilesMapType; SourceFilesMapType;
SourceFilesMapType SourceFilesMap; SourceFilesMapType SourceFilesMap;
@ -203,15 +217,12 @@ public:
CachedLinkInterfaceSourcesEntries; CachedLinkInterfaceSourcesEntries;
std::map<std::string, std::vector<TargetPropertyEntry*> > std::map<std::string, std::vector<TargetPropertyEntry*> >
CachedLinkInterfaceCompileFeaturesEntries; CachedLinkInterfaceCompileFeaturesEntries;
std::map<std::string, std::vector<cmTarget const*> >
CachedLinkImplementationClosure;
std::map<std::string, bool> CacheLinkInterfaceIncludeDirectoriesDone; std::map<std::string, bool> CacheLinkInterfaceIncludeDirectoriesDone;
std::map<std::string, bool> CacheLinkInterfaceCompileDefinitionsDone; std::map<std::string, bool> CacheLinkInterfaceCompileDefinitionsDone;
std::map<std::string, bool> CacheLinkInterfaceCompileOptionsDone; std::map<std::string, bool> CacheLinkInterfaceCompileOptionsDone;
std::map<std::string, bool> CacheLinkInterfaceSourcesDone; std::map<std::string, bool> CacheLinkInterfaceSourcesDone;
std::map<std::string, bool> CacheLinkInterfaceCompileFeaturesDone; std::map<std::string, bool> CacheLinkInterfaceCompileFeaturesDone;
std::map<std::string, bool> CacheLinkImplementationClosureDone;
}; };
cmLinkImplItem cmTargetInternals::TargetPropertyEntry::NoLinkImplItem; cmLinkImplItem cmTargetInternals::TargetPropertyEntry::NoLinkImplItem;
@ -4379,7 +4390,7 @@ bool cmTarget::HaveBuildTreeRPATH(const std::string& config) const
{ {
return false; return false;
} }
if(LinkImplementation const* impl = if(LinkImplementationLibraries const* impl =
this->GetLinkImplementationLibraries(config)) this->GetLinkImplementationLibraries(config))
{ {
return !impl->Libraries.empty(); return !impl->Libraries.empty();
@ -5298,44 +5309,6 @@ const char * cmTarget::GetLinkInterfaceDependentNumberMaxProperty(
NumberMaxType, 0); NumberMaxType, 0);
} }
//----------------------------------------------------------------------------
bool isLinkDependentProperty(cmTarget const* tgt, const std::string &p,
const std::string& interfaceProperty,
const std::string& config)
{
std::vector<cmTarget const*> const& deps =
tgt->GetLinkImplementationClosure(config);
if(deps.empty())
{
return false;
}
for(std::vector<cmTarget const*>::const_iterator li = deps.begin();
li != deps.end(); ++li)
{
const char *prop = (*li)->GetProperty(interfaceProperty);
if (!prop)
{
continue;
}
std::vector<std::string> props;
cmSystemTools::ExpandListArgument(prop, props);
for(std::vector<std::string>::iterator pi = props.begin();
pi != props.end(); ++pi)
{
if (*pi == p)
{
return true;
}
}
}
return false;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool cmTarget::IsLinkInterfaceDependentBoolProperty(const std::string &p, bool cmTarget::IsLinkInterfaceDependentBoolProperty(const std::string &p,
const std::string& config) const const std::string& config) const
@ -5345,9 +5318,7 @@ bool cmTarget::IsLinkInterfaceDependentBoolProperty(const std::string &p,
{ {
return false; return false;
} }
return (p == "POSITION_INDEPENDENT_CODE") || return this->GetCompatibleInterfaces(config).PropsBool.count(p) > 0;
isLinkDependentProperty(this, p, "COMPATIBLE_INTERFACE_BOOL",
config);
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -5359,9 +5330,7 @@ bool cmTarget::IsLinkInterfaceDependentStringProperty(const std::string &p,
{ {
return false; return false;
} }
return (p == "AUTOUIC_OPTIONS") || return this->GetCompatibleInterfaces(config).PropsString.count(p) > 0;
isLinkDependentProperty(this, p, "COMPATIBLE_INTERFACE_STRING",
config);
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -5373,8 +5342,7 @@ bool cmTarget::IsLinkInterfaceDependentNumberMinProperty(const std::string &p,
{ {
return false; return false;
} }
return isLinkDependentProperty(this, p, "COMPATIBLE_INTERFACE_NUMBER_MIN", return this->GetCompatibleInterfaces(config).PropsNumberMin.count(p) > 0;
config);
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -5386,8 +5354,7 @@ bool cmTarget::IsLinkInterfaceDependentNumberMaxProperty(const std::string &p,
{ {
return false; return false;
} }
return isLinkDependentProperty(this, p, "COMPATIBLE_INTERFACE_NUMBER_MAX", return this->GetCompatibleInterfaces(config).PropsNumberMax.count(p) > 0;
config);
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -5935,7 +5902,7 @@ cmTarget::LinkInterface const* cmTarget::GetLinkInterface(
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
cmTarget::LinkInterface const* cmTarget::LinkInterfaceLibraries const*
cmTarget::GetLinkInterfaceLibraries(const std::string& config, cmTarget::GetLinkInterfaceLibraries(const std::string& config,
cmTarget const* head, cmTarget const* head,
bool usage_requirements_only) const bool usage_requirements_only) const
@ -6017,7 +5984,7 @@ void processILibs(const std::string& config,
if (item.Target && emitted.insert(item.Target).second) if (item.Target && emitted.insert(item.Target).second)
{ {
tgts.push_back(item.Target); tgts.push_back(item.Target);
if(cmTarget::LinkInterface const* iface = if(cmTarget::LinkInterfaceLibraries const* iface =
item.Target->GetLinkInterfaceLibraries(config, headTarget, true)) item.Target->GetLinkInterfaceLibraries(config, headTarget, true))
{ {
for(std::vector<cmLinkItem>::const_iterator for(std::vector<cmLinkItem>::const_iterator
@ -6034,14 +6001,14 @@ void processILibs(const std::string& config,
std::vector<cmTarget const*> const& std::vector<cmTarget const*> const&
cmTarget::GetLinkImplementationClosure(const std::string& config) const cmTarget::GetLinkImplementationClosure(const std::string& config) const
{ {
std::vector<cmTarget const*>& tgts = cmTargetInternals::LinkImplClosure& tgts =
this->Internal->CachedLinkImplementationClosure[config]; this->Internal->LinkImplClosureMap[config];
if(!this->Internal->CacheLinkImplementationClosureDone[config]) if(!tgts.Done)
{ {
this->Internal->CacheLinkImplementationClosureDone[config] = true; tgts.Done = true;
std::set<cmTarget const*> emitted; std::set<cmTarget const*> emitted;
cmTarget::LinkImplementation const* impl cmTarget::LinkImplementationLibraries const* impl
= this->GetLinkImplementationLibraries(config); = this->GetLinkImplementationLibraries(config);
for(std::vector<cmLinkImplItem>::const_iterator for(std::vector<cmLinkImplItem>::const_iterator
@ -6055,22 +6022,37 @@ cmTarget::GetLinkImplementationClosure(const std::string& config) const
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void cmTarget::GetTransitivePropertyTargets(const std::string& config, cmTarget::CompatibleInterfaces const&
cmTarget const* headTarget, cmTarget::GetCompatibleInterfaces(std::string const& config) const
std::vector<cmTarget const*> &tgts) const
{ {
if(cmTarget::LinkInterface const* iface = cmTargetInternals::CompatibleInterfaces& compat =
this->GetLinkInterfaceLibraries(config, headTarget, true)) this->Internal->CompatibleInterfacesMap[config];
if(!compat.Done)
{ {
for(std::vector<cmLinkItem>::const_iterator it = iface->Libraries.begin(); compat.Done = true;
it != iface->Libraries.end(); ++it) compat.PropsBool.insert("POSITION_INDEPENDENT_CODE");
compat.PropsString.insert("AUTOUIC_OPTIONS");
std::vector<cmTarget const*> const& deps =
this->GetLinkImplementationClosure(config);
for(std::vector<cmTarget const*>::const_iterator li = deps.begin();
li != deps.end(); ++li)
{ {
if (it->Target) #define CM_READ_COMPATIBLE_INTERFACE(X, x) \
{ if(const char* prop = (*li)->GetProperty("COMPATIBLE_INTERFACE_" #X)) \
tgts.push_back(it->Target); { \
std::vector<std::string> props; \
cmSystemTools::ExpandListArgument(prop, props); \
std::copy(props.begin(), props.end(), \
std::inserter(compat.Props##x, compat.Props##x.begin())); \
} }
CM_READ_COMPATIBLE_INTERFACE(BOOL, Bool)
CM_READ_COMPATIBLE_INTERFACE(STRING, String)
CM_READ_COMPATIBLE_INTERFACE(NUMBER_MIN, NumberMin)
CM_READ_COMPATIBLE_INTERFACE(NUMBER_MAX, NumberMax)
#undef CM_READ_COMPATIBLE_INTERFACE
} }
} }
return compat;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -6177,7 +6159,7 @@ cmTargetInternals::ComputeLinkInterfaceLibraries(
// to the link implementation. // to the link implementation.
{ {
// The link implementation is the default link interface. // The link implementation is the default link interface.
cmTarget::LinkImplementation const* impl = cmTarget::LinkImplementationLibraries const* impl =
thisTarget->GetLinkImplementationLibrariesInternal(config, headTarget); thisTarget->GetLinkImplementationLibrariesInternal(config, headTarget);
std::copy(impl->Libraries.begin(), impl->Libraries.end(), std::copy(impl->Libraries.begin(), impl->Libraries.end(),
std::back_inserter(iface.Libraries)); std::back_inserter(iface.Libraries));
@ -6294,7 +6276,7 @@ void cmTargetInternals::ComputeLinkInterface(cmTarget const* thisTarget,
|| thisTarget->PolicyStatusCMP0022 == cmPolicies::OLD) || thisTarget->PolicyStatusCMP0022 == cmPolicies::OLD)
{ {
// The link implementation is the default link interface. // The link implementation is the default link interface.
cmTarget::LinkImplementation const* cmTarget::LinkImplementationLibraries const*
impl = thisTarget->GetLinkImplementationLibrariesInternal(config, impl = thisTarget->GetLinkImplementationLibrariesInternal(config,
headTarget); headTarget);
iface.ImplementationIsInterface = true; iface.ImplementationIsInterface = true;
@ -6345,7 +6327,7 @@ void cmTargetInternals::AddInterfaceEntries(
cmTarget const* thisTarget, std::string const& config, cmTarget const* thisTarget, std::string const& config,
std::string const& prop, std::vector<TargetPropertyEntry*>& entries) std::string const& prop, std::vector<TargetPropertyEntry*>& entries)
{ {
if(cmTarget::LinkImplementation const* impl = if(cmTarget::LinkImplementationLibraries const* impl =
thisTarget->GetLinkImplementationLibraries(config)) thisTarget->GetLinkImplementationLibraries(config))
{ {
for (std::vector<cmLinkImplItem>::const_iterator for (std::vector<cmLinkImplItem>::const_iterator
@ -6383,7 +6365,7 @@ cmTarget::GetLinkImplementation(const std::string& config) const
if(!impl.LibrariesDone) if(!impl.LibrariesDone)
{ {
impl.LibrariesDone = true; impl.LibrariesDone = true;
this->ComputeLinkImplementation(config, impl, this); this->ComputeLinkImplementationLibraries(config, impl, this);
} }
if(!impl.LanguagesDone) if(!impl.LanguagesDone)
{ {
@ -6394,14 +6376,14 @@ cmTarget::GetLinkImplementation(const std::string& config) const
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
cmTarget::LinkImplementation const* cmTarget::LinkImplementationLibraries const*
cmTarget::GetLinkImplementationLibraries(const std::string& config) const cmTarget::GetLinkImplementationLibraries(const std::string& config) const
{ {
return this->GetLinkImplementationLibrariesInternal(config, this); return this->GetLinkImplementationLibrariesInternal(config, this);
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
cmTarget::LinkImplementation const* cmTarget::LinkImplementationLibraries const*
cmTarget::GetLinkImplementationLibrariesInternal(const std::string& config, cmTarget::GetLinkImplementationLibrariesInternal(const std::string& config,
cmTarget const* head) const cmTarget const* head) const
{ {
@ -6418,15 +6400,16 @@ cmTarget::GetLinkImplementationLibrariesInternal(const std::string& config,
if(!impl.LibrariesDone) if(!impl.LibrariesDone)
{ {
impl.LibrariesDone = true; impl.LibrariesDone = true;
this->ComputeLinkImplementation(config, impl, head); this->ComputeLinkImplementationLibraries(config, impl, head);
} }
return &impl; return &impl;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void cmTarget::ComputeLinkImplementation(const std::string& config, void
LinkImplementation& impl, cmTarget::ComputeLinkImplementationLibraries(const std::string& config,
cmTarget const* head) const LinkImplementation& impl,
cmTarget const* head) const
{ {
// Collect libraries directly linked in this configuration. // Collect libraries directly linked in this configuration.
for (std::vector<cmValueWithOrigin>::const_iterator for (std::vector<cmValueWithOrigin>::const_iterator

View File

@ -262,14 +262,16 @@ public:
/** The link interface specifies transitive library dependencies and /** The link interface specifies transitive library dependencies and
other information needed by targets that link to this target. */ other information needed by targets that link to this target. */
struct LinkInterface struct LinkInterfaceLibraries
{
// Libraries listed in the interface.
std::vector<cmLinkItem> Libraries;
};
struct LinkInterface: public LinkInterfaceLibraries
{ {
// Languages whose runtime libraries must be linked. // Languages whose runtime libraries must be linked.
std::vector<std::string> Languages; std::vector<std::string> Languages;
// Libraries listed in the interface.
std::vector<cmLinkItem> Libraries;
// Shared library dependencies needed for linking on some platforms. // Shared library dependencies needed for linking on some platforms.
std::vector<cmLinkItem> SharedDeps; std::vector<cmLinkItem> SharedDeps;
@ -290,22 +292,28 @@ public:
if the target cannot be linked. */ if the target cannot be linked. */
LinkInterface const* GetLinkInterface(const std::string& config, LinkInterface const* GetLinkInterface(const std::string& config,
cmTarget const* headTarget) const; cmTarget const* headTarget) const;
LinkInterface const* GetLinkInterfaceLibraries(const std::string& config, LinkInterfaceLibraries const*
cmTarget const* headTarget, GetLinkInterfaceLibraries(const std::string& config,
bool usage_requirements_only) const; cmTarget const* headTarget,
void GetTransitivePropertyTargets(const std::string& config, bool usage_requirements_only) const;
cmTarget const* headTarget,
std::vector<cmTarget const*> &libs) const;
std::vector<cmTarget const*> const& std::vector<cmTarget const*> const&
GetLinkImplementationClosure(const std::string& config) const; GetLinkImplementationClosure(const std::string& config) const;
struct CompatibleInterfaces
{
std::set<std::string> PropsBool;
std::set<std::string> PropsString;
std::set<std::string> PropsNumberMax;
std::set<std::string> PropsNumberMin;
};
CompatibleInterfaces const&
GetCompatibleInterfaces(std::string const& config) const;
/** The link implementation specifies the direct library /** The link implementation specifies the direct library
dependencies needed by the object files of the target. */ dependencies needed by the object files of the target. */
struct LinkImplementation struct LinkImplementationLibraries
{ {
// Languages whose runtime libraries must be linked.
std::vector<std::string> Languages;
// Libraries linked directly in this configuration. // Libraries linked directly in this configuration.
std::vector<cmLinkImplItem> Libraries; std::vector<cmLinkImplItem> Libraries;
@ -313,10 +321,15 @@ public:
// Needed only for OLD behavior of CMP0003. // Needed only for OLD behavior of CMP0003.
std::vector<cmLinkItem> WrongConfigLibraries; std::vector<cmLinkItem> WrongConfigLibraries;
}; };
struct LinkImplementation: public LinkImplementationLibraries
{
// Languages whose runtime libraries must be linked.
std::vector<std::string> Languages;
};
LinkImplementation const* LinkImplementation const*
GetLinkImplementation(const std::string& config) const; GetLinkImplementation(const std::string& config) const;
LinkImplementation const* LinkImplementationLibraries const*
GetLinkImplementationLibraries(const std::string& config) const; GetLinkImplementationLibraries(const std::string& config) const;
/** Link information from the transitive closure of the link /** Link information from the transitive closure of the link
@ -778,12 +791,12 @@ private:
GetImportLinkInterface(const std::string& config, cmTarget const* head, GetImportLinkInterface(const std::string& config, cmTarget const* head,
bool usage_requirements_only) const; bool usage_requirements_only) const;
LinkImplementation const* LinkImplementationLibraries const*
GetLinkImplementationLibrariesInternal(const std::string& config, GetLinkImplementationLibrariesInternal(const std::string& config,
cmTarget const* head) const; cmTarget const* head) const;
void ComputeLinkImplementation(const std::string& config, void ComputeLinkImplementationLibraries(const std::string& config,
LinkImplementation& impl, LinkImplementation& impl,
cmTarget const* head) const; cmTarget const* head) const;
void ComputeLinkImplementationLanguages(const std::string& config, void ComputeLinkImplementationLanguages(const std::string& config,
LinkImplementation& impl) const; LinkImplementation& impl) const;
void ComputeLinkClosure(const std::string& config, LinkClosure& lc) const; void ComputeLinkClosure(const std::string& config, LinkClosure& lc) const;