ENH: Simplify cmTarget link interface storage

This makes the LinkInterface struct a member of cmTarget, pimplizes the
config-to-interface map, and stores interface instances by value.
This commit is contained in:
Brad King 2009-07-07 09:45:29 -04:00
parent a608467180
commit 34f78ee552
4 changed files with 51 additions and 86 deletions

View File

@ -356,7 +356,7 @@ void cmComputeLinkDepends::FollowLinkEntry(BFSEntry const& qe)
if(entry.Target) if(entry.Target)
{ {
// Follow the target dependencies. // Follow the target dependencies.
if(cmTargetLinkInterface const* iface = if(cmTarget::LinkInterface const* iface =
entry.Target->GetLinkInterface(this->Config)) entry.Target->GetLinkInterface(this->Config))
{ {
// This target provides its own link interface information. // This target provides its own link interface information.
@ -431,7 +431,7 @@ void cmComputeLinkDepends::HandleSharedDependency(SharedDepEntry const& dep)
// Target items may have their own dependencies. // Target items may have their own dependencies.
if(entry.Target) if(entry.Target)
{ {
if(cmTargetLinkInterface const* iface = if(cmTarget::LinkInterface const* iface =
entry.Target->GetLinkInterface(this->Config)) entry.Target->GetLinkInterface(this->Config))
{ {
// We use just the shared dependencies, not the interface. // We use just the shared dependencies, not the interface.

View File

@ -150,7 +150,7 @@ cmExportFileGenerator
} }
// Add the transitive link dependencies for this configuration. // Add the transitive link dependencies for this configuration.
if(cmTargetLinkInterface const* iface = target->GetLinkInterface(config)) if(cmTarget::LinkInterface const* iface = target->GetLinkInterface(config))
{ {
this->SetImportLinkProperty(suffix, target, this->SetImportLinkProperty(suffix, target,
"IMPORTED_LINK_INTERFACE_LIBRARIES", "IMPORTED_LINK_INTERFACE_LIBRARIES",

View File

@ -49,6 +49,15 @@ public:
// The backtrace when the target was created. // The backtrace when the target was created.
cmListFileBacktrace Backtrace; cmListFileBacktrace Backtrace;
// Cache link interface computation from each configuration.
struct OptionalLinkInterface: public cmTarget::LinkInterface
{
OptionalLinkInterface(): Exists(false) {}
bool Exists;
};
typedef std::map<cmStdString, OptionalLinkInterface> LinkInterfaceMapType;
LinkInterfaceMapType LinkInterfaceMap;
}; };
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -3666,7 +3675,7 @@ void cmTarget::ComputeImportInfo(std::string const& desired_config,
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
cmTargetLinkInterface const* cmTarget::GetLinkInterface(const char* config) cmTarget::LinkInterface const* cmTarget::GetLinkInterface(const char* config)
{ {
// Imported targets have their own link interface. // Imported targets have their own link interface.
if(this->IsImported()) if(this->IsImported())
@ -3687,27 +3696,25 @@ cmTargetLinkInterface const* cmTarget::GetLinkInterface(const char* config)
} }
// Lookup any existing link interface for this configuration. // Lookup any existing link interface for this configuration.
std::map<cmStdString, cmTargetLinkInterface*>::iterator cmTargetInternals::LinkInterfaceMapType::iterator
i = this->LinkInterface.find(config?config:""); i = this->Internal->LinkInterfaceMap.find(config?config:"");
if(i == this->LinkInterface.end()) if(i == this->Internal->LinkInterfaceMap.end())
{ {
// Compute the link interface for this configuration. // Compute the link interface for this configuration.
cmsys::auto_ptr<cmTargetLinkInterface> cmTargetInternals::OptionalLinkInterface iface;
iface(this->ComputeLinkInterface(config)); iface.Exists = this->ComputeLinkInterface(config, iface);
// Store the information for this configuration. // Store the information for this configuration.
std::map<cmStdString, cmTargetLinkInterface*>::value_type cmTargetInternals::LinkInterfaceMapType::value_type
entry(config?config:"", 0); entry(config?config:"", iface);
i = this->LinkInterface.insert(entry).first; i = this->Internal->LinkInterfaceMap.insert(entry).first;
i->second = iface.release();
} }
return i->second; return i->second.Exists? &i->second : 0;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
cmsys::auto_ptr<cmTargetLinkInterface> bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface)
cmTarget::ComputeLinkInterface(const char* config)
{ {
// Construct the property name suffix for this configuration. // Construct the property name suffix for this configuration.
std::string suffix = "_"; std::string suffix = "_";
@ -3742,14 +3749,7 @@ cmTarget::ComputeLinkInterface(const char* config)
// was explicitly set, there is no link interface. // was explicitly set, there is no link interface.
if(!explicitLibraries && this->GetType() == cmTarget::EXECUTABLE) if(!explicitLibraries && this->GetType() == cmTarget::EXECUTABLE)
{ {
return cmsys::auto_ptr<cmTargetLinkInterface>(); return false;
}
// Allocate the interface.
cmsys::auto_ptr<cmTargetLinkInterface> iface(new cmTargetLinkInterface);
if(!iface.get())
{
return cmsys::auto_ptr<cmTargetLinkInterface>();
} }
// Is the link interface just the link implementation? // Is the link interface just the link implementation?
@ -3767,9 +3767,9 @@ cmTarget::ComputeLinkInterface(const char* config)
if(explicitLibraries) if(explicitLibraries)
{ {
// The interface libraries have been explicitly set. // The interface libraries have been explicitly set.
cmSystemTools::ExpandListArgument(explicitLibraries, iface->Libraries); cmSystemTools::ExpandListArgument(explicitLibraries, iface.Libraries);
for(std::vector<std::string>::const_iterator for(std::vector<std::string>::const_iterator
li = iface->Libraries.begin(); li != iface->Libraries.end(); ++li) li = iface.Libraries.begin(); li != iface.Libraries.end(); ++li)
{ {
emitted.insert(*li); emitted.insert(*li);
} }
@ -3799,7 +3799,7 @@ cmTarget::ComputeLinkInterface(const char* config)
// Support OLD behavior for CMP0003. // Support OLD behavior for CMP0003.
if(doLibraries && !emittedWrongConfig.insert(item).second) if(doLibraries && !emittedWrongConfig.insert(item).second)
{ {
iface->WrongConfigLibraries.push_back(item); iface.WrongConfigLibraries.push_back(item);
} }
continue; continue;
} }
@ -3814,14 +3814,14 @@ cmTarget::ComputeLinkInterface(const char* config)
if(doLibraries) if(doLibraries)
{ {
// This implementation dependency goes in the implicit interface. // This implementation dependency goes in the implicit interface.
iface->Libraries.push_back(item); iface.Libraries.push_back(item);
} }
else if(cmTarget* tgt = this->Makefile->FindTargetToUse(item.c_str())) else if(cmTarget* tgt = this->Makefile->FindTargetToUse(item.c_str()))
{ {
// This is a runtime dependency on another shared library. // This is a runtime dependency on another shared library.
if(tgt->GetType() == cmTarget::SHARED_LIBRARY) if(tgt->GetType() == cmTarget::SHARED_LIBRARY)
{ {
iface->SharedDeps.push_back(item); iface.SharedDeps.push_back(item);
} }
} }
else else
@ -3834,8 +3834,7 @@ cmTarget::ComputeLinkInterface(const char* config)
} }
} }
// Return the completed interface. return true;
return iface;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -3946,29 +3945,6 @@ cmTargetLinkInformationMap::~cmTargetLinkInformationMap()
} }
} }
//----------------------------------------------------------------------------
cmTargetLinkInterfaceMap
::cmTargetLinkInterfaceMap(cmTargetLinkInterfaceMap const& r): derived()
{
// Ideally cmTarget instances should never be copied. However until
// we can make a sweep to remove that, this copy constructor avoids
// allowing the resources (LinkInterface) from getting copied. In
// the worst case this will lead to extra cmTargetLinkInterface
// instances. We also enforce in debug mode that the map be emptied
// when copied.
static_cast<void>(r);
assert(r.empty());
}
//----------------------------------------------------------------------------
cmTargetLinkInterfaceMap::~cmTargetLinkInterfaceMap()
{
for(derived::iterator i = this->begin(); i != this->end(); ++i)
{
delete i->second;
}
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
cmTargetInternalPointer::cmTargetInternalPointer() cmTargetInternalPointer::cmTargetInternalPointer()
{ {

View File

@ -39,28 +39,6 @@ struct cmTargetLinkInformationMap:
~cmTargetLinkInformationMap(); ~cmTargetLinkInformationMap();
}; };
struct cmTargetLinkInterface
{
// Libraries listed in the interface.
std::vector<std::string> Libraries;
// Shared library dependencies needed for linking on some platforms.
std::vector<std::string> SharedDeps;
// Libraries listed for other configurations.
// Needed only for OLD behavior of CMP0003.
std::vector<std::string> WrongConfigLibraries;
};
struct cmTargetLinkInterfaceMap:
public std::map<cmStdString, cmTargetLinkInterface*>
{
typedef std::map<cmStdString, cmTargetLinkInterface*> derived;
cmTargetLinkInterfaceMap() {}
cmTargetLinkInterfaceMap(cmTargetLinkInterfaceMap const& r);
~cmTargetLinkInterfaceMap();
};
class cmTargetInternals; class cmTargetInternals;
class cmTargetInternalPointer class cmTargetInternalPointer
{ {
@ -258,11 +236,25 @@ public:
bool IsImported() const {return this->IsImportedTarget;} bool IsImported() const {return this->IsImportedTarget;}
/** Get the library interface dependencies. This is the set of /** The link interface specifies the transitive librarty
libraries from which something that links to this target may dependencies and other information needed by targets that link
also receive symbols. Returns 0 if the user has not specified to this target. */
such dependencies or for static libraries. */ struct LinkInterface
cmTargetLinkInterface const* GetLinkInterface(const char* config); {
// Libraries listed in the interface.
std::vector<std::string> Libraries;
// Shared library dependencies needed for linking on some platforms.
std::vector<std::string> SharedDeps;
// Libraries listed for other configurations.
// Needed only for OLD behavior of CMP0003.
std::vector<std::string> WrongConfigLibraries;
};
/** Get the link interface for the given configuration. Returns 0
if the target cannot be linked. */
LinkInterface const* GetLinkInterface(const char* config);
/** Strip off leading and trailing whitespace from an item named in /** Strip off leading and trailing whitespace from an item named in
the link dependencies of this target. */ the link dependencies of this target. */
@ -533,7 +525,7 @@ private:
std::string Location; std::string Location;
std::string SOName; std::string SOName;
std::string ImportLibrary; std::string ImportLibrary;
cmTargetLinkInterface LinkInterface; cmTarget::LinkInterface LinkInterface;
}; };
typedef std::map<cmStdString, ImportInfo> ImportInfoMapType; typedef std::map<cmStdString, ImportInfo> ImportInfoMapType;
ImportInfoMapType ImportInfoMap; ImportInfoMapType ImportInfoMap;
@ -542,10 +534,7 @@ private:
cmTargetLinkInformationMap LinkInformation; cmTargetLinkInformationMap LinkInformation;
// Link interface. bool ComputeLinkInterface(const char* config, LinkInterface& iface);
cmsys::auto_ptr<cmTargetLinkInterface>
ComputeLinkInterface(const char* config);
cmTargetLinkInterfaceMap LinkInterface;
// The cmMakefile instance that owns this target. This should // The cmMakefile instance that owns this target. This should
// always be set. // always be set.