summaryrefslogtreecommitdiffstats
path: root/Source/cmLocalGenerator.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/cmLocalGenerator.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/cmLocalGenerator.cxx')
-rw-r--r--Source/cmLocalGenerator.cxx220
1 files changed, 46 insertions, 174 deletions
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 4812572..493d26e 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -1483,70 +1483,33 @@ std::string cmLocalGenerator::ConvertToLinkReference(std::string const& lib)
return this->Convert(lib.c_str(), START_OUTPUT, SHELL);
}
-bool cmLocalGenerator::GetLinkerArgs(std::string& rpath,
- std::string& linkLibs,
- cmTarget& tgt,
- bool relink,
- unsigned int minRpathSize)
+/**
+ * Output the linking rules on a command line. For executables,
+ * targetLibrary should be a NULL pointer. For libraries, it should point
+ * to the name of the library. This will not link a library against itself.
+ */
+void cmLocalGenerator::OutputLinkLibraries(std::ostream& fout,
+ cmTarget& tgt,
+ bool relink)
{
- rpath = "";
- // collect all the flags needed for linking libraries
- linkLibs = "";
-
const char* config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE");
-
- cmComputeLinkInformation cli(&tgt, config);
- if(!cli.Compute())
+ cmComputeLinkInformation* pcli = tgt.GetLinkInformation(config);
+ if(!pcli)
{
- return false;
- }
-
- const char* linkLanguage = cli.GetLinkLanguage();
-
- // Embed runtime search paths if possible and if required.
- bool outputRuntime = !this->Makefile->IsOn("CMAKE_SKIP_RPATH");
-
- // Lookup rpath specification flags.
- std::string runtimeFlag;
- std::string runtimeSep;
- if(tgt.GetType() != cmTarget::STATIC_LIBRARY)
- {
- std::string runTimeFlagVar = "CMAKE_";
- if(tgt.GetType() == cmTarget::EXECUTABLE)
- {
- runTimeFlagVar += "EXECUTABLE";
- }
- else
- {
- runTimeFlagVar += "SHARED_LIBRARY";
- }
- runTimeFlagVar += "_RUNTIME_";
- runTimeFlagVar += linkLanguage;
- runTimeFlagVar += "_FLAG";
- std::string runTimeFlagSepVar = runTimeFlagVar + "_SEP";
- runtimeFlag = this->Makefile->GetSafeDefinition(runTimeFlagVar.c_str());
- runtimeSep = this->Makefile->GetSafeDefinition(runTimeFlagSepVar.c_str());
+ return;
}
- // concatenate all paths or no?
- bool runtimeConcatenate = !runtimeSep.empty();
+ cmComputeLinkInformation& cli = *pcli;
- const char* runtimeAlways =
- this->Makefile->GetDefinition("CMAKE_PLATFORM_REQUIRED_RUNTIME_PATH");
+ // Collect library linking flags command line options.
+ std::string linkLibs;
- // Turn off rpath support if no flag is available to specify it.
- if(runtimeFlag.empty())
- {
- outputRuntime = false;
- runtimeAlways = 0;
- }
+ const char* linkLanguage = cli.GetLinkLanguage();
std::string libPathFlag =
this->Makefile->GetRequiredDefinition("CMAKE_LIBRARY_PATH_FLAG");
std::string libPathTerminator =
this->Makefile->GetSafeDefinition("CMAKE_LIBRARY_PATH_TERMINATOR");
- std::string libLinkFlag =
- this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_FLAG");
-
+
// Flags to link an executable to shared libraries.
std::string linkFlagsVar = "CMAKE_SHARED_LIBRARY_LINK_";
linkFlagsVar += linkLanguage;
@@ -1595,146 +1558,55 @@ bool cmLocalGenerator::GetLinkerArgs(std::string& rpath,
linkLibs += " ";
}
- // Select whether to generate an rpath for the install tree or the
- // build tree.
- bool linking_for_install =
- relink || tgt.GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH");
- bool use_install_rpath =
- outputRuntime && tgt.HaveInstallTreeRPATH() && linking_for_install;
- bool use_build_rpath =
- outputRuntime && tgt.HaveBuildTreeRPATH() && !linking_for_install;
- bool use_link_rpath =
- outputRuntime && linking_for_install &&
- tgt.GetPropertyAsBool("INSTALL_RPATH_USE_LINK_PATH");
+ // Write the library flags to the build rule.
+ fout << linkLibs;
- // Construct the RPATH.
+ // Get the RPATH entries.
std::vector<std::string> runtimeDirs;
- if(use_install_rpath)
- {
- const char* install_rpath = tgt.GetProperty("INSTALL_RPATH");
- cmSystemTools::ExpandListArgument(install_rpath, runtimeDirs);
- }
- if(use_build_rpath || use_link_rpath)
+ cli.GetRPath(runtimeDirs, relink);
+
+ // Check what kind of rpath flags to use.
+ if(cli.GetRuntimeSep().empty())
{
- std::vector<std::string> const& rdirs = cli.GetRuntimeSearchPath();
- for(std::vector<std::string>::const_iterator ri = rdirs.begin();
- ri != rdirs.end(); ++ri)
+ // Each rpath entry gets its own option ("-R a -R b -R c")
+ std::string rpath;
+ for(std::vector<std::string>::iterator ri = runtimeDirs.begin();
+ ri != runtimeDirs.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);
- }
- }
+ rpath += cli.GetRuntimeFlag();
+ rpath += this->Convert(ri->c_str(), FULL, SHELL, false);
+ rpath += " ";
}
+ fout << rpath;
}
- if(runtimeAlways)
- {
- // Add runtime paths required by the platform to always be
- // present. This is done even when skipping rpath support.
- cmSystemTools::ExpandListArgument(runtimeAlways, runtimeDirs);
- }
-
- // Convert the runtime directory names for use in the build file.
- for(std::vector<std::string>::iterator ri = runtimeDirs.begin();
- ri != runtimeDirs.end(); ++ri)
+ else
{
- *ri = this->Convert(ri->c_str(), FULL, SHELL, false);
- }
+ // All rpath entries are combined ("-Wl,-rpath,a:b:c").
+ std::string rpath = cli.GetRPathString(relink);
- if(!runtimeDirs.empty())
- {
- // For the runtime search directories, do a "-Wl,-rpath,a:b:c" or
- // a "-R a -R b -R c" type link line
- rpath += runtimeFlag;
- std::vector<std::string>::iterator itr = runtimeDirs.begin();
- rpath += *itr;
- ++itr;
- for( ; itr != runtimeDirs.end(); ++itr )
+ // If not relinking, make sure the rpath string is long enough to
+ // support a subsequent chrpath on installation.
+ if(!relink)
{
- if(runtimeConcatenate)
+ std::string::size_type minLength = cli.GetChrpathString().size();
+ while(rpath.size() < minLength)
{
- rpath += runtimeSep;
- rpath += *itr;
- }
- else
- {
- rpath += " ";
- rpath += runtimeFlag;
- rpath += *itr;
+ rpath += cli.GetRuntimeSep();
}
}
- }
- while (rpath.size() < minRpathSize)
- {
- if (rpath.size()==0)
+ // Store the rpath option in the stream.
+ if(!rpath.empty())
{
- rpath += runtimeFlag;
+ fout << cli.GetRuntimeFlag();
+ fout << this->EscapeForShell(rpath.c_str(), true);
+ fout << " ";
}
-
- rpath += runtimeSep;
- }
- return true;
-}
-
-/**
- * Output the linking rules on a command line. For executables,
- * targetLibrary should be a NULL pointer. For libraries, it should point
- * to the name of the library. This will not link a library against itself.
- */
-void cmLocalGenerator::OutputLinkLibraries(std::ostream& fout,
- cmTarget& tgt,
- bool relink)
-{
- std::string rpath;
- std::string linkLibs;
- unsigned int minBuildRpathSize = 0;
-
- if ((relink==false)
- && this->Makefile->IsOn("CMAKE_USE_CHRPATH")
- && (tgt.IsChrpathAvailable()))
- {
- std::string installRpath;
- std::string dummy;
- this->GetLinkerArgs(installRpath, dummy, tgt, true, 0);
- minBuildRpathSize = static_cast<unsigned int>(installRpath.size());
}
- if (!this->GetLinkerArgs(rpath, linkLibs, tgt, relink, minBuildRpathSize))
- {
- return;
- }
-
- const char* linkLanguage =
- tgt.GetLinkerLanguage(this->GetGlobalGenerator());
- if(!linkLanguage)
- {
- cmSystemTools::
- Error("CMake can not determine linker language for target:",
- tgt.GetName());
- return;
- }
-
- fout << linkLibs;
- fout << rpath << " ";
-
// Add standard libraries for this language.
std::string standardLibsVar = "CMAKE_";
- standardLibsVar += linkLanguage;
+ standardLibsVar += cli.GetLinkLanguage();
standardLibsVar += "_STANDARD_LIBRARIES";
if(const char* stdLibs =
this->Makefile->GetDefinition(standardLibsVar.c_str()))