summaryrefslogtreecommitdiff
path: root/Source/cmComputeLinkInformation.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmComputeLinkInformation.cxx')
-rw-r--r--Source/cmComputeLinkInformation.cxx105
1 files changed, 91 insertions, 14 deletions
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index cd3ef59a9..896b50aa5 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -239,10 +239,12 @@ because this need be done only for shared libraries without soname-s.
//----------------------------------------------------------------------------
cmComputeLinkInformation
-::cmComputeLinkInformation(cmTarget* target, const char* config)
+::cmComputeLinkInformation(cmTarget* target, const char* config,
+ cmTarget *headTarget)
{
// Store context information.
this->Target = target;
+ this->HeadTarget = headTarget;
this->Makefile = this->Target->GetMakefile();
this->LocalGenerator = this->Makefile->GetLocalGenerator();
this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator();
@@ -265,7 +267,7 @@ cmComputeLinkInformation
this->OrderDependentRPath = 0;
// Get the language used for linking this target.
- this->LinkLanguage = this->Target->GetLinkerLanguage(config);
+ this->LinkLanguage = this->Target->GetLinkerLanguage(config, headTarget);
if(!this->LinkLanguage)
{
// The Compute method will do nothing, so skip the rest of the
@@ -277,6 +279,10 @@ cmComputeLinkInformation
this->UseImportLibrary =
this->Makefile->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")?true:false;
+ // Check whether we should skip dependencies on shared library files.
+ this->LinkDependsNoShared =
+ this->Target->GetPropertyAsBool("LINK_DEPENDS_NO_SHARED");
+
// On platforms without import libraries there may be a special flag
// to use when creating a plugin (module) that obtains symbols from
// the program that will load it.
@@ -499,7 +505,7 @@ bool cmComputeLinkInformation::Compute()
}
// Compute the ordered link line items.
- cmComputeLinkDepends cld(this->Target, this->Config);
+ cmComputeLinkDepends cld(this->Target, this->Config, this->HeadTarget);
cld.SetOldLinkDirMode(this->OldLinkDirMode);
cmComputeLinkDepends::EntryVector const& linkEntries = cld.Compute();
@@ -565,7 +571,8 @@ bool cmComputeLinkInformation::Compute()
void cmComputeLinkInformation::AddImplicitLinkInfo()
{
// The link closure lists all languages whose implicit info is needed.
- cmTarget::LinkClosure const* lc=this->Target->GetLinkClosure(this->Config);
+ cmTarget::LinkClosure const* lc=this->Target->GetLinkClosure(this->Config,
+ this->HeadTarget);
for(std::vector<std::string>::const_iterator li = lc->Languages.begin();
li != lc->Languages.end(); ++li)
{
@@ -650,7 +657,11 @@ void cmComputeLinkInformation::AddItem(std::string const& item, cmTarget* tgt)
// Pass the full path to the target file.
std::string lib = tgt->GetFullPath(config, implib, true);
- this->Depends.push_back(lib);
+ if(!this->LinkDependsNoShared ||
+ tgt->GetType() != cmTarget::SHARED_LIBRARY)
+ {
+ this->Depends.push_back(lib);
+ }
this->AddTargetItem(lib, tgt);
this->AddLibraryRuntimeInfo(lib, tgt);
@@ -1368,10 +1379,31 @@ void cmComputeLinkInformation::DropDirectoryItem(std::string const& item)
//----------------------------------------------------------------------------
void cmComputeLinkInformation::ComputeFrameworkInfo()
{
- // Avoid adding system framework paths. See "man ld" on OS X.
- this->FrameworkPathsEmmitted.insert("/Library/Frameworks");
- this->FrameworkPathsEmmitted.insert("/Network/Library/Frameworks");
- this->FrameworkPathsEmmitted.insert("/System/Library/Frameworks");
+ // Avoid adding implicit framework paths.
+ std::vector<std::string> implicitDirVec;
+
+ // Get platform-wide implicit directories.
+ if(const char* implicitLinks = this->Makefile->GetDefinition
+ ("CMAKE_PLATFORM_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES"))
+ {
+ cmSystemTools::ExpandListArgument(implicitLinks, implicitDirVec);
+ }
+
+ // Get language-specific implicit directories.
+ std::string implicitDirVar = "CMAKE_";
+ implicitDirVar += this->LinkLanguage;
+ implicitDirVar += "_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES";
+ if(const char* implicitDirs =
+ this->Makefile->GetDefinition(implicitDirVar.c_str()))
+ {
+ cmSystemTools::ExpandListArgument(implicitDirs, implicitDirVec);
+ }
+
+ for(std::vector<std::string>::const_iterator i = implicitDirVec.begin();
+ i != implicitDirVec.end(); ++i)
+ {
+ this->FrameworkPathsEmmitted.insert(*i);
+ }
// Regular expression to extract a framework path and name.
this->SplitFramework.compile("(.*)/(.*)\\.framework$");
@@ -1752,6 +1784,22 @@ cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath)
}
//----------------------------------------------------------------------------
+static void cmCLI_ExpandListUnique(const char* str,
+ std::vector<std::string>& out,
+ std::set<cmStdString>& emitted)
+{
+ std::vector<std::string> tmp;
+ cmSystemTools::ExpandListArgument(str, tmp);
+ for(std::vector<std::string>::iterator i = tmp.begin(); i != tmp.end(); ++i)
+ {
+ if(emitted.insert(*i).second)
+ {
+ out.push_back(*i);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
bool for_install)
{
@@ -1768,7 +1816,7 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
(outputRuntime && this->Target->HaveInstallTreeRPATH() &&
linking_for_install);
bool use_build_rpath =
- (outputRuntime && this->Target->HaveBuildTreeRPATH() &&
+ (outputRuntime && this->Target->HaveBuildTreeRPATH(this->Config) &&
!linking_for_install);
bool use_link_rpath =
outputRuntime && linking_for_install &&
@@ -1776,10 +1824,11 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
this->Target->GetPropertyAsBool("INSTALL_RPATH_USE_LINK_PATH");
// Construct the RPATH.
+ std::set<cmStdString> emitted;
if(use_install_rpath)
{
const char* install_rpath = this->Target->GetProperty("INSTALL_RPATH");
- cmSystemTools::ExpandListArgument(install_rpath, runtimeDirs);
+ cmCLI_ExpandListUnique(install_rpath, runtimeDirs, emitted);
}
if(use_build_rpath || use_link_rpath)
{
@@ -1791,7 +1840,10 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
// support or if using the link path as an rpath.
if(use_build_rpath)
{
- runtimeDirs.push_back(*ri);
+ if(emitted.insert(*ri).second)
+ {
+ runtimeDirs.push_back(*ri);
+ }
}
else if(use_link_rpath)
{
@@ -1803,15 +1855,40 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
!cmSystemTools::IsSubDirectory(ri->c_str(), topSourceDir) &&
!cmSystemTools::IsSubDirectory(ri->c_str(), topBinaryDir))
{
- runtimeDirs.push_back(*ri);
+ if(emitted.insert(*ri).second)
+ {
+ runtimeDirs.push_back(*ri);
+ }
}
}
}
}
+ // Add runtime paths required by the languages to always be
+ // present. This is done even when skipping rpath support.
+ {
+ cmTarget::LinkClosure const* lc =
+ this->Target->GetLinkClosure(this->Config, this->HeadTarget);
+ for(std::vector<std::string>::const_iterator li = lc->Languages.begin();
+ li != lc->Languages.end(); ++li)
+ {
+ std::string useVar = "CMAKE_" + *li +
+ "_USE_IMPLICIT_LINK_DIRECTORIES_IN_RUNTIME_PATH";
+ if(this->Makefile->IsOn(useVar.c_str()))
+ {
+ std::string dirVar = "CMAKE_" + *li +
+ "_IMPLICIT_LINK_DIRECTORIES";
+ if(const char* dirs = this->Makefile->GetDefinition(dirVar.c_str()))
+ {
+ cmCLI_ExpandListUnique(dirs, runtimeDirs, emitted);
+ }
+ }
+ }
+ }
+
// Add runtime paths required by the platform to always be
// present. This is done even when skipping rpath support.
- cmSystemTools::ExpandListArgument(this->RuntimeAlways.c_str(), runtimeDirs);
+ cmCLI_ExpandListUnique(this->RuntimeAlways.c_str(), runtimeDirs, emitted);
}
//----------------------------------------------------------------------------