diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx index 52f4cc83a..ef6926a88 100644 --- a/Source/cmComputeLinkDepends.cxx +++ b/Source/cmComputeLinkDepends.cxx @@ -356,7 +356,7 @@ void cmComputeLinkDepends::FollowLinkEntry(BFSEntry const& qe) if(entry.Target) { // Follow the target dependencies. - if(cmTargetLinkInterface const* iface = + if(cmTarget::LinkInterface const* iface = entry.Target->GetLinkInterface(this->Config)) { // 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. if(entry.Target) { - if(cmTargetLinkInterface const* iface = + if(cmTarget::LinkInterface const* iface = entry.Target->GetLinkInterface(this->Config)) { // We use just the shared dependencies, not the interface. diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index f231e3369..9c603c1a6 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -150,7 +150,7 @@ cmExportFileGenerator } // 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, "IMPORTED_LINK_INTERFACE_LIBRARIES", diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 588327411..4643d30c0 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -49,6 +49,15 @@ public: // The backtrace when the target was created. cmListFileBacktrace Backtrace; + + // Cache link interface computation from each configuration. + struct OptionalLinkInterface: public cmTarget::LinkInterface + { + OptionalLinkInterface(): Exists(false) {} + bool Exists; + }; + typedef std::map 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. if(this->IsImported()) @@ -3687,27 +3696,25 @@ cmTargetLinkInterface const* cmTarget::GetLinkInterface(const char* config) } // Lookup any existing link interface for this configuration. - std::map::iterator - i = this->LinkInterface.find(config?config:""); - if(i == this->LinkInterface.end()) + cmTargetInternals::LinkInterfaceMapType::iterator + i = this->Internal->LinkInterfaceMap.find(config?config:""); + if(i == this->Internal->LinkInterfaceMap.end()) { // Compute the link interface for this configuration. - cmsys::auto_ptr - iface(this->ComputeLinkInterface(config)); + cmTargetInternals::OptionalLinkInterface iface; + iface.Exists = this->ComputeLinkInterface(config, iface); // Store the information for this configuration. - std::map::value_type - entry(config?config:"", 0); - i = this->LinkInterface.insert(entry).first; - i->second = iface.release(); + cmTargetInternals::LinkInterfaceMapType::value_type + entry(config?config:"", iface); + i = this->Internal->LinkInterfaceMap.insert(entry).first; } - return i->second; + return i->second.Exists? &i->second : 0; } //---------------------------------------------------------------------------- -cmsys::auto_ptr -cmTarget::ComputeLinkInterface(const char* config) +bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface) { // Construct the property name suffix for this configuration. std::string suffix = "_"; @@ -3742,14 +3749,7 @@ cmTarget::ComputeLinkInterface(const char* config) // was explicitly set, there is no link interface. if(!explicitLibraries && this->GetType() == cmTarget::EXECUTABLE) { - return cmsys::auto_ptr(); - } - - // Allocate the interface. - cmsys::auto_ptr iface(new cmTargetLinkInterface); - if(!iface.get()) - { - return cmsys::auto_ptr(); + return false; } // Is the link interface just the link implementation? @@ -3767,9 +3767,9 @@ cmTarget::ComputeLinkInterface(const char* config) if(explicitLibraries) { // The interface libraries have been explicitly set. - cmSystemTools::ExpandListArgument(explicitLibraries, iface->Libraries); + cmSystemTools::ExpandListArgument(explicitLibraries, iface.Libraries); for(std::vector::const_iterator - li = iface->Libraries.begin(); li != iface->Libraries.end(); ++li) + li = iface.Libraries.begin(); li != iface.Libraries.end(); ++li) { emitted.insert(*li); } @@ -3799,7 +3799,7 @@ cmTarget::ComputeLinkInterface(const char* config) // Support OLD behavior for CMP0003. if(doLibraries && !emittedWrongConfig.insert(item).second) { - iface->WrongConfigLibraries.push_back(item); + iface.WrongConfigLibraries.push_back(item); } continue; } @@ -3814,14 +3814,14 @@ cmTarget::ComputeLinkInterface(const char* config) if(doLibraries) { // 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())) { // This is a runtime dependency on another shared library. if(tgt->GetType() == cmTarget::SHARED_LIBRARY) { - iface->SharedDeps.push_back(item); + iface.SharedDeps.push_back(item); } } else @@ -3834,8 +3834,7 @@ cmTarget::ComputeLinkInterface(const char* config) } } - // Return the completed interface. - return iface; + return true; } //---------------------------------------------------------------------------- @@ -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(r); - assert(r.empty()); -} - -//---------------------------------------------------------------------------- -cmTargetLinkInterfaceMap::~cmTargetLinkInterfaceMap() -{ - for(derived::iterator i = this->begin(); i != this->end(); ++i) - { - delete i->second; - } -} - //---------------------------------------------------------------------------- cmTargetInternalPointer::cmTargetInternalPointer() { diff --git a/Source/cmTarget.h b/Source/cmTarget.h index a3e243946..8a8b30ef7 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -39,28 +39,6 @@ struct cmTargetLinkInformationMap: ~cmTargetLinkInformationMap(); }; -struct cmTargetLinkInterface -{ - // Libraries listed in the interface. - std::vector Libraries; - - // Shared library dependencies needed for linking on some platforms. - std::vector SharedDeps; - - // Libraries listed for other configurations. - // Needed only for OLD behavior of CMP0003. - std::vector WrongConfigLibraries; -}; - -struct cmTargetLinkInterfaceMap: - public std::map -{ - typedef std::map derived; - cmTargetLinkInterfaceMap() {} - cmTargetLinkInterfaceMap(cmTargetLinkInterfaceMap const& r); - ~cmTargetLinkInterfaceMap(); -}; - class cmTargetInternals; class cmTargetInternalPointer { @@ -258,11 +236,25 @@ public: bool IsImported() const {return this->IsImportedTarget;} - /** Get the library interface dependencies. This is the set of - libraries from which something that links to this target may - also receive symbols. Returns 0 if the user has not specified - such dependencies or for static libraries. */ - cmTargetLinkInterface const* GetLinkInterface(const char* config); + /** The link interface specifies the transitive librarty + dependencies and other information needed by targets that link + to this target. */ + struct LinkInterface + { + // Libraries listed in the interface. + std::vector Libraries; + + // Shared library dependencies needed for linking on some platforms. + std::vector SharedDeps; + + // Libraries listed for other configurations. + // Needed only for OLD behavior of CMP0003. + std::vector 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 the link dependencies of this target. */ @@ -533,7 +525,7 @@ private: std::string Location; std::string SOName; std::string ImportLibrary; - cmTargetLinkInterface LinkInterface; + cmTarget::LinkInterface LinkInterface; }; typedef std::map ImportInfoMapType; ImportInfoMapType ImportInfoMap; @@ -542,10 +534,7 @@ private: cmTargetLinkInformationMap LinkInformation; - // Link interface. - cmsys::auto_ptr - ComputeLinkInterface(const char* config); - cmTargetLinkInterfaceMap LinkInterface; + bool ComputeLinkInterface(const char* config, LinkInterface& iface); // The cmMakefile instance that owns this target. This should // always be set.