cmTarget: Avoid computing languages when computing transitive targets.
For the OLD CMP0022 behavior, we need to treat the implementation as the interface when computing the interface libraries. Make it possible to do that without computing the link languages by adding a new GetLinkImplementationLibraries method. Extend the existing GetLinkImplementation method to populate the languages if the libraries have already been computed and cached. Change GetTransitivePropertyTargets to invoke GetLinkInterfaceLibraries instead of GetLinkInterface. This is key, as it is a method called by cmGeneratorExpressionEvaluator. Change the cmGeneratorExpressionEvaluator to invoke GetLinkImplementationLibraries instead of GetLinkImplementation.
This commit is contained in:
parent
01bca553b8
commit
b8b99cc1e5
@ -1099,9 +1099,9 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
|
|||||||
else if (std::find_if(transBegin, transEnd,
|
else if (std::find_if(transBegin, transEnd,
|
||||||
cmStrCmp(interfacePropertyName)) != transEnd)
|
cmStrCmp(interfacePropertyName)) != transEnd)
|
||||||
{
|
{
|
||||||
const cmTarget::LinkImplementation *impl = target->GetLinkImplementation(
|
const cmTarget::LinkImplementation *impl
|
||||||
context->Config,
|
= target->GetLinkImplementationLibraries(context->Config,
|
||||||
headTarget);
|
headTarget);
|
||||||
if(impl)
|
if(impl)
|
||||||
{
|
{
|
||||||
linkedTargetsContent =
|
linkedTargetsContent =
|
||||||
|
@ -96,8 +96,11 @@ public:
|
|||||||
// Cache link interface computation from each configuration.
|
// Cache link interface computation from each configuration.
|
||||||
struct OptionalLinkInterface: public cmTarget::LinkInterface
|
struct OptionalLinkInterface: public cmTarget::LinkInterface
|
||||||
{
|
{
|
||||||
OptionalLinkInterface(): Exists(false) {}
|
OptionalLinkInterface():
|
||||||
|
Exists(false), Complete(false), ExplicitLibraries(0) {}
|
||||||
bool Exists;
|
bool Exists;
|
||||||
|
bool Complete;
|
||||||
|
const char* ExplicitLibraries;
|
||||||
};
|
};
|
||||||
void ComputeLinkInterface(cmTarget const* thisTarget,
|
void ComputeLinkInterface(cmTarget const* thisTarget,
|
||||||
const char* config, OptionalLinkInterface& iface,
|
const char* config, OptionalLinkInterface& iface,
|
||||||
@ -5207,17 +5210,70 @@ cmTarget::LinkInterface const* cmTarget::GetLinkInterface(const char* config,
|
|||||||
{
|
{
|
||||||
// Compute the link interface for this configuration.
|
// Compute the link interface for this configuration.
|
||||||
cmTargetInternals::OptionalLinkInterface iface;
|
cmTargetInternals::OptionalLinkInterface iface;
|
||||||
const char* explicitLibraries =
|
iface.ExplicitLibraries =
|
||||||
this->ComputeLinkInterfaceLibraries(config, iface, head, iface.Exists);
|
this->ComputeLinkInterfaceLibraries(config, iface, head, iface.Exists);
|
||||||
this->Internal->ComputeLinkInterface(this, config, iface,
|
if (iface.Exists)
|
||||||
head, explicitLibraries);
|
{
|
||||||
|
this->Internal->ComputeLinkInterface(this, config, iface,
|
||||||
|
head, iface.ExplicitLibraries);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store the information for this configuration.
|
||||||
|
cmTargetInternals::LinkInterfaceMapType::value_type entry(key, iface);
|
||||||
|
i = this->Internal->LinkInterfaceMap.insert(entry).first;
|
||||||
|
}
|
||||||
|
else if(!i->second.Complete && i->second.Exists)
|
||||||
|
{
|
||||||
|
this->Internal->ComputeLinkInterface(this, config, i->second, head,
|
||||||
|
i->second.ExplicitLibraries);
|
||||||
|
}
|
||||||
|
|
||||||
|
return i->second.Exists ? &i->second : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
cmTarget::LinkInterface const*
|
||||||
|
cmTarget::GetLinkInterfaceLibraries(const char* config,
|
||||||
|
cmTarget const* head) const
|
||||||
|
{
|
||||||
|
// Imported targets have their own link interface.
|
||||||
|
if(this->IsImported())
|
||||||
|
{
|
||||||
|
if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, head))
|
||||||
|
{
|
||||||
|
return &info->LinkInterface;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Link interfaces are not supported for executables that do not
|
||||||
|
// export symbols.
|
||||||
|
if(this->GetType() == cmTarget::EXECUTABLE &&
|
||||||
|
!this->IsExecutableWithExports())
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lookup any existing link interface for this configuration.
|
||||||
|
TargetConfigPair key(head, cmSystemTools::UpperCase(config? config : ""));
|
||||||
|
|
||||||
|
cmTargetInternals::LinkInterfaceMapType::iterator
|
||||||
|
i = this->Internal->LinkInterfaceMap.find(key);
|
||||||
|
if(i == this->Internal->LinkInterfaceMap.end())
|
||||||
|
{
|
||||||
|
// Compute the link interface for this configuration.
|
||||||
|
cmTargetInternals::OptionalLinkInterface iface;
|
||||||
|
iface.ExplicitLibraries = this->ComputeLinkInterfaceLibraries(config,
|
||||||
|
iface,
|
||||||
|
head,
|
||||||
|
iface.Exists);
|
||||||
|
|
||||||
// Store the information for this configuration.
|
// Store the information for this configuration.
|
||||||
cmTargetInternals::LinkInterfaceMapType::value_type entry(key, iface);
|
cmTargetInternals::LinkInterfaceMapType::value_type entry(key, iface);
|
||||||
i = this->Internal->LinkInterfaceMap.insert(entry).first;
|
i = this->Internal->LinkInterfaceMap.insert(entry).first;
|
||||||
}
|
}
|
||||||
|
|
||||||
return i->second.Exists? &i->second : 0;
|
return i->second.Exists ? &i->second : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@ -5225,8 +5281,8 @@ void cmTarget::GetTransitivePropertyTargets(const char* config,
|
|||||||
cmTarget const* headTarget,
|
cmTarget const* headTarget,
|
||||||
std::vector<cmTarget*> &tgts) const
|
std::vector<cmTarget*> &tgts) const
|
||||||
{
|
{
|
||||||
cmTarget::LinkInterface const* iface = this->GetLinkInterface(config,
|
cmTarget::LinkInterface const* iface
|
||||||
headTarget);
|
= this->GetLinkInterfaceLibraries(config, headTarget);
|
||||||
if (!iface)
|
if (!iface)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -5387,8 +5443,8 @@ const char* cmTarget::ComputeLinkInterfaceLibraries(const char* config,
|
|||||||
// to the link implementation.
|
// to the link implementation.
|
||||||
{
|
{
|
||||||
// The link implementation is the default link interface.
|
// The link implementation is the default link interface.
|
||||||
LinkImplementation const* impl = this->GetLinkImplementation(config,
|
LinkImplementation const* impl =
|
||||||
headTarget);
|
this->GetLinkImplementationLibraries(config, headTarget);
|
||||||
iface.Libraries = impl->Libraries;
|
iface.Libraries = impl->Libraries;
|
||||||
if(this->PolicyStatusCMP0022 == cmPolicies::WARN &&
|
if(this->PolicyStatusCMP0022 == cmPolicies::WARN &&
|
||||||
!this->Internal->PolicyWarnedCMP0022)
|
!this->Internal->PolicyWarnedCMP0022)
|
||||||
@ -5554,6 +5610,7 @@ void cmTargetInternals::ComputeLinkInterface(cmTarget const* thisTarget,
|
|||||||
sscanf(reps, "%u", &iface.Multiplicity);
|
sscanf(reps, "%u", &iface.Multiplicity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
iface.Complete = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@ -5578,6 +5635,40 @@ cmTarget::GetLinkImplementation(const char* config, cmTarget const* head) const
|
|||||||
this->ComputeLinkImplementation(config, impl, head);
|
this->ComputeLinkImplementation(config, impl, head);
|
||||||
this->ComputeLinkImplementationLanguages(impl);
|
this->ComputeLinkImplementationLanguages(impl);
|
||||||
|
|
||||||
|
// Store the information for this configuration.
|
||||||
|
cmTargetInternals::LinkImplMapType::value_type entry(key, impl);
|
||||||
|
i = this->Internal->LinkImplMap.insert(entry).first;
|
||||||
|
}
|
||||||
|
else if (i->second.Languages.empty())
|
||||||
|
{
|
||||||
|
this->ComputeLinkImplementationLanguages(i->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
return &i->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
cmTarget::LinkImplementation const*
|
||||||
|
cmTarget::GetLinkImplementationLibraries(const char* config,
|
||||||
|
cmTarget const* head) const
|
||||||
|
{
|
||||||
|
// There is no link implementation for imported targets.
|
||||||
|
if(this->IsImported())
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lookup any existing link implementation for this configuration.
|
||||||
|
TargetConfigPair key(head, cmSystemTools::UpperCase(config? config : ""));
|
||||||
|
|
||||||
|
cmTargetInternals::LinkImplMapType::iterator
|
||||||
|
i = this->Internal->LinkImplMap.find(key);
|
||||||
|
if(i == this->Internal->LinkImplMap.end())
|
||||||
|
{
|
||||||
|
// Compute the link implementation for this configuration.
|
||||||
|
LinkImplementation impl;
|
||||||
|
this->ComputeLinkImplementation(config, impl, head);
|
||||||
|
|
||||||
// Store the information for this configuration.
|
// Store the information for this configuration.
|
||||||
cmTargetInternals::LinkImplMapType::value_type entry(key, impl);
|
cmTargetInternals::LinkImplMapType::value_type entry(key, impl);
|
||||||
i = this->Internal->LinkImplMap.insert(entry).first;
|
i = this->Internal->LinkImplMap.insert(entry).first;
|
||||||
|
@ -264,6 +264,8 @@ public:
|
|||||||
if the target cannot be linked. */
|
if the target cannot be linked. */
|
||||||
LinkInterface const* GetLinkInterface(const char* config,
|
LinkInterface const* GetLinkInterface(const char* config,
|
||||||
cmTarget const* headTarget) const;
|
cmTarget const* headTarget) const;
|
||||||
|
LinkInterface const* GetLinkInterfaceLibraries(const char* config,
|
||||||
|
cmTarget const* headTarget) const;
|
||||||
void GetTransitivePropertyTargets(const char* config,
|
void GetTransitivePropertyTargets(const char* config,
|
||||||
cmTarget const* headTarget,
|
cmTarget const* headTarget,
|
||||||
std::vector<cmTarget*> &libs) const;
|
std::vector<cmTarget*> &libs) const;
|
||||||
@ -285,6 +287,9 @@ public:
|
|||||||
LinkImplementation const* GetLinkImplementation(const char* config,
|
LinkImplementation const* GetLinkImplementation(const char* config,
|
||||||
cmTarget const* head) const;
|
cmTarget const* head) const;
|
||||||
|
|
||||||
|
LinkImplementation const* GetLinkImplementationLibraries(const char* config,
|
||||||
|
cmTarget const* head) const;
|
||||||
|
|
||||||
/** Link information from the transitive closure of the link
|
/** Link information from the transitive closure of the link
|
||||||
implementation and the interfaces of its dependencies. */
|
implementation and the interfaces of its dependencies. */
|
||||||
struct LinkClosure
|
struct LinkClosure
|
||||||
|
Loading…
x
Reference in New Issue
Block a user