summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Source/cmLinkLineDeviceComputer.cxx97
-rw-r--r--Source/cmLinkLineDeviceComputer.h6
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.cxx18
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx51
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx30
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx18
-rwxr-xr-xbootstrap1
7 files changed, 113 insertions, 108 deletions
diff --git a/Source/cmLinkLineDeviceComputer.cxx b/Source/cmLinkLineDeviceComputer.cxx
index 72edba3..6cfe5bb 100644
--- a/Source/cmLinkLineDeviceComputer.cxx
+++ b/Source/cmLinkLineDeviceComputer.cxx
@@ -3,14 +3,20 @@
#include "cmLinkLineDeviceComputer.h"
+#include <algorithm>
#include <set>
#include <sstream>
#include <utility>
+#include <vector>
#include "cmAlgorithms.h"
#include "cmComputeLinkInformation.h"
#include "cmGeneratorTarget.h"
+#include "cmLocalGenerator.h"
+#include "cmStateDirectory.h"
+#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
+#include "cmSystemTools.h"
class cmOutputConverter;
@@ -40,6 +46,27 @@ static bool cmLinkItemValidForDevice(std::string const& item)
cmHasLiteralPrefix(item, "--library"));
}
+bool cmLinkLineDeviceComputer::ComputeRequiresDeviceLinking(
+ cmComputeLinkInformation& cli)
+{
+ // Determine if this item might requires device linking.
+ // For this we only consider targets
+ typedef cmComputeLinkInformation::ItemVector ItemVector;
+ ItemVector const& items = cli.GetItems();
+ std::string config = cli.GetConfig();
+ for (auto const& item : items) {
+ if (item.Target &&
+ item.Target->GetType() == cmStateEnums::STATIC_LIBRARY) {
+ if ((!item.Target->GetPropertyAsBool("CUDA_RESOLVE_DEVICE_SYMBOLS")) &&
+ item.Target->GetPropertyAsBool("CUDA_SEPARABLE_COMPILATION")) {
+ // this dependency requires us to device link it
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
std::string cmLinkLineDeviceComputer::ComputeLinkLibraries(
cmComputeLinkInformation& cli, std::string const& stdLibString)
{
@@ -62,17 +89,12 @@ std::string cmLinkLineDeviceComputer::ComputeLinkLibraries(
}
if (item.Target) {
- bool skip = false;
- switch (item.Target->GetType()) {
- case cmStateEnums::MODULE_LIBRARY:
- case cmStateEnums::INTERFACE_LIBRARY:
- skip = true;
- break;
- case cmStateEnums::STATIC_LIBRARY:
- skip = item.Target->GetPropertyAsBool("CUDA_RESOLVE_DEVICE_SYMBOLS");
- break;
- default:
- break;
+ bool skip = true;
+ if (item.Target->GetType() == cmStateEnums::STATIC_LIBRARY) {
+ if ((!item.Target->GetPropertyAsBool("CUDA_RESOLVE_DEVICE_SYMBOLS")) &&
+ item.Target->GetPropertyAsBool("CUDA_SEPARABLE_COMPILATION")) {
+ skip = false;
+ }
}
if (skip) {
continue;
@@ -116,3 +138,56 @@ std::string cmLinkLineDeviceComputer::GetLinkerLanguage(cmGeneratorTarget*,
{
return "CUDA";
}
+
+bool requireDeviceLinking(cmGeneratorTarget& target, cmLocalGenerator& lg,
+ const std::string& config)
+{
+
+ if (target.GetType() == cmStateEnums::OBJECT_LIBRARY) {
+ 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);
+ }
+
+ 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;
+ }
+ }
+
+ // 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) {
+ cmComputeLinkInformation* pcli = target.GetLinkInformation(config);
+ if (pcli) {
+ cmLinkLineDeviceComputer deviceLinkComputer(
+ &lg, lg.GetStateSnapshot().GetDirectory());
+ return deviceLinkComputer.ComputeRequiresDeviceLinking(*pcli);
+ }
+ return true;
+ }
+ return false;
+}
diff --git a/Source/cmLinkLineDeviceComputer.h b/Source/cmLinkLineDeviceComputer.h
index 26fc125..0ea5f69 100644
--- a/Source/cmLinkLineDeviceComputer.h
+++ b/Source/cmLinkLineDeviceComputer.h
@@ -12,6 +12,7 @@
class cmComputeLinkInformation;
class cmGeneratorTarget;
+class cmLocalGenerator;
class cmOutputConverter;
class cmStateDirectory;
@@ -26,6 +27,8 @@ public:
cmLinkLineDeviceComputer& operator=(cmLinkLineDeviceComputer const&) =
delete;
+ bool ComputeRequiresDeviceLinking(cmComputeLinkInformation& cli);
+
std::string ComputeLinkLibraries(cmComputeLinkInformation& cli,
std::string const& stdLibString) override;
@@ -33,4 +36,7 @@ public:
std::string const& config) override;
};
+bool requireDeviceLinking(cmGeneratorTarget& target, cmLocalGenerator& lg,
+ const std::string& config);
+
#endif
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index beabf91..1113a2c 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -2,7 +2,6 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmMakefileExecutableTargetGenerator.h"
-#include <algorithm>
#include <memory> // IWYU pragma: keep
#include <set>
#include <sstream>
@@ -87,20 +86,9 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule(
return;
}
- const std::string cuda_lang("CUDA");
- cmGeneratorTarget::LinkClosure const* closure =
- this->GeneratorTarget->GetLinkClosure(this->ConfigName);
-
- const bool hasCUDA =
- (std::find(closure->Languages.begin(), closure->Languages.end(),
- cuda_lang) != closure->Languages.end());
-
- bool doDeviceLinking = true;
- if (const char* resolveDeviceSymbols =
- this->GeneratorTarget->GetProperty("CUDA_RESOLVE_DEVICE_SYMBOLS")) {
- doDeviceLinking = cmSystemTools::IsOn(resolveDeviceSymbols);
- }
- if (!hasCUDA || !doDeviceLinking) {
+ bool requiresDeviceLinking = requireDeviceLinking(
+ *this->GeneratorTarget, *this->LocalGenerator, this->ConfigName);
+ if (!requiresDeviceLinking) {
return;
}
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index f5d1fc9..d4d565d 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -2,7 +2,6 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmMakefileLibraryTargetGenerator.h"
-#include <algorithm>
#include <memory> // IWYU pragma: keep
#include <set>
#include <sstream>
@@ -124,20 +123,10 @@ void cmMakefileLibraryTargetGenerator::WriteObjectLibraryRules()
void cmMakefileLibraryTargetGenerator::WriteStaticLibraryRules()
{
- const std::string cuda_lang("CUDA");
- cmGeneratorTarget::LinkClosure const* closure =
- this->GeneratorTarget->GetLinkClosure(this->ConfigName);
-
- const bool hasCUDA =
- (std::find(closure->Languages.begin(), closure->Languages.end(),
- cuda_lang) != closure->Languages.end());
-
- bool doDeviceLinking = false;
- if (const char* resolveDeviceSymbols =
- this->GeneratorTarget->GetProperty("CUDA_RESOLVE_DEVICE_SYMBOLS")) {
- doDeviceLinking = cmSystemTools::IsOn(resolveDeviceSymbols);
- }
- if (hasCUDA && doDeviceLinking) {
+
+ bool requiresDeviceLinking = requireDeviceLinking(
+ *this->GeneratorTarget, *this->LocalGenerator, this->ConfigName);
+ if (requiresDeviceLinking) {
std::string linkRuleVar = "CMAKE_CUDA_DEVICE_LINK_LIBRARY";
this->WriteDeviceLibraryRules(linkRuleVar, false);
}
@@ -163,19 +152,9 @@ void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink)
}
if (!relink) {
- const std::string cuda_lang("CUDA");
- cmGeneratorTarget::LinkClosure const* closure =
- this->GeneratorTarget->GetLinkClosure(this->ConfigName);
-
- const bool hasCUDA =
- (std::find(closure->Languages.begin(), closure->Languages.end(),
- cuda_lang) != closure->Languages.end());
- bool doDeviceLinking = true;
- if (const char* resolveDeviceSymbols =
- this->GeneratorTarget->GetProperty("CUDA_RESOLVE_DEVICE_SYMBOLS")) {
- doDeviceLinking = cmSystemTools::IsOn(resolveDeviceSymbols);
- }
- if (hasCUDA && doDeviceLinking) {
+ bool requiresDeviceLinking = requireDeviceLinking(
+ *this->GeneratorTarget, *this->LocalGenerator, this->ConfigName);
+ if (requiresDeviceLinking) {
std::string linkRuleVar = "CMAKE_CUDA_DEVICE_LINK_LIBRARY";
this->WriteDeviceLibraryRules(linkRuleVar, relink);
}
@@ -209,19 +188,9 @@ void cmMakefileLibraryTargetGenerator::WriteModuleLibraryRules(bool relink)
{
if (!relink) {
- const std::string cuda_lang("CUDA");
- cmGeneratorTarget::LinkClosure const* closure =
- this->GeneratorTarget->GetLinkClosure(this->ConfigName);
-
- const bool hasCUDA =
- (std::find(closure->Languages.begin(), closure->Languages.end(),
- cuda_lang) != closure->Languages.end());
- bool doDeviceLinking = true;
- if (const char* resolveDeviceSymbols =
- this->GeneratorTarget->GetProperty("CUDA_RESOLVE_DEVICE_SYMBOLS")) {
- doDeviceLinking = cmSystemTools::IsOn(resolveDeviceSymbols);
- }
- if (hasCUDA && doDeviceLinking) {
+ bool requiresDeviceLinking = requireDeviceLinking(
+ *this->GeneratorTarget, *this->LocalGenerator, this->ConfigName);
+ if (requiresDeviceLinking) {
std::string linkRuleVar = "CMAKE_CUDA_DEVICE_LINK_LIBRARY";
this->WriteDeviceLibraryRules(linkRuleVar, relink);
}
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index 4d13006..f8a13ce 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -18,6 +18,7 @@
#include "cmGeneratorTarget.h"
#include "cmGlobalNinjaGenerator.h"
#include "cmLinkLineComputer.h"
+#include "cmLinkLineDeviceComputer.h"
#include "cmLocalGenerator.h"
#include "cmLocalNinjaGenerator.h"
#include "cmMakefile.h"
@@ -571,32 +572,9 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement()
cmGeneratorTarget& genTarget = *this->GetGeneratorTarget();
- // determine if we need to do any device linking for this target
- const std::string cuda_lang("CUDA");
- cmGeneratorTarget::LinkClosure const* closure =
- genTarget.GetLinkClosure(this->GetConfigName());
-
- const bool hasCUDA =
- (std::find(closure->Languages.begin(), closure->Languages.end(),
- cuda_lang) != closure->Languages.end());
-
- bool doDeviceLinking = false;
- if (const char* resolveDeviceSymbols =
- genTarget.GetProperty("CUDA_RESOLVE_DEVICE_SYMBOLS")) {
- doDeviceLinking = cmSystemTools::IsOn(resolveDeviceSymbols);
- } else {
- switch (genTarget.GetType()) {
- case cmStateEnums::SHARED_LIBRARY:
- case cmStateEnums::MODULE_LIBRARY:
- case cmStateEnums::EXECUTABLE:
- doDeviceLinking = true;
- break;
- default:
- break;
- }
- }
-
- if (!(doDeviceLinking && hasCUDA)) {
+ bool requiresDeviceLinking = requireDeviceLinking(
+ *this->GeneratorTarget, *this->GetLocalGenerator(), this->ConfigName);
+ if (!requiresDeviceLinking) {
return;
}
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index c60706d..0685a41 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -10,6 +10,7 @@
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalVisualStudio10Generator.h"
+#include "cmLinkLineDeviceComputer.h"
#include "cmLocalVisualStudio10Generator.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
@@ -3007,21 +3008,8 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaLinkOptions(
Options& cudaLinkOptions = *pOptions;
// Determine if we need to do a device link
- bool doDeviceLinking = false;
- if (const char* resolveDeviceSymbols =
- this->GeneratorTarget->GetProperty("CUDA_RESOLVE_DEVICE_SYMBOLS")) {
- doDeviceLinking = cmSystemTools::IsOn(resolveDeviceSymbols);
- } else {
- switch (this->GeneratorTarget->GetType()) {
- case cmStateEnums::SHARED_LIBRARY:
- case cmStateEnums::MODULE_LIBRARY:
- case cmStateEnums::EXECUTABLE:
- doDeviceLinking = true;
- break;
- default:
- break;
- }
- }
+ bool doDeviceLinking = requireDeviceLinking(
+ *this->GeneratorTarget, *this->LocalGenerator, configName);
cudaLinkOptions.AddFlag("PerformDeviceLink",
doDeviceLinking ? "true" : "false");
diff --git a/bootstrap b/bootstrap
index c5274ce..ce27ca6 100755
--- a/bootstrap
+++ b/bootstrap
@@ -359,6 +359,7 @@ CMAKE_CXX_SOURCES="\
cmLinkDirectoriesCommand \
cmLinkItem \
cmLinkLineComputer \
+ cmLinkLineDeviceComputer \
cmListCommand \
cmListFileCache \
cmLocalCommonGenerator \