summaryrefslogtreecommitdiffstats
path: root/Source/cmTarget.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmTarget.cxx')
-rw-r--r--Source/cmTarget.cxx163
1 files changed, 96 insertions, 67 deletions
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 50a6ea9..c7fd6b0 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -81,6 +81,10 @@ public:
typedef std::map<cmStdString, cmTarget::ImportInfo> ImportInfoMapType;
ImportInfoMapType ImportInfoMap;
+
+ // Cache link implementation computation from each configuration.
+ typedef std::map<cmStdString, cmTarget::LinkImplementation> LinkImplMapType;
+ LinkImplMapType LinkImplMap;
};
//----------------------------------------------------------------------------
@@ -3777,92 +3781,117 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface)
return false;
}
- // Is the link interface just the link implementation?
- bool doLibraries = !explicitLibraries;
-
- // Do we need to construct a list of shared library dependencies not
- // included in the interface?
- bool doSharedDeps = (explicitLibraries &&
- this->GetType() == cmTarget::SHARED_LIBRARY);
-
- // Keep track of what libraries have been emitted.
- std::set<cmStdString> emitted;
- std::set<cmStdString> emittedWrongConfig;
-
if(explicitLibraries)
{
// The interface libraries have been explicitly set.
cmSystemTools::ExpandListArgument(explicitLibraries, iface.Libraries);
- for(std::vector<std::string>::const_iterator
- li = iface.Libraries.begin(); li != iface.Libraries.end(); ++li)
- {
- emitted.insert(*li);
- }
- }
- if(doLibraries || doSharedDeps)
- {
- // Compute which library configuration to link.
- cmTarget::LinkLibraryType linkType = this->ComputeLinkType(config);
-
- // Construct the list of libs linked for this configuration.
- cmTarget::LinkLibraryVectorType const& llibs =
- this->GetOriginalLinkLibraries();
- for(cmTarget::LinkLibraryVectorType::const_iterator li = llibs.begin();
- li != llibs.end(); ++li)
+ if(this->GetType() == cmTarget::SHARED_LIBRARY)
{
- // Skip entries that resolve to the target itself or are empty.
- std::string item = this->CheckCMP0004(li->first);
- if(item == this->GetName() || item.empty())
+ // 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)
{
- continue;
+ emitted.insert(*li);
}
-
- // Skip entries not meant for this configuration.
- if(li->second != cmTarget::GENERAL && li->second != linkType)
+ LinkImplementation const* impl = this->GetLinkImplementation(config);
+ for(std::vector<std::string>::const_iterator
+ li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li)
{
- // Support OLD behavior for CMP0003.
- if(doLibraries && emittedWrongConfig.insert(item).second)
+ if(emitted.insert(*li).second)
{
- iface.WrongConfigLibraries.push_back(item);
- }
- continue;
- }
-
- // Skip entries that have already been emitted.
- if(!emitted.insert(item).second)
- {
- continue;
- }
-
- // Emit this item.
- if(doLibraries)
- {
- // This implementation dependency goes in the implicit interface.
- iface.Libraries.push_back(item);
- }
- else if(cmTarget* tgt = this->Makefile->FindTargetToUse(item.c_str()))
- {
- // This is a runtime dependency on another shared library.
- if(tgt->GetType() == cmTarget::SHARED_LIBRARY)
- {
- iface.SharedDeps.push_back(item);
+ if(cmTarget* tgt = this->Makefile->FindTargetToUse(li->c_str()))
+ {
+ // 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.
+ }
}
}
- 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.
- }
}
}
+ else
+ {
+ // The link implementation is the default link interface.
+ LinkImplementation const* impl = this->GetLinkImplementation(config);
+ iface.Libraries = impl->Libraries;
+ iface.WrongConfigLibraries = impl->WrongConfigLibraries;
+ }
return true;
}
//----------------------------------------------------------------------------
+cmTarget::LinkImplementation const*
+cmTarget::GetLinkImplementation(const char* config)
+{
+ // There is no link implementation for imported targets.
+ if(this->IsImported())
+ {
+ return 0;
+ }
+
+ // Lookup any existing link implementation for this configuration.
+ std::string key = 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);
+
+ // Store the information for this configuration.
+ cmTargetInternals::LinkImplMapType::value_type entry(key, impl);
+ i = this->Internal->LinkImplMap.insert(entry).first;
+ }
+
+ return &i->second;
+}
+
+//----------------------------------------------------------------------------
+void cmTarget::ComputeLinkImplementation(const char* config,
+ LinkImplementation& impl)
+{
+ // Compute which library configuration to link.
+ cmTarget::LinkLibraryType linkType = this->ComputeLinkType(config);
+
+ LinkLibraryVectorType const& llibs = this->GetOriginalLinkLibraries();
+ for(cmTarget::LinkLibraryVectorType::const_iterator li = llibs.begin();
+ li != llibs.end(); ++li)
+ {
+ // Skip entries that resolve to the target itself or are empty.
+ std::string item = this->CheckCMP0004(li->first);
+ if(item == this->GetName() || item.empty())
+ {
+ continue;
+ }
+
+ if(li->second == cmTarget::GENERAL || li->second == linkType)
+ {
+ // The entry is meant for this configuration.
+ impl.Libraries.push_back(item);
+ }
+ else
+ {
+ // Support OLD behavior for CMP0003.
+ impl.WrongConfigLibraries.push_back(item);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
std::string cmTarget::CheckCMP0004(std::string const& item)
{
// Strip whitespace off the library names because we used to do this