diff options
author | Brad King <brad.king@kitware.com> | 2008-01-29 20:07:33 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2008-01-29 20:07:33 (GMT) |
commit | ffac622a858cca4dc661caa896d961da666430cc (patch) | |
tree | 3c52af43de45021dbfc5afc7f64f3ce17701a78f /Source/cmLocalGenerator.cxx | |
parent | bb52f45ebb6b1c80f8f7b8e2b841202118ed9d06 (diff) | |
download | CMake-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.cxx | 220 |
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())) |