diff options
Diffstat (limited to 'Source/cmLinkLineComputer.cxx')
-rw-r--r-- | Source/cmLinkLineComputer.cxx | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/Source/cmLinkLineComputer.cxx b/Source/cmLinkLineComputer.cxx new file mode 100644 index 0000000..c271246 --- /dev/null +++ b/Source/cmLinkLineComputer.cxx @@ -0,0 +1,181 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#include "cmLinkLineComputer.h" +#include "cmComputeLinkInformation.h" +#include "cmGeneratorTarget.h" +#include "cmOutputConverter.h" +#include "cmStateDirectory.h" + +cmLinkLineComputer::cmLinkLineComputer(cmOutputConverter* outputConverter, + cmStateDirectory stateDir) + : StateDir(stateDir) + , OutputConverter(outputConverter) + , ForResponse(false) + , UseWatcomQuote(false) + , Relink(false) +{ +} + +cmLinkLineComputer::~cmLinkLineComputer() +{ +} + +void cmLinkLineComputer::SetUseWatcomQuote(bool useWatcomQuote) +{ + this->UseWatcomQuote = useWatcomQuote; +} + +void cmLinkLineComputer::SetForResponse(bool forResponse) +{ + this->ForResponse = forResponse; +} + +void cmLinkLineComputer::SetRelink(bool relink) +{ + this->Relink = relink; +} + +std::string cmLinkLineComputer::ConvertToLinkReference( + std::string const& lib) const +{ + std::string relLib = lib; + + if (cmOutputConverter::ContainedInDirectory( + this->StateDir.GetCurrentBinary(), lib, this->StateDir)) { + relLib = cmOutputConverter::ForceToRelativePath( + this->StateDir.GetCurrentBinary(), lib); + } + return relLib; +} + +std::string cmLinkLineComputer::ComputeLinkLibs(cmComputeLinkInformation& cli) +{ + std::string linkLibs; + typedef cmComputeLinkInformation::ItemVector ItemVector; + ItemVector const& items = cli.GetItems(); + for (ItemVector::const_iterator li = items.begin(); li != items.end(); + ++li) { + if (li->Target && + li->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY) { + continue; + } + if (li->IsPath) { + linkLibs += + this->ConvertToOutputFormat(this->ConvertToLinkReference(li->Value)); + } else { + linkLibs += li->Value; + } + linkLibs += " "; + } + return linkLibs; +} + +std::string cmLinkLineComputer::ConvertToOutputFormat(std::string const& input) +{ + cmOutputConverter::OutputFormat shellFormat = (this->ForResponse) + ? cmOutputConverter::RESPONSE + : ((this->UseWatcomQuote) ? cmOutputConverter::WATCOMQUOTE + : cmOutputConverter::SHELL); + + return this->OutputConverter->ConvertToOutputFormat(input, shellFormat); +} + +std::string cmLinkLineComputer::ConvertToOutputForExisting( + std::string const& input) +{ + cmOutputConverter::OutputFormat shellFormat = (this->ForResponse) + ? cmOutputConverter::RESPONSE + : ((this->UseWatcomQuote) ? cmOutputConverter::WATCOMQUOTE + : cmOutputConverter::SHELL); + + return this->OutputConverter->ConvertToOutputForExisting(input, shellFormat); +} + +std::string cmLinkLineComputer::ComputeLinkPath( + cmComputeLinkInformation& cli, std::string const& libPathFlag, + std::string const& libPathTerminator) +{ + std::string linkPath; + std::vector<std::string> const& libDirs = cli.GetDirectories(); + for (std::vector<std::string>::const_iterator libDir = libDirs.begin(); + libDir != libDirs.end(); ++libDir) { + std::string libpath = this->ConvertToOutputForExisting(*libDir); + linkPath += " " + libPathFlag; + linkPath += libpath; + linkPath += libPathTerminator; + linkPath += " "; + } + return linkPath; +} + +std::string cmLinkLineComputer::ComputeRPath(cmComputeLinkInformation& cli) +{ + std::string rpath; + // Check what kind of rpath flags to use. + if (cli.GetRuntimeSep().empty()) { + // Each rpath entry gets its own option ("-R a -R b -R c") + std::vector<std::string> runtimeDirs; + cli.GetRPath(runtimeDirs, this->Relink); + + for (std::vector<std::string>::iterator ri = runtimeDirs.begin(); + ri != runtimeDirs.end(); ++ri) { + rpath += cli.GetRuntimeFlag(); + rpath += this->ConvertToOutputFormat(*ri); + rpath += " "; + } + } else { + // All rpath entries are combined ("-Wl,-rpath,a:b:c"). + std::string rpathString = cli.GetRPathString(this->Relink); + + // Store the rpath option in the stream. + if (!rpathString.empty()) { + rpath += cli.GetRuntimeFlag(); + rpath += + this->OutputConverter->EscapeForShell(rpathString, !this->ForResponse); + rpath += " "; + } + } + return rpath; +} + +std::string cmLinkLineComputer::ComputeFrameworkPath( + cmComputeLinkInformation& cli, std::string const& fwSearchFlag) +{ + std::string frameworkPath; + if (!fwSearchFlag.empty()) { + std::vector<std::string> const& fwDirs = cli.GetFrameworkPaths(); + for (std::vector<std::string>::const_iterator fdi = fwDirs.begin(); + fdi != fwDirs.end(); ++fdi) { + frameworkPath += fwSearchFlag; + frameworkPath += this->ConvertToOutputFormat(*fdi); + frameworkPath += " "; + } + } + return frameworkPath; +} + +std::string cmLinkLineComputer::ComputeLinkLibraries( + cmComputeLinkInformation& cli, std::string const& stdLibString) +{ + std::ostringstream fout; + fout << this->ComputeRPath(cli); + + // Write the library flags to the build rule. + fout << this->ComputeLinkLibs(cli); + + // Add the linker runtime search path if any. + std::string rpath_link = cli.GetRPathLinkString(); + if (!cli.GetRPathLinkFlag().empty() && !rpath_link.empty()) { + fout << cli.GetRPathLinkFlag(); + fout << this->OutputConverter->EscapeForShell(rpath_link, + !this->ForResponse); + fout << " "; + } + + if (!stdLibString.empty()) { + fout << stdLibString << " "; + } + + return fout.str(); +} |