summaryrefslogtreecommitdiff
path: root/Source/cmLinkLineDeviceComputer.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmLinkLineDeviceComputer.cxx')
-rw-r--r--Source/cmLinkLineDeviceComputer.cxx100
1 files changed, 58 insertions, 42 deletions
diff --git a/Source/cmLinkLineDeviceComputer.cxx b/Source/cmLinkLineDeviceComputer.cxx
index 2cb2fd635..d8456523d 100644
--- a/Source/cmLinkLineDeviceComputer.cxx
+++ b/Source/cmLinkLineDeviceComputer.cxx
@@ -3,21 +3,21 @@
#include "cmLinkLineDeviceComputer.h"
-#include <algorithm>
#include <set>
-#include <sstream>
#include <utility>
-#include <vector>
#include "cmAlgorithms.h"
#include "cmComputeLinkInformation.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
+#include "cmLinkItem.h"
+#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
+#include "cmMakefile.h"
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
-#include "cmSystemTools.h"
+#include "cmStringAlgorithms.h"
class cmOutputConverter;
@@ -52,7 +52,7 @@ bool cmLinkLineDeviceComputer::ComputeRequiresDeviceLinking(
{
// Determine if this item might requires device linking.
// For this we only consider targets
- typedef cmComputeLinkInformation::ItemVector ItemVector;
+ using ItemVector = cmComputeLinkInformation::ItemVector;
ItemVector const& items = cli.GetItems();
std::string config = cli.GetConfig();
for (auto const& item : items) {
@@ -68,21 +68,22 @@ bool cmLinkLineDeviceComputer::ComputeRequiresDeviceLinking(
return false;
}
-std::string cmLinkLineDeviceComputer::ComputeLinkLibraries(
- cmComputeLinkInformation& cli, std::string const& stdLibString)
+void cmLinkLineDeviceComputer::ComputeLinkLibraries(
+ cmComputeLinkInformation& cli, std::string const& stdLibString,
+ std::vector<BT<std::string>>& linkLibraries)
{
- // Write the library flags to the build rule.
- std::ostringstream fout;
-
// Generate the unique set of link items when device linking.
// The nvcc device linker is designed so that each static library
// with device symbols only needs to be listed once as it doesn't
// care about link order.
std::set<std::string> emitted;
- typedef cmComputeLinkInformation::ItemVector ItemVector;
+ using ItemVector = cmComputeLinkInformation::ItemVector;
ItemVector const& items = cli.GetItems();
std::string config = cli.GetConfig();
bool skipItemAfterFramework = false;
+ // Note:
+ // Any modification of this algorithm should be reflected also in
+ // cmVisualStudio10TargetGenerator::ComputeCudaLinkOptions
for (auto const& item : items) {
if (skipItemAfterFramework) {
skipItemAfterFramework = false;
@@ -92,6 +93,7 @@ std::string cmLinkLineDeviceComputer::ComputeLinkLibraries(
if (item.Target) {
bool skip = false;
switch (item.Target->GetType()) {
+ case cmStateEnums::SHARED_LIBRARY:
case cmStateEnums::MODULE_LIBRARY:
case cmStateEnums::INTERFACE_LIBRARY:
skip = true;
@@ -107,7 +109,7 @@ std::string cmLinkLineDeviceComputer::ComputeLinkLibraries(
}
}
- std::string out;
+ BT<std::string> linkLib;
if (item.IsPath) {
// nvcc understands absolute paths to libraries ending in '.a' or '.lib'.
// These should be passed to nvlink. Other extensions need to be left
@@ -115,7 +117,7 @@ std::string cmLinkLineDeviceComputer::ComputeLinkLibraries(
// can tolerate '.so' or '.dylib' it cannot tolerate '.so.1'.
if (cmHasLiteralSuffix(item.Value, ".a") ||
cmHasLiteralSuffix(item.Value, ".lib")) {
- out += this->ConvertToOutputFormat(
+ linkLib.Value += this->ConvertToOutputFormat(
this->ConvertToLinkReference(item.Value));
}
} else if (item.Value == "-framework") {
@@ -124,19 +126,33 @@ std::string cmLinkLineDeviceComputer::ComputeLinkLibraries(
skipItemAfterFramework = true;
continue;
} else if (cmLinkItemValidForDevice(item.Value)) {
- out += item.Value;
+ linkLib.Value += item.Value;
}
- if (emitted.insert(out).second) {
- fout << out << " ";
+ if (emitted.insert(linkLib.Value).second) {
+ 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);
}
}
if (!stdLibString.empty()) {
- fout << stdLibString << " ";
+ linkLibraries.emplace_back(cmStrCat(stdLibString, ' '));
}
-
- return fout.str();
}
std::string cmLinkLineDeviceComputer::GetLinkerLanguage(cmGeneratorTarget*,
@@ -156,40 +172,40 @@ bool requireDeviceLinking(cmGeneratorTarget& target, cmLocalGenerator& lg,
return false;
}
+ if (!lg.GetMakefile()->IsOn("CMAKE_CUDA_COMPILER_HAS_DEVICE_LINK_PHASE")) {
+ return false;
+ }
+
if (const char* resolveDeviceSymbols =
target.GetProperty("CUDA_RESOLVE_DEVICE_SYMBOLS")) {
// If CUDA_RESOLVE_DEVICE_SYMBOLS has been explicitly set we need
// to honor the value no matter what it is.
- return cmSystemTools::IsOn(resolveDeviceSymbols);
+ return cmIsOn(resolveDeviceSymbols);
+ }
+
+ if (const char* separableCompilation =
+ target.GetProperty("CUDA_SEPARABLE_COMPILATION")) {
+ if (cmIsOn(separableCompilation)) {
+ bool doDeviceLinking = false;
+ switch (target.GetType()) {
+ case cmStateEnums::SHARED_LIBRARY:
+ case cmStateEnums::MODULE_LIBRARY:
+ case cmStateEnums::EXECUTABLE:
+ doDeviceLinking = true;
+ break;
+ default:
+ break;
+ }
+ return doDeviceLinking;
+ }
}
// Determine if we have any dependencies that require
// us to do a device link step
- const std::string cuda_lang("CUDA");
cmGeneratorTarget::LinkClosure const* closure =
target.GetLinkClosure(config);
- bool closureHasCUDA =
- (std::find(closure->Languages.begin(), closure->Languages.end(),
- cuda_lang) != closure->Languages.end());
-
- if (closureHasCUDA) {
- if (const char* separableCompilation =
- target.GetProperty("CUDA_SEPARABLE_COMPILATION")) {
- if (cmSystemTools::IsOn(separableCompilation)) {
- bool doDeviceLinking = false;
- switch (target.GetType()) {
- case cmStateEnums::SHARED_LIBRARY:
- case cmStateEnums::MODULE_LIBRARY:
- case cmStateEnums::EXECUTABLE:
- doDeviceLinking = true;
- break;
- default:
- break;
- }
- return doDeviceLinking;
- }
- }
+ if (cmContains(closure->Languages, "CUDA")) {
cmComputeLinkInformation* pcli = target.GetLinkInformation(config);
if (pcli) {
cmLinkLineDeviceComputer deviceLinkComputer(