cmTarget: Extract a ComputeLinkInterfaceLibraries method.

When evaluating the SOURCES property, we will need to be able to access
the link libraries without accessing the link languages, as the languages
depend on the SOURCES.
This commit is contained in:
Stephen Kelly 2014-02-13 11:07:22 +01:00
parent 3bcb197c11
commit d93e1af292
2 changed files with 99 additions and 72 deletions

View File

@ -5202,7 +5202,9 @@ cmTarget::LinkInterface const* cmTarget::GetLinkInterface(const char* config,
{
// Compute the link interface for this configuration.
cmTargetInternals::OptionalLinkInterface iface;
iface.Exists = this->ComputeLinkInterface(config, iface, head);
const char* explicitLibraries =
this->ComputeLinkInterfaceLibraries(config, iface, head, iface.Exists);
this->ComputeLinkInterface(config, iface, head, explicitLibraries);
// Store the information for this configuration.
cmTargetInternals::LinkInterfaceMapType::value_type entry(key, iface);
@ -5273,8 +5275,10 @@ void cmTarget::GetTransitivePropertyTargets(const char* config,
}
//----------------------------------------------------------------------------
bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
cmTarget const* headTarget) const
const char* cmTarget::ComputeLinkInterfaceLibraries(const char* config,
LinkInterface& iface,
cmTarget const* headTarget,
bool &exists) const
{
// Construct the property name suffix for this configuration.
std::string suffix = "_";
@ -5350,8 +5354,10 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
(this->GetType() == cmTarget::EXECUTABLE ||
(this->GetType() == cmTarget::MODULE_LIBRARY)))
{
return false;
exists = false;
return 0;
}
exists = true;
if(explicitLibraries)
{
@ -5378,70 +5384,6 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
LinkImplementation const* impl = this->GetLinkImplementation(config,
headTarget);
iface.Libraries = impl->Libraries;
}
if(explicitLibraries)
{
if(this->GetType() == cmTarget::SHARED_LIBRARY
|| this->GetType() == cmTarget::STATIC_LIBRARY
|| this->GetType() == cmTarget::INTERFACE_LIBRARY)
{
// Shared libraries may have runtime implementation dependencies
// on other shared libraries that are not in the interface.
std::set<cmStdString> emitted;
for(std::vector<std::string>::const_iterator
li = iface.Libraries.begin(); li != iface.Libraries.end(); ++li)
{
emitted.insert(*li);
}
if (this->GetType() != cmTarget::INTERFACE_LIBRARY)
{
LinkImplementation const* impl = this->GetLinkImplementation(config,
headTarget);
for(std::vector<std::string>::const_iterator
li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li)
{
if(emitted.insert(*li).second)
{
if(cmTarget* tgt = this->Makefile->FindTargetToUse(*li))
{
// This is a runtime dependency on another shared library.
if(tgt->GetType() == cmTarget::SHARED_LIBRARY)
{
iface.SharedDeps.push_back(*li);
}
}
else
{
// TODO: Recognize shared library file names. Perhaps this
// should be moved to cmComputeLinkInformation, but that creates
// a chicken-and-egg problem since this list is needed for its
// construction.
}
}
}
if(this->LinkLanguagePropagatesToDependents())
{
// Targets using this archive need its language runtime libraries.
iface.Languages = impl->Languages;
}
}
}
}
else if (this->PolicyStatusCMP0022 == cmPolicies::WARN
|| this->PolicyStatusCMP0022 == cmPolicies::OLD)
{
// The link implementation is the default link interface.
LinkImplementation const* impl = this->GetLinkImplementation(config,
headTarget);
iface.ImplementationIsInterface = true;
iface.WrongConfigLibraries = impl->WrongConfigLibraries;
if(this->LinkLanguagePropagatesToDependents())
{
// Targets using this archive need its language runtime libraries.
iface.Languages = impl->Languages;
}
if(this->PolicyStatusCMP0022 == cmPolicies::WARN &&
!this->Internal->PolicyWarnedCMP0022)
{
@ -5506,9 +5448,90 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
}
}
}
return explicitLibraries;
}
//----------------------------------------------------------------------------
void cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
cmTarget const* headTarget,
const char* explicitLibraries) const
{
if(explicitLibraries)
{
if(this->GetType() == cmTarget::SHARED_LIBRARY
|| this->GetType() == cmTarget::STATIC_LIBRARY
|| this->GetType() == cmTarget::INTERFACE_LIBRARY)
{
// Shared libraries may have runtime implementation dependencies
// on other shared libraries that are not in the interface.
std::set<cmStdString> emitted;
for(std::vector<std::string>::const_iterator
li = iface.Libraries.begin(); li != iface.Libraries.end(); ++li)
{
emitted.insert(*li);
}
if (this->GetType() != cmTarget::INTERFACE_LIBRARY)
{
LinkImplementation const* impl = this->GetLinkImplementation(config,
headTarget);
for(std::vector<std::string>::const_iterator
li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li)
{
if(emitted.insert(*li).second)
{
if(cmTarget* tgt = this->Makefile->FindTargetToUse(*li))
{
// This is a runtime dependency on another shared library.
if(tgt->GetType() == cmTarget::SHARED_LIBRARY)
{
iface.SharedDeps.push_back(*li);
}
}
else
{
// TODO: Recognize shared library file names. Perhaps this
// should be moved to cmComputeLinkInformation, but that creates
// a chicken-and-egg problem since this list is needed for its
// construction.
}
}
}
if(this->LinkLanguagePropagatesToDependents())
{
// Targets using this archive need its language runtime libraries.
iface.Languages = impl->Languages;
}
}
}
}
else if (this->PolicyStatusCMP0022 == cmPolicies::WARN
|| this->PolicyStatusCMP0022 == cmPolicies::OLD)
{
// The link implementation is the default link interface.
LinkImplementation const* impl = this->GetLinkImplementation(config,
headTarget);
iface.ImplementationIsInterface = true;
iface.WrongConfigLibraries = impl->WrongConfigLibraries;
if(this->LinkLanguagePropagatesToDependents())
{
// Targets using this archive need its language runtime libraries.
iface.Languages = impl->Languages;
}
}
if(this->GetType() == cmTarget::STATIC_LIBRARY)
{
// Construct the property name suffix for this configuration.
std::string suffix = "_";
if(config && *config)
{
suffix += cmSystemTools::UpperCase(config);
}
else
{
suffix += "NOCONFIG";
}
// How many repetitions are needed if this library has cyclic
// dependencies?
std::string propName = "LINK_INTERFACE_MULTIPLICITY";
@ -5523,8 +5546,6 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
sscanf(reps, "%u", &iface.Multiplicity);
}
}
return true;
}
//----------------------------------------------------------------------------

View File

@ -690,8 +690,14 @@ private:
void CheckPropertyCompatibility(cmComputeLinkInformation *info,
const char* config) const;
bool ComputeLinkInterface(const char* config, LinkInterface& iface,
cmTarget const* head) const;
void ComputeLinkInterface(const char* config, LinkInterface& iface,
cmTarget const* head,
const char *explicitLibraries) const;
const char* ComputeLinkInterfaceLibraries(const char* config,
LinkInterface& iface,
cmTarget const* head,
bool &exists) const;
void ComputeLinkImplementation(const char* config,
LinkImplementation& impl,