| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266 | 
							- /* 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 <sstream>
 
- #include <utility>
 
- #include <vector>
 
- #include "cmComputeLinkInformation.h"
 
- #include "cmGeneratorTarget.h"
 
- #include "cmListFileCache.h"
 
- #include "cmOutputConverter.h"
 
- #include "cmStateTypes.h"
 
- #include "cmStringAlgorithms.h"
 
- cmLinkLineComputer::cmLinkLineComputer(cmOutputConverter* outputConverter,
 
-                                        cmStateDirectory const& stateDir)
 
-   : StateDir(stateDir)
 
-   , OutputConverter(outputConverter)
 
- {
 
- }
 
- cmLinkLineComputer::~cmLinkLineComputer() = default;
 
- void cmLinkLineComputer::SetUseWatcomQuote(bool useWatcomQuote)
 
- {
 
-   this->UseWatcomQuote = useWatcomQuote;
 
- }
 
- void cmLinkLineComputer::SetUseNinjaMulti(bool useNinjaMulti)
 
- {
 
-   this->UseNinjaMulti = useNinjaMulti;
 
- }
 
- 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
 
- {
 
-   return this->OutputConverter->MaybeRelativeToCurBinDir(lib);
 
- }
 
- std::string cmLinkLineComputer::ComputeLinkLibs(cmComputeLinkInformation& cli)
 
- {
 
-   std::string linkLibs;
 
-   std::vector<BT<std::string>> linkLibsList;
 
-   this->ComputeLinkLibs(cli, linkLibsList);
 
-   cli.AppendValues(linkLibs, linkLibsList);
 
-   return linkLibs;
 
- }
 
- void cmLinkLineComputer::ComputeLinkLibs(
 
-   cmComputeLinkInformation& cli, std::vector<BT<std::string>>& linkLibraries)
 
- {
 
-   using ItemVector = cmComputeLinkInformation::ItemVector;
 
-   ItemVector const& items = cli.GetItems();
 
-   for (auto const& item : items) {
 
-     if (item.Target &&
 
-         (item.Target->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
 
-          item.Target->GetType() == cmStateEnums::OBJECT_LIBRARY)) {
 
-       continue;
 
-     }
 
-     BT<std::string> linkLib;
 
-     if (item.IsPath == cmComputeLinkInformation::ItemIsPath::Yes) {
 
-       linkLib = item.GetFormattedItem(this->ConvertToOutputFormat(
 
-         this->ConvertToLinkReference(item.Value.Value)));
 
-     } else {
 
-       linkLib = item.Value;
 
-     }
 
-     linkLib.Value += " ";
 
-     linkLibraries.emplace_back(linkLib);
 
-   }
 
- }
 
- std::string cmLinkLineComputer::ConvertToOutputFormat(std::string const& input)
 
- {
 
-   cmOutputConverter::OutputFormat shellFormat = cmOutputConverter::SHELL;
 
-   if (this->ForResponse) {
 
-     shellFormat = cmOutputConverter::RESPONSE;
 
-   } else if (this->UseNinjaMulti) {
 
-     shellFormat = cmOutputConverter::NINJAMULTI;
 
-   }
 
-   return this->OutputConverter->ConvertToOutputFormat(input, shellFormat,
 
-                                                       this->UseWatcomQuote);
 
- }
 
- std::string cmLinkLineComputer::ConvertToOutputForExisting(
 
-   std::string const& input)
 
- {
 
-   cmOutputConverter::OutputFormat shellFormat = cmOutputConverter::SHELL;
 
-   if (this->ForResponse) {
 
-     shellFormat = cmOutputConverter::RESPONSE;
 
-   } else if (this->UseNinjaMulti) {
 
-     shellFormat = cmOutputConverter::NINJAMULTI;
 
-   }
 
-   return this->OutputConverter->ConvertToOutputForExisting(
 
-     input, shellFormat, this->UseWatcomQuote);
 
- }
 
- std::string cmLinkLineComputer::ComputeLinkPath(
 
-   cmComputeLinkInformation& cli, std::string const& libPathFlag,
 
-   std::string const& libPathTerminator)
 
- {
 
-   std::string linkPath;
 
-   std::vector<BT<std::string>> linkPathList;
 
-   this->ComputeLinkPath(cli, libPathFlag, libPathTerminator, linkPathList);
 
-   cli.AppendValues(linkPath, linkPathList);
 
-   return linkPath;
 
- }
 
- void cmLinkLineComputer::ComputeLinkPath(
 
-   cmComputeLinkInformation& cli, std::string const& libPathFlag,
 
-   std::string const& libPathTerminator, std::vector<BT<std::string>>& linkPath)
 
- {
 
-   if (cli.GetLinkLanguage() == "Swift") {
 
-     std::string linkPathNoBT;
 
-     for (const cmComputeLinkInformation::Item& item : cli.GetItems()) {
 
-       const cmGeneratorTarget* target = item.Target;
 
-       if (!target) {
 
-         continue;
 
-       }
 
-       if (target->GetType() == cmStateEnums::STATIC_LIBRARY ||
 
-           target->GetType() == cmStateEnums::SHARED_LIBRARY) {
 
-         cmStateEnums::ArtifactType type = cmStateEnums::RuntimeBinaryArtifact;
 
-         if (target->HasImportLibrary(cli.GetConfig())) {
 
-           type = cmStateEnums::ImportLibraryArtifact;
 
-         }
 
-         linkPathNoBT +=
 
-           cmStrCat(" ", libPathFlag,
 
-                    this->ConvertToOutputForExisting(
 
-                      item.Target->GetDirectory(cli.GetConfig(), type)),
 
-                    libPathTerminator, " ");
 
-       }
 
-     }
 
-     if (!linkPathNoBT.empty()) {
 
-       linkPath.emplace_back(std::move(linkPathNoBT));
 
-     }
 
-   }
 
-   for (BT<std::string> libDir : cli.GetDirectoriesWithBacktraces()) {
 
-     libDir.Value = cmStrCat(" ", libPathFlag,
 
-                             this->ConvertToOutputForExisting(libDir.Value),
 
-                             libPathTerminator, " ");
 
-     linkPath.emplace_back(libDir);
 
-   }
 
- }
 
- 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::string const& rd : runtimeDirs) {
 
-       rpath += cli.GetRuntimeFlag();
 
-       rpath += this->ConvertToOutputFormat(rd);
 
-       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, cmValue fwSearchFlag, cmValue sysFwSearchFlag)
 
- {
 
-   if (!fwSearchFlag && !sysFwSearchFlag) {
 
-     return std::string{};
 
-   }
 
-   std::string frameworkPath;
 
-   auto const& fwDirs = cli.GetFrameworkPaths();
 
-   for (auto const& fd : fwDirs) {
 
-     if (sysFwSearchFlag &&
 
-         cli.GetTarget()->IsSystemIncludeDirectory(fd, cli.GetConfig(),
 
-                                                   cli.GetLinkLanguage())) {
 
-       frameworkPath += sysFwSearchFlag;
 
-     } else {
 
-       frameworkPath += fwSearchFlag;
 
-     }
 
-     frameworkPath += this->ConvertToOutputFormat(fd);
 
-     frameworkPath += " ";
 
-   }
 
-   return frameworkPath;
 
- }
 
- std::string cmLinkLineComputer::ComputeLinkLibraries(
 
-   cmComputeLinkInformation& cli, std::string const& stdLibString)
 
- {
 
-   std::string linkLibraries;
 
-   std::vector<BT<std::string>> linkLibrariesList;
 
-   this->ComputeLinkLibraries(cli, stdLibString, linkLibrariesList);
 
-   cli.AppendValues(linkLibraries, linkLibrariesList);
 
-   return linkLibraries;
 
- }
 
- void cmLinkLineComputer::ComputeLinkLibraries(
 
-   cmComputeLinkInformation& cli, std::string const& stdLibString,
 
-   std::vector<BT<std::string>>& linkLibraries)
 
- {
 
-   std::ostringstream rpathOut;
 
-   rpathOut << this->ComputeRPath(cli);
 
-   std::string rpath = rpathOut.str();
 
-   if (!rpath.empty()) {
 
-     linkLibraries.emplace_back(std::move(rpath));
 
-   }
 
-   // Write the library flags to the build rule.
 
-   this->ComputeLinkLibs(cli, linkLibraries);
 
-   // Add the linker runtime search path if any.
 
-   std::ostringstream fout;
 
-   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 << " ";
 
-   }
 
-   std::string remainingLibs = fout.str();
 
-   if (!remainingLibs.empty()) {
 
-     linkLibraries.emplace_back(remainingLibs);
 
-   }
 
- }
 
- std::string cmLinkLineComputer::GetLinkerLanguage(cmGeneratorTarget* target,
 
-                                                   std::string const& config)
 
- {
 
-   return target->GetLinkerLanguage(config);
 
- }
 
 
  |