ソースを参照

CUDA: Compute CMAKE_CUDA_RUNTIME_LIBRARY default from toolchain

Since commit 0d0145138f (CUDA: Add abstraction for cuda runtime
selection, 2019-11-29, v3.17.0-rc1~83^2) we add CUDA runtime library
selection flags by default.

To maintain backwards compatibility the default CUDA runtime
library needs to be computed based on what libraries are found
on the initial compiler invocation. For example a toolchain
could establish initial flags that have all CUDA compilations
using the runtime version, and if we don't detect this we will
try to link to both the static and shared runtime.

Co-Author: Brad King <[email protected]>
Fixes: #20708
Robert Maynard 5 年 前
コミット
e55b21e24e

+ 2 - 2
Help/prop_tgt/CUDA_RUNTIME_LIBRARY.rst

@@ -10,8 +10,8 @@ The allowed case insensitive values are:
 Contents of ``CUDA_RUNTIME_LIBRARY`` may use
 :manual:`generator expressions <cmake-generator-expressions(7)>`.
 
-If this property is not set then CMake uses the default value
-``Static`` to select the CUDA runtime library.
+If that property is not set then CMake uses an appropriate default
+value based on the compiler to select the CUDA runtime library.
 
 .. note::
 

+ 2 - 1
Help/variable/CMAKE_CUDA_RUNTIME_LIBRARY.rst

@@ -14,7 +14,8 @@ Contents of ``CMAKE_CUDA_RUNTIME_LIBRARY`` may use
 
 If this variable is not set then the :prop_tgt:`CUDA_RUNTIME_LIBRARY` target
 property will not be set automatically.  If that property is not set then
-CMake uses the default value ``Static`` to select the CUDA runtime library.
+CMake uses an appropriate default value based on the compiler to select the
+CUDA runtime library.
 
 .. note::
 

+ 2 - 0
Modules/CMakeCUDACompiler.cmake.in

@@ -53,5 +53,7 @@ set(CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES "@CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES@")
 set(CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES "@CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES@")
 set(CMAKE_CUDA_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "@CMAKE_CUDA_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES@")
 
+@_SET_CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT@
+
 set(CMAKE_LINKER "@CMAKE_LINKER@")
 set(CMAKE_MT "@CMAKE_MT@")

+ 28 - 0
Modules/CMakeDetermineCUDACompiler.cmake

@@ -86,6 +86,20 @@ if(${CMAKE_GENERATOR} MATCHES "Visual Studio")
   set(CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES "")
   set(CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES "")
   set(CMAKE_CUDA_HOST_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "")
+
+  # We do not currently detect CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES but we
+  # do need to detect CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT from the compiler by
+  # looking at which cudart library exists in the implicit link libraries passed
+  # to the host linker.
+  if(CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT MATCHES "link\\.exe [^\n]*cudart_static\\.lib")
+    set(CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT "STATIC")
+  elseif(CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT MATCHES "link\\.exe [^\n]*cudart\\.lib")
+    set(CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT "SHARED")
+  else()
+    set(CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT "NONE")
+  endif()
+  set(_SET_CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT
+    "set(CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT \"${CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT}\")")
 elseif(CMAKE_CUDA_COMPILER_ID STREQUAL NVIDIA)
   set(_nvcc_log "")
   string(REPLACE "\r" "" _nvcc_output_orig "${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}")
@@ -179,6 +193,20 @@ elseif(CMAKE_CUDA_COMPILER_ID STREQUAL NVIDIA)
                                    log
                                    "${CMAKE_CUDA_IMPLICIT_OBJECT_REGEX}")
 
+    # Detect CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT from the compiler by looking at which
+    # cudart library exists in the implicit link libraries passed to the host linker.
+    # This is required when a project sets the cuda runtime library as part of the
+    # initial flags.
+    if(";${CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES};" MATCHES [[;cudart_static(\.lib)?;]])
+      set(CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT "STATIC")
+    elseif(";${CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES};" MATCHES [[;cudart(\.lib)?;]])
+      set(CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT "SHARED")
+    else()
+      set(CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT "NONE")
+    endif()
+    set(_SET_CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT
+      "set(CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT \"${CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT}\")")
+
     file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
       "Parsed CUDA nvcc implicit link information from above output:\n${_nvcc_log}\n${log}\n\n")
   else()

+ 5 - 1
Modules/CMakeDetermineCompilerId.cmake

@@ -381,7 +381,11 @@ Id flags: ${testflags} ${CMAKE_${lang}_COMPILER_ID_FLAGS_ALWAYS}
       if(CMAKE_VS_PLATFORM_NAME STREQUAL x64)
         set(id_ItemDefinitionGroup_entry "<CudaCompile><TargetMachinePlatform>64</TargetMachinePlatform><AdditionalOptions>%(AdditionalOptions)-v</AdditionalOptions></CudaCompile>")
       endif()
-      set(id_Link_AdditionalDependencies "<AdditionalDependencies>cudart.lib</AdditionalDependencies>")
+      if(CMAKE_CUDA_FLAGS MATCHES "(^| )-cudart +shared( |$)")
+        set(id_Link_AdditionalDependencies "<AdditionalDependencies>cudart.lib</AdditionalDependencies>")
+      else()
+        set(id_Link_AdditionalDependencies "<AdditionalDependencies>cudart_static.lib</AdditionalDependencies>")
+      endif()
     endif()
     configure_file(${CMAKE_ROOT}/Modules/CompilerId/VS-${v}.${ext}.in
       ${id_dir}/CompilerId${lang}.${ext} @ONLY)

+ 0 - 1
Modules/Compiler/NVIDIA-CUDA.cmake

@@ -43,7 +43,6 @@ endif()
 set(CMAKE_SHARED_LIBRARY_CREATE_CUDA_FLAGS -shared)
 set(CMAKE_INCLUDE_SYSTEM_FLAG_CUDA -isystem=)
 
-set(CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT "STATIC")
 set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_STATIC  "cudadevrt;cudart_static")
 set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_SHARED  "cudadevrt;cudart")
 set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_NONE    "")

+ 0 - 1
Modules/Platform/Windows-NVIDIA-CUDA.cmake

@@ -69,7 +69,6 @@ else()
 endif()
 unset(_cmp0092)
 
-set(CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT "STATIC")
 set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_STATIC  "cudadevrt;cudart_static")
 set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_SHARED  "cudadevrt;cudart")
 set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_NONE    "")

+ 1 - 0
Tests/CudaOnly/CMakeLists.txt

@@ -6,6 +6,7 @@ ADD_TEST_MACRO(CudaOnly.GPUDebugFlag CudaOnlyGPUDebugFlag)
 ADD_TEST_MACRO(CudaOnly.ResolveDeviceSymbols CudaOnlyResolveDeviceSymbols)
 ADD_TEST_MACRO(CudaOnly.SeparateCompilation CudaOnlySeparateCompilation)
 ADD_TEST_MACRO(CudaOnly.SharedRuntimePlusToolkit CudaOnlySharedRuntimePlusToolkit)
+ADD_TEST_MACRO(CudaOnly.SharedRuntimeViaCUDAFlags CudaOnlySharedRuntimeViaCUDAFlags)
 ADD_TEST_MACRO(CudaOnly.Standard98 CudaOnlyStandard98)
 ADD_TEST_MACRO(CudaOnly.Toolkit CudaOnlyToolkit)
 ADD_TEST_MACRO(CudaOnly.WithDefs CudaOnlyWithDefs)

+ 15 - 0
Tests/CudaOnly/SharedRuntimeViaCUDAFlags/CMakeLists.txt

@@ -0,0 +1,15 @@
+cmake_minimum_required(VERSION 3.17)
+project(SharedRuntimeViaCUDAFlags NONE)
+
+set(CMAKE_CUDA_FLAGS "")
+string(APPEND CMAKE_CUDA_FLAGS "-cudart shared")
+
+enable_language(CUDA)
+
+add_executable(CudaOnlySharedRuntimeViaCUDAFlags main.cu)
+
+if(UNIX)
+  # Help the shared cuda runtime find libcudart as it is not located
+  # in a default system searched location
+  set_property(TARGET CudaOnlySharedRuntimeViaCUDAFlags PROPERTY BUILD_RPATH ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES})
+endif()

+ 5 - 0
Tests/CudaOnly/SharedRuntimeViaCUDAFlags/main.cu

@@ -0,0 +1,5 @@
+
+int main()
+{
+  return 0;
+}