summaryrefslogtreecommitdiffstats
path: root/Source/cmTarget.cxx
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2008-01-31 20:45:31 (GMT)
committerBrad King <brad.king@kitware.com>2008-01-31 20:45:31 (GMT)
commit2cff26fa52cf9043f00d1efaaf31ab93e2db22e8 (patch)
tree4d403a91a70594893fc6b303a9cf693d4e538a9d /Source/cmTarget.cxx
parent52e75800b4731692f1e311f0d8701875ac98c96d (diff)
downloadCMake-2cff26fa52cf9043f00d1efaaf31ab93e2db22e8.zip
CMake-2cff26fa52cf9043f00d1efaaf31ab93e2db22e8.tar.gz
CMake-2cff26fa52cf9043f00d1efaaf31ab93e2db22e8.tar.bz2
ENH: Support linking to shared libs with dependent libs
- Split IMPORTED_LINK_LIBRARIES into two parts: IMPORTED_LINK_INTERFACE_LIBRARIES IMPORTED_LINK_DEPENDENT_LIBRARIES - Add CMAKE_DEPENDENT_SHARED_LIBRARY_MODE to select behavior - Set mode to LINK for Darwin (fixes universal binary problem) - Update ExportImport test to account for changes
Diffstat (limited to 'Source/cmTarget.cxx')
-rw-r--r--Source/cmTarget.cxx158
1 files changed, 129 insertions, 29 deletions
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index e007367..b484a95 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -188,15 +188,38 @@ void cmTarget::DefineProperties(cmake *cm)
"from which the target is imported.");
cm->DefineProperty
- ("IMPORTED_LINK_LIBRARIES", cmProperty::TARGET,
- "Transitive link dependencies of an IMPORTED target.",
- "Lists dependencies that must be linked when an IMPORTED library "
+ ("IMPORTED_LINK_DEPENDENT_LIBRARIES", cmProperty::TARGET,
+ "Dependent shared libraries of an imported shared library.",
+ "Shared libraries may be linked to other shared libraries as part "
+ "of their implementation. On some platforms the linker searches "
+ "for the dependent libraries of shared libraries they are including "
+ "in the link. CMake gives the paths to these libraries to the linker "
+ "by listing them on the link line explicitly. This property lists "
+ "the dependent shared libraries of an imported library. The list "
+ "should be disjoint from the list of interface libraries in the "
+ "IMPORTED_LINK_INTERFACE_LIBRARIES property. On platforms requiring "
+ "dependent shared libraries to be found at link time CMake uses this "
+ "list to add the dependent libraries to the link command line.");
+
+ cm->DefineProperty
+ ("IMPORTED_LINK_DEPENDENT_LIBRARIES_<CONFIG>", cmProperty::TARGET,
+ "Per-configuration version of IMPORTED_LINK_DEPENDENT_LIBRARIES.",
+ "This property is used when loading settings for the <CONFIG> "
+ "configuration of an imported target. "
+ "Configuration names correspond to those provided by the project "
+ "from which the target is imported.");
+
+ cm->DefineProperty
+ ("IMPORTED_LINK_INTERFACE_LIBRARIES", cmProperty::TARGET,
+ "Transitive link interface of an IMPORTED target.",
+ "Lists libraries whose interface is included when an IMPORTED library "
"target is linked to another target. "
+ "The libraries will be included on the link line for the target. "
"Ignored for non-imported targets.");
cm->DefineProperty
- ("IMPORTED_LINK_LIBRARIES_<CONFIG>", cmProperty::TARGET,
- "Per-configuration version of IMPORTED_LINK_LIBRARIES property.",
+ ("IMPORTED_LINK_INTERFACE_LIBRARIES_<CONFIG>", cmProperty::TARGET,
+ "Per-configuration version of IMPORTED_LINK_INTERFACE_LIBRARIES.",
"This property is used when loading settings for the <CONFIG> "
"configuration of an imported target. "
"Configuration names correspond to those provided by the project "
@@ -3045,43 +3068,56 @@ void cmTarget::ComputeImportInfo(std::string const& desired_config,
}
}
- // Get the link dependencies.
+ // Get the link interface.
{
- std::string linkProp = "IMPORTED_LINK_LIBRARIES";
+ std::string linkProp = "IMPORTED_LINK_INTERFACE_LIBRARIES";
linkProp += suffix;
if(const char* config_libs = this->GetProperty(linkProp.c_str()))
{
- cmSystemTools::ExpandListArgument(config_libs, info.LinkLibraries);
+ cmSystemTools::ExpandListArgument(config_libs,
+ info.LinkInterface.Libraries);
}
- else if(const char* libs = this->GetProperty("IMPORTED_LINK_LIBRARIES"))
+ else if(const char* libs =
+ this->GetProperty("IMPORTED_LINK_INTERFACE_LIBRARIES"))
{
- cmSystemTools::ExpandListArgument(libs, info.LinkLibraries);
+ cmSystemTools::ExpandListArgument(libs,
+ info.LinkInterface.Libraries);
}
}
-}
-//----------------------------------------------------------------------------
-std::vector<std::string> const*
-cmTarget::GetImportedLinkLibraries(const char* config)
-{
- if(cmTarget::ImportInfo const* info = this->GetImportInfo(config))
+ // Get the link dependencies.
+ {
+ std::string linkProp = "IMPORTED_LINK_DEPENDENT_LIBRARIES";
+ linkProp += suffix;
+ if(const char* config_libs = this->GetProperty(linkProp.c_str()))
{
- return &info->LinkLibraries;
+ cmSystemTools::ExpandListArgument(config_libs,
+ info.LinkInterface.SharedDeps);
}
- else
+ else if(const char* libs =
+ this->GetProperty("IMPORTED_LINK_DEPENDENT_LIBRARIES"))
{
- return 0;
+ cmSystemTools::ExpandListArgument(libs, info.LinkInterface.SharedDeps);
}
+ }
}
//----------------------------------------------------------------------------
cmTargetLinkInterface const* cmTarget::GetLinkInterface(const char* config)
{
- // Link interfaces are supported only for non-imported shared
- // libraries and executables that export symbols. Imported targets
- // provide their own link information.
- if(this->IsImported() ||
- (this->GetType() != cmTarget::SHARED_LIBRARY &&
+ // Imported targets have their own link interface.
+ if(this->IsImported())
+ {
+ if(cmTarget::ImportInfo const* info = this->GetImportInfo(config))
+ {
+ return &info->LinkInterface;
+ }
+ return 0;
+ }
+
+ // Link interfaces are supported only for shared libraries and
+ // executables that export symbols.
+ if((this->GetType() != cmTarget::SHARED_LIBRARY &&
!this->IsExecutableWithExports()))
{
return 0;
@@ -3139,13 +3175,77 @@ cmTargetLinkInterface* cmTarget::ComputeLinkInterface(const char* config)
return 0;
}
- // Return the interface libraries even if the list is empty.
- if(cmTargetLinkInterface* interface = new cmTargetLinkInterface)
+ // Allocate the interface.
+ cmTargetLinkInterface* interface = new cmTargetLinkInterface;
+ if(!interface)
{
- cmSystemTools::ExpandListArgument(libs, *interface);
- return interface;
+ return 0;
+ }
+
+ // Expand the list of libraries in the interface.
+ cmSystemTools::ExpandListArgument(libs, interface->Libraries);
+
+ // Now we need to construct a list of shared library dependencies
+ // not included in the interface.
+ if(this->GetType() == cmTarget::SHARED_LIBRARY)
+ {
+ // Use a set to keep track of what libraries have been emitted to
+ // either list.
+ std::set<cmStdString> emitted;
+ for(std::vector<std::string>::const_iterator
+ li = interface->Libraries.begin();
+ li != interface->Libraries.end(); ++li)
+ {
+ emitted.insert(*li);
+ }
+
+ // Compute which library configuration to link.
+ cmTarget::LinkLibraryType linkType = cmTarget::OPTIMIZED;
+ if(config && cmSystemTools::UpperCase(config) == "DEBUG")
+ {
+ linkType = cmTarget::DEBUG;
+ }
+
+ // Construct the list of libs linked for this configuration.
+ cmTarget::LinkLibraryVectorType const& libs =
+ this->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 == this->GetName() || li->first.empty() ||
+ !(li->second == cmTarget::GENERAL || li->second == linkType))
+ {
+ continue;
+ }
+
+ // Skip entries that have already been emitted into either list.
+ if(!emitted.insert(li->first).second)
+ {
+ continue;
+ }
+
+ // Add this entry if it is a shared library.
+ if(cmTarget* tgt = this->Makefile->FindTargetToUse(li->first.c_str()))
+ {
+ if(tgt->GetType() == cmTarget::SHARED_LIBRARY)
+ {
+ interface->SharedDeps.push_back(li->first);
+ }
+ }
+ 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.
+ }
+ }
}
- return 0;
+
+ // Return the completed interface.
+ return interface;
}
//----------------------------------------------------------------------------