summaryrefslogtreecommitdiffstats
path: root/Source/cmComputeLinkInformation.cxx
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2008-01-29 20:07:33 (GMT)
committerBrad King <brad.king@kitware.com>2008-01-29 20:07:33 (GMT)
commitffac622a858cca4dc661caa896d961da666430cc (patch)
tree3c52af43de45021dbfc5afc7f64f3ce17701a78f /Source/cmComputeLinkInformation.cxx
parentbb52f45ebb6b1c80f8f7b8e2b841202118ed9d06 (diff)
downloadCMake-ffac622a858cca4dc661caa896d961da666430cc.zip
CMake-ffac622a858cca4dc661caa896d961da666430cc.tar.gz
CMake-ffac622a858cca4dc661caa896d961da666430cc.tar.bz2
ENH: Add cmTarget::GetLinkInformation method to allow several places in the generators to share link information while only computing it once per configuration for a target. Use it to simplify the chrpath feature.
Diffstat (limited to 'Source/cmComputeLinkInformation.cxx')
-rw-r--r--Source/cmComputeLinkInformation.cxx133
1 files changed, 133 insertions, 0 deletions
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index b614de8..190ffb8 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -168,6 +168,12 @@ cmComputeLinkInformation
// Get the language used for linking this target.
this->LinkLanguage =
this->Target->GetLinkerLanguage(this->GlobalGenerator);
+ if(!this->LinkLanguage)
+ {
+ // The Compute method will do nothing, so skip the rest of the
+ // initialization.
+ return;
+ }
// Check whether we should use an import library for linking a target.
this->UseImportLibrary =
@@ -194,6 +200,31 @@ cmComputeLinkInformation
this->LibLinkSuffix =
this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_SUFFIX");
+ // Get options needed to specify RPATHs.
+ this->RuntimeUseChrpath = false;
+ if(this->Target->GetType() != cmTarget::STATIC_LIBRARY)
+ {
+ std::string rtVar = "CMAKE_";
+ if(this->Target->GetType() == cmTarget::EXECUTABLE)
+ {
+ rtVar += "EXECUTABLE";
+ }
+ else
+ {
+ rtVar += "SHARED_LIBRARY";
+ }
+ rtVar += "_RUNTIME_";
+ rtVar += this->LinkLanguage;
+ rtVar += "_FLAG";
+ std::string rtSepVar = rtVar + "_SEP";
+ this->RuntimeFlag = this->Makefile->GetSafeDefinition(rtVar.c_str());
+ this->RuntimeSep = this->Makefile->GetSafeDefinition(rtSepVar.c_str());
+ this->RuntimeAlways =
+ (this->Makefile->
+ GetSafeDefinition("CMAKE_PLATFORM_REQUIRED_RUNTIME_PATH"));
+ this->RuntimeUseChrpath = this->Target->IsChrpathUsed();
+ }
+
// Get link type information.
this->ComputeLinkTypeInfo();
@@ -1227,3 +1258,105 @@ void cmComputeLinkInformation::DiagnoseCycle()
}
cmSystemTools::Message(e.str().c_str());
}
+
+//----------------------------------------------------------------------------
+void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
+ bool for_install)
+{
+ // Select whether to generate runtime search directories.
+ bool outputRuntime =
+ !this->Makefile->IsOn("CMAKE_SKIP_RPATH") && !this->RuntimeFlag.empty();
+
+ // Select whether to generate an rpath for the install tree or the
+ // build tree.
+ bool linking_for_install =
+ (for_install ||
+ this->Target->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"));
+ bool use_install_rpath =
+ (outputRuntime && this->Target->HaveInstallTreeRPATH() &&
+ linking_for_install);
+ bool use_build_rpath =
+ (outputRuntime && this->Target->HaveBuildTreeRPATH() &&
+ !linking_for_install);
+ bool use_link_rpath =
+ outputRuntime && linking_for_install &&
+ this->Target->GetPropertyAsBool("INSTALL_RPATH_USE_LINK_PATH");
+
+ // Construct the RPATH.
+ if(use_install_rpath)
+ {
+ const char* install_rpath = this->Target->GetProperty("INSTALL_RPATH");
+ cmSystemTools::ExpandListArgument(install_rpath, runtimeDirs);
+ }
+ if(use_build_rpath || use_link_rpath)
+ {
+ std::vector<std::string> const& rdirs = this->GetRuntimeSearchPath();
+ for(std::vector<std::string>::const_iterator ri = rdirs.begin();
+ ri != rdirs.end(); ++ri)
+ {
+ // Put this directory in the rpath if using build-tree rpath
+ // support or if using the link path as an rpath.
+ if(use_build_rpath)
+ {
+ runtimeDirs.push_back(*ri);
+ }
+ else if(use_link_rpath)
+ {
+ // Do not add any path inside the source or build tree.
+ const char* topSourceDir = this->Makefile->GetHomeDirectory();
+ const char* topBinaryDir = this->Makefile->GetHomeOutputDirectory();
+ if(!cmSystemTools::ComparePath(ri->c_str(), topSourceDir) &&
+ !cmSystemTools::ComparePath(ri->c_str(), topBinaryDir) &&
+ !cmSystemTools::IsSubDirectory(ri->c_str(), topSourceDir) &&
+ !cmSystemTools::IsSubDirectory(ri->c_str(), topBinaryDir))
+ {
+ runtimeDirs.push_back(*ri);
+ }
+ }
+ }
+ }
+
+ // 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);
+}
+
+//----------------------------------------------------------------------------
+std::string cmComputeLinkInformation::GetRPathString(bool for_install)
+{
+ // Get the directories to use.
+ std::vector<std::string> runtimeDirs;
+ this->GetRPath(runtimeDirs, for_install);
+
+ // Concatenate the paths.
+ std::string rpath;
+ const char* sep = "";
+ for(std::vector<std::string>::const_iterator ri = runtimeDirs.begin();
+ ri != runtimeDirs.end(); ++ri)
+ {
+ // Separate from previous path.
+ rpath += sep;
+ sep = this->GetRuntimeSep().c_str();
+
+ // Add this path.
+ rpath += *ri;
+ }
+ return rpath;
+}
+
+//----------------------------------------------------------------------------
+std::string cmComputeLinkInformation::GetChrpathString()
+{
+ if(!this->RuntimeUseChrpath)
+ {
+ return "";
+ }
+
+ return this->GetRPathString(true);
+}
+
+//----------------------------------------------------------------------------
+std::string cmComputeLinkInformation::GetChrpathTool()
+{
+ return this->Makefile->GetSafeDefinition("CMAKE_CHRPATH");
+}