|
|
@@ -4,10 +4,13 @@
|
|
|
#include "cmLinkLineComputer.h"
|
|
|
|
|
|
#include <sstream>
|
|
|
+#include <utility>
|
|
|
#include <vector>
|
|
|
|
|
|
#include "cmComputeLinkInformation.h"
|
|
|
#include "cmGeneratorTarget.h"
|
|
|
+#include "cmLinkItem.h"
|
|
|
+#include "cmListFileCache.h"
|
|
|
#include "cmOutputConverter.h"
|
|
|
#include "cmStateDirectory.h"
|
|
|
#include "cmStateTypes.h"
|
|
|
@@ -56,6 +59,15 @@ std::string cmLinkLineComputer::ConvertToLinkReference(
|
|
|
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) {
|
|
|
@@ -63,16 +75,33 @@ std::string cmLinkLineComputer::ComputeLinkLibs(cmComputeLinkInformation& cli)
|
|
|
item.Target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
|
|
|
continue;
|
|
|
}
|
|
|
+
|
|
|
+ BT<std::string> linkLib;
|
|
|
if (item.IsPath) {
|
|
|
- linkLibs += cli.GetLibLinkFileFlag();
|
|
|
- linkLibs +=
|
|
|
+ linkLib.Value += cli.GetLibLinkFileFlag();
|
|
|
+ linkLib.Value +=
|
|
|
this->ConvertToOutputFormat(this->ConvertToLinkReference(item.Value));
|
|
|
} else {
|
|
|
- linkLibs += item.Value;
|
|
|
+ linkLib.Value += item.Value;
|
|
|
}
|
|
|
- linkLibs += " ";
|
|
|
+ linkLib.Value += " ";
|
|
|
+
|
|
|
+ const cmLinkImplementation* linkImpl =
|
|
|
+ cli.GetTarget()->GetLinkImplementation(cli.GetConfig());
|
|
|
+
|
|
|
+ for (const cmLinkImplItem& iter : linkImpl->Libraries) {
|
|
|
+ if (iter.Target != nullptr &&
|
|
|
+ iter.Target->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
|
|
|
+ std::string libPath = iter.Target->GetLocation(cli.GetConfig());
|
|
|
+ if (item.Value == libPath) {
|
|
|
+ linkLib.Backtrace = iter.Backtrace;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ linkLibraries.emplace_back(linkLib);
|
|
|
}
|
|
|
- return linkLibs;
|
|
|
}
|
|
|
|
|
|
std::string cmLinkLineComputer::ConvertToOutputFormat(std::string const& input)
|
|
|
@@ -101,8 +130,19 @@ std::string cmLinkLineComputer::ComputeLinkPath(
|
|
|
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) {
|
|
|
@@ -116,20 +156,23 @@ std::string cmLinkLineComputer::ComputeLinkPath(
|
|
|
type = cmStateEnums::ImportLibraryArtifact;
|
|
|
}
|
|
|
|
|
|
- linkPath += cmStrCat(" ", libPathFlag,
|
|
|
- item.Target->GetDirectory(cli.GetConfig(), type),
|
|
|
- libPathTerminator, " ");
|
|
|
+ linkPathNoBT += cmStrCat(
|
|
|
+ " ", libPathFlag, item.Target->GetDirectory(cli.GetConfig(), type),
|
|
|
+ libPathTerminator, " ");
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- for (std::string const& libDir : cli.GetDirectories()) {
|
|
|
- linkPath +=
|
|
|
- cmStrCat(" ", libPathFlag, this->ConvertToOutputForExisting(libDir),
|
|
|
- libPathTerminator, " ");
|
|
|
+ if (!linkPathNoBT.empty()) {
|
|
|
+ linkPath.emplace_back(std::move(linkPathNoBT));
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- return linkPath;
|
|
|
+ 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)
|
|
|
@@ -179,13 +222,30 @@ std::string cmLinkLineComputer::ComputeFrameworkPath(
|
|
|
std::string cmLinkLineComputer::ComputeLinkLibraries(
|
|
|
cmComputeLinkInformation& cli, std::string const& stdLibString)
|
|
|
{
|
|
|
- std::ostringstream fout;
|
|
|
- fout << this->ComputeRPath(cli);
|
|
|
+ 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.
|
|
|
- fout << this->ComputeLinkLibs(cli);
|
|
|
+ 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();
|
|
|
@@ -198,7 +258,10 @@ std::string cmLinkLineComputer::ComputeLinkLibraries(
|
|
|
fout << stdLibString << " ";
|
|
|
}
|
|
|
|
|
|
- return fout.str();
|
|
|
+ std::string remainingLibs = fout.str();
|
|
|
+ if (!remainingLibs.empty()) {
|
|
|
+ linkLibraries.emplace_back(remainingLibs);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
std::string cmLinkLineComputer::GetLinkerLanguage(cmGeneratorTarget* target,
|