Browse Source

CUDA: Do not device link if target has no CUDA usage

When CUDA is enabled, and a pure non-CUDA target has
CMAKE_CUDA_SEPARABLE_COMPILATION enabled, don't actually perform
the device linking step, as it will fail. A target that has
CMAKE_CUDA_SEPARABLE_COMPILATION enabled must also have CUDA
usage (either itself, or something it links to).

Fixes: #20182
Robert Maynard 5 years ago
parent
commit
071c4f1a2a

+ 18 - 18
Source/cmLinkLineDeviceComputer.cxx

@@ -163,33 +163,33 @@ bool requireDeviceLinking(cmGeneratorTarget& target, cmLocalGenerator& lg,
     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) {
+    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;
+      }
+    }
+
     cmComputeLinkInformation* pcli = target.GetLinkInformation(config);
     if (pcli) {
       cmLinkLineDeviceComputer deviceLinkComputer(

+ 1 - 0
Tests/Cuda/CMakeLists.txt

@@ -4,6 +4,7 @@ ADD_TEST_MACRO(Cuda.ConsumeCompileFeatures CudaConsumeCompileFeatures)
 ADD_TEST_MACRO(Cuda.ObjectLibrary CudaObjectLibrary)
 ADD_TEST_MACRO(Cuda.MixedStandardLevels MixedStandardLevels)
 ADD_TEST_MACRO(Cuda.NotEnabled CudaNotEnabled)
+ADD_TEST_MACRO(Cuda.SeparableCompCXXOnly SeparableCompCXXOnly)
 ADD_TEST_MACRO(Cuda.ToolkitInclude CudaToolkitInclude)
 ADD_TEST_MACRO(Cuda.ProperDeviceLibraries ProperDeviceLibraries)
 ADD_TEST_MACRO(Cuda.ProperLinkFlags ProperLinkFlags)

+ 3 - 0
Tests/Cuda/SeparableCompCXXOnly/CMakeLists.txt

@@ -0,0 +1,3 @@
+project(SeparableCompCXXOnly LANGUAGES CXX CUDA)
+set(CMAKE_CUDA_SEPARABLE_COMPILATION ON)
+add_executable(SeparableCompCXXOnly main.cpp)

+ 5 - 0
Tests/Cuda/SeparableCompCXXOnly/main.cpp

@@ -0,0 +1,5 @@
+
+int main(int, char const* [])
+{
+  return 0;
+}