diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx index 406761fc9..52f4cc83a 100644 --- a/Source/cmComputeLinkDepends.cxx +++ b/Source/cmComputeLinkDepends.cxx @@ -223,7 +223,7 @@ std::vector const& cmComputeLinkDepends::Compute() { // Follow the link dependencies of the target to be linked. - this->AddTargetLinkEntries(-1, this->Target->GetOriginalLinkLibraries()); + this->AddDirectLinkEntries(); // Complete the breadth-first search of dependencies. while(!this->BFSQueue.empty()) @@ -364,13 +364,14 @@ void cmComputeLinkDepends::FollowLinkEntry(BFSEntry const& qe) // Handle dependent shared libraries. this->QueueSharedDependencies(depender_index, iface->SharedDeps); - } - else if(!entry.Target->IsImported() && - entry.Target->GetType() != cmTarget::EXECUTABLE) - { - // Use the target's link implementation as the interface. - this->AddTargetLinkEntries(depender_index, - entry.Target->GetOriginalLinkLibraries()); + + // Support for CMP0003. + for(std::vector::const_iterator + oi = iface->WrongConfigLibraries.begin(); + oi != iface->WrongConfigLibraries.end(); ++oi) + { + this->CheckWrongConfigItem(depender_index, *oi); + } } } else @@ -516,11 +517,11 @@ void cmComputeLinkDepends::AddVarLinkEntries(int depender_index, } //---------------------------------------------------------------------------- -void -cmComputeLinkDepends::AddTargetLinkEntries(int depender_index, - LinkLibraryVectorType const& libs) +void cmComputeLinkDepends::AddDirectLinkEntries() { - // Look for entries meant for this configuration. + // Add direct link dependencies in this configuration. + int depender_index = -1; + LinkLibraryVectorType const& libs=this->Target->GetOriginalLinkLibraries(); std::vector actual_libs; for(cmTarget::LinkLibraryVectorType::const_iterator li = libs.begin(); li != libs.end(); ++li) @@ -534,8 +535,6 @@ cmComputeLinkDepends::AddTargetLinkEntries(int depender_index, this->CheckWrongConfigItem(depender_index, li->first); } } - - // Add these entries. this->AddLinkEntries(depender_index, actual_libs); } diff --git a/Source/cmComputeLinkDepends.h b/Source/cmComputeLinkDepends.h index c48447a5b..d6920101a 100644 --- a/Source/cmComputeLinkDepends.h +++ b/Source/cmComputeLinkDepends.h @@ -83,8 +83,7 @@ private: AllocateLinkEntry(std::string const& item); int AddLinkEntry(int depender_index, std::string const& item); void AddVarLinkEntries(int depender_index, const char* value); - void AddTargetLinkEntries(int depender_index, - LinkLibraryVectorType const& libs); + void AddDirectLinkEntries(); void AddLinkEntries(int depender_index, std::vector const& libs); cmTarget* FindTargetToLink(int depender_index, const char* name); diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index dc2efc53f..f231e3369 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -150,10 +150,8 @@ cmExportFileGenerator } // Add the transitive link dependencies for this configuration. - if(cmTargetLinkInterface const* iface = - target->GetLinkInterface(config)) + if(cmTargetLinkInterface const* iface = target->GetLinkInterface(config)) { - // This target provides a link interface, so use it. this->SetImportLinkProperty(suffix, target, "IMPORTED_LINK_INTERFACE_LIBRARIES", iface->Libraries, properties); @@ -161,47 +159,6 @@ cmExportFileGenerator "IMPORTED_LINK_DEPENDENT_LIBRARIES", iface->SharedDeps, properties); } - else if(target->GetType() == cmTarget::STATIC_LIBRARY || - target->GetType() == cmTarget::SHARED_LIBRARY) - { - // The default link interface for static and shared libraries is - // their link implementation library list. - this->SetImportLinkProperties(config, suffix, target, properties); - } -} - -//---------------------------------------------------------------------------- -void -cmExportFileGenerator -::SetImportLinkProperties(const char* config, std::string const& suffix, - cmTarget* target, ImportPropertyMap& properties) -{ - // Compute which library configuration to link. - cmTarget::LinkLibraryType linkType = target->ComputeLinkType(config); - - // Construct the list of libs linked for this configuration. - std::vector actual_libs; - cmTarget::LinkLibraryVectorType const& libs = - target->GetOriginalLinkLibraries(); - for(cmTarget::LinkLibraryVectorType::const_iterator li = libs.begin(); - li != libs.end(); ++li) - { - // Skip entries that will resolve to the target itself, are empty, - // or are not meant for this configuration. - if(li->first == target->GetName() || li->first.empty() || - !(li->second == cmTarget::GENERAL || li->second == linkType)) - { - continue; - } - - // Store this entry. - actual_libs.push_back(li->first); - } - - // Store the entries in the property. - this->SetImportLinkProperty(suffix, target, - "IMPORTED_LINK_INTERFACE_LIBRARIES", - actual_libs, properties); } //---------------------------------------------------------------------------- diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h index 66aed56f8..1901d4b7f 100644 --- a/Source/cmExportFileGenerator.h +++ b/Source/cmExportFileGenerator.h @@ -67,9 +67,6 @@ protected: void SetImportDetailProperties(const char* config, std::string const& suffix, cmTarget* target, ImportPropertyMap& properties); - void SetImportLinkProperties(const char* config, - std::string const& suffix, cmTarget* target, - ImportPropertyMap& properties); void SetImportLinkProperty(std::string const& suffix, cmTarget* target, const char* propName, std::vector const& libs, diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 6cddbe338..ca6440268 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -3682,10 +3682,10 @@ cmTargetLinkInterface const* cmTarget::GetLinkInterface(const char* config) return 0; } - // Link interfaces are supported only for shared libraries and - // executables that export symbols. - if((this->GetType() != cmTarget::SHARED_LIBRARY && - !this->IsExecutableWithExports())) + // Link interfaces are not supported for executables that do not + // export symbols. + if(this->GetType() == cmTarget::EXECUTABLE && + !this->IsExecutableWithExports()) { return 0; } @@ -3724,23 +3724,27 @@ cmTarget::ComputeLinkInterface(const char* config) suffix += "NOCONFIG"; } - // Lookup the link interface libraries. - const char* libs = 0; - { - // Lookup the per-configuration property. - std::string propName = "LINK_INTERFACE_LIBRARIES"; - propName += suffix; - libs = this->GetProperty(propName.c_str()); - - // If not set, try the generic property. - if(!libs) + // An explicit list of interface libraries may be set for shared + // libraries and executables that export symbols. + const char* explicitLibraries = 0; + if(this->GetType() == cmTarget::SHARED_LIBRARY || + this->IsExecutableWithExports()) { - libs = this->GetProperty("LINK_INTERFACE_LIBRARIES"); - } - } + // Lookup the per-configuration property. + std::string propName = "LINK_INTERFACE_LIBRARIES"; + propName += suffix; + explicitLibraries = this->GetProperty(propName.c_str()); - // If still not set, there is no link interface. - if(!libs) + // If not set, try the generic property. + if(!explicitLibraries) + { + explicitLibraries = this->GetProperty("LINK_INTERFACE_LIBRARIES"); + } + } + + // There is no implicit link interface for executables, so if none + // was explicitly set, there is no link interface. + if(!explicitLibraries && this->GetType() == cmTarget::EXECUTABLE) { return cmsys::auto_ptr(); } @@ -3752,23 +3756,31 @@ cmTarget::ComputeLinkInterface(const char* config) return cmsys::auto_ptr(); } - // Expand the list of libraries in the interface. - cmSystemTools::ExpandListArgument(libs, iface->Libraries); + // Is the link interface just the link implementation? + bool doLibraries = !explicitLibraries; - // Now we need to construct a list of shared library dependencies - // not included in the interface. - if(this->GetType() == cmTarget::SHARED_LIBRARY) + // 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 emitted; + std::set emittedWrongConfig; + + if(explicitLibraries) { - // Use a set to keep track of what libraries have been emitted to - // either list. - std::set emitted; + // The interface libraries have been explicitly set. + 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); } + } + if(doLibraries || doSharedDeps) + { // Compute which library configuration to link. cmTarget::LinkLibraryType linkType = this->ComputeLinkType(config); @@ -3778,26 +3790,42 @@ cmTarget::ComputeLinkInterface(const char* config) for(cmTarget::LinkLibraryVectorType::const_iterator li = llibs.begin(); li != llibs.end(); ++li) { - // Skip entries that will resolve to the target itself, are empty, - // or are not meant for this configuration. - if(li->first == this->GetName() || li->first.empty() || - !(li->second == cmTarget::GENERAL || li->second == linkType)) + // 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; } - // Skip entries that have already been emitted into either list. - if(!emitted.insert(li->first).second) + // Skip entries not meant for this configuration. + if(li->second != cmTarget::GENERAL && li->second != linkType) + { + // Support OLD behavior for CMP0003. + if(doLibraries && !emittedWrongConfig.insert(item).second) + { + iface->WrongConfigLibraries.push_back(item); + } + continue; + } + + // Skip entries that have already been emitted. + if(!emitted.insert(item).second) { continue; } - // Add this entry if it is a shared library. - if(cmTarget* tgt = this->Makefile->FindTargetToUse(li->first.c_str())) + // 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(li->first); + iface->SharedDeps.push_back(item); } } else diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 83fd0b127..fabf7cf65 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -46,6 +46,10 @@ struct cmTargetLinkInterface // 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: