summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Source/cmComputeLinkDepends.cxx21
-rw-r--r--Source/cmTarget.cxx163
-rw-r--r--Source/cmTarget.h16
3 files changed, 119 insertions, 81 deletions
diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index ef6926a..50a63eb 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -520,22 +520,15 @@ void cmComputeLinkDepends::AddVarLinkEntries(int depender_index,
void cmComputeLinkDepends::AddDirectLinkEntries()
{
// Add direct link dependencies in this configuration.
- int depender_index = -1;
- LinkLibraryVectorType const& libs=this->Target->GetOriginalLinkLibraries();
- std::vector<std::string> actual_libs;
- for(cmTarget::LinkLibraryVectorType::const_iterator li = libs.begin();
- li != libs.end(); ++li)
+ cmTarget::LinkImplementation const* impl =
+ this->Target->GetLinkImplementation(this->Config);
+ this->AddLinkEntries(-1, impl->Libraries);
+ for(std::vector<std::string>::const_iterator
+ wi = impl->WrongConfigLibraries.begin();
+ wi != impl->WrongConfigLibraries.end(); ++wi)
{
- if(li->second == cmTarget::GENERAL || li->second == this->LinkType)
- {
- actual_libs.push_back(li->first);
- }
- else if(this->OldLinkDirMode)
- {
- this->CheckWrongConfigItem(depender_index, li->first);
- }
+ this->CheckWrongConfigItem(-1, *wi);
}
- this->AddLinkEntries(depender_index, actual_libs);
}
//----------------------------------------------------------------------------
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
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index ad7e611..46c268e 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -255,6 +255,19 @@ public:
if the target cannot be linked. */
LinkInterface const* GetLinkInterface(const char* config);
+ /** The link implementation specifies the direct library
+ dependencies needed by the object files of the target. */
+ struct LinkImplementation
+ {
+ // Libraries linked directly in this configuration.
+ std::vector<std::string> Libraries;
+
+ // Libraries linked directly in other configurations.
+ // Needed only for OLD behavior of CMP0003.
+ std::vector<std::string> WrongConfigLibraries;
+ };
+ LinkImplementation const* GetLinkImplementation(const char* config);
+
/** Strip off leading and trailing whitespace from an item named in
the link dependencies of this target. */
std::string CheckCMP0004(std::string const& item);
@@ -520,6 +533,9 @@ private:
bool ComputeLinkInterface(const char* config, LinkInterface& iface);
+ void ComputeLinkImplementation(const char* config,
+ LinkImplementation& impl);
+
// The cmMakefile instance that owns this target. This should
// always be set.
cmMakefile* Makefile;