浏览代码

CUDA: Support nvcc symlinking to ccache

Invoke `nvcc -v` to find the real CUDA bin directory.
This is needed if `nvcc` is a symlink to `ccache` or `colornvcc`.

Fixes: #21177
Rong Ou 5 年之前
父节点
当前提交
fb2afef620

+ 9 - 0
Help/release/dev/cuda-nvcc-ccache-symlink.rst

@@ -0,0 +1,9 @@
+cuda-nvcc-ccache-symlink
+------------------------
+
+* ``CUDA`` language support now works when ``nvcc`` is a symbolic link,
+  for example due to a ``ccache`` or ``colornvcc`` wrapper script.
+
+* The :module:`FindCUDAToolkit` module gained support for finding CUDA
+  toolkits when ``nvcc`` is a symbolic link,
+  for example due to a ``ccache`` or ``colornvcc`` wrapper script.

+ 14 - 1
Modules/CMakeDetermineCUDACompiler.cmake

@@ -172,7 +172,20 @@ if(NOT CMAKE_CUDA_COMPILER_ID_RUN)
       endif()
     endif()
 
-    get_filename_component(CMAKE_CUDA_COMPILER_TOOLKIT_ROOT "${_CUDA_NVCC_EXECUTABLE}" DIRECTORY)
+    # If NVCC is a symlink due to a wrapper script (e.g. ccache or colornvcc), then invoke it to find the
+    # real non-scattered toolkit.
+    if(IS_SYMLINK ${_CUDA_NVCC_EXECUTABLE})
+      execute_process(COMMAND ${_CUDA_NVCC_EXECUTABLE} "-v" "__cmake_determine_cuda" ERROR_VARIABLE NVCC_ERR)
+      if(NVCC_ERR MATCHES " _HERE_=([^\r\n]*)")
+        set(CMAKE_CUDA_COMPILER_TOOLKIT_ROOT "${CMAKE_MATCH_1}")
+      else()
+        message(FATAL_ERROR "Could not execute nvcc with -v.")
+      endif()
+      unset(NVCC_ERR)
+    else()
+      get_filename_component(CMAKE_CUDA_COMPILER_TOOLKIT_ROOT "${_CUDA_NVCC_EXECUTABLE}" DIRECTORY)
+    endif()
+
     set(CMAKE_CUDA_DEVICE_LINKER "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}/nvlink${CMAKE_EXECUTABLE_SUFFIX}")
     set(CMAKE_CUDA_FATBINARY "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}/fatbinary${CMAKE_EXECUTABLE_SUFFIX}")
     get_filename_component(CMAKE_CUDA_COMPILER_TOOLKIT_ROOT "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}" DIRECTORY)

+ 14 - 1
Modules/FindCUDA.cmake

@@ -834,7 +834,20 @@ if(NOT CUDA_TOOLKIT_ROOT_DIR AND NOT CMAKE_CROSSCOMPILING)
     )
 
   if (CUDA_TOOLKIT_ROOT_DIR_NVCC)
-    get_filename_component(CUDA_TOOLKIT_ROOT_DIR_NVCC_PAR "${CUDA_TOOLKIT_ROOT_DIR_NVCC}" DIRECTORY)
+    # If NVCC is a symlink due to a wrapper script (e.g. ccache or colornvcc), then invoke it to find the
+    # real non-scattered toolkit.
+    if(IS_SYMLINK ${CUDA_TOOLKIT_ROOT_DIR_NVCC})
+      execute_process(COMMAND ${CUDA_TOOLKIT_ROOT_DIR_NVCC} "-v" "__cmake_determine_cuda" ERROR_VARIABLE NVCC_ERR)
+      if(NVCC_ERR MATCHES " _HERE_=([^\r\n]*)")
+        set(CUDA_TOOLKIT_ROOT_DIR_NVCC_PAR "${CMAKE_MATCH_1}")
+      else()
+        message(FATAL_ERROR "Could not execute nvcc with -v.")
+      endif()
+      unset(NVCC_ERR)
+    else()
+      get_filename_component(CUDA_TOOLKIT_ROOT_DIR_NVCC_PAR "${CUDA_TOOLKIT_ROOT_DIR_NVCC}" DIRECTORY)
+    endif()
+
     get_filename_component(CUDA_TOOLKIT_ROOT_DIR "${CUDA_TOOLKIT_ROOT_DIR_NVCC_PAR}" DIRECTORY CACHE)
     string(REGEX REPLACE "[/\\\\]?bin[64]*[/\\\\]?$" "" CUDA_TOOLKIT_ROOT_DIR ${CUDA_TOOLKIT_ROOT_DIR})
     # We need to force this back into the cache.

+ 13 - 1
Modules/FindCUDAToolkit.cmake

@@ -519,7 +519,19 @@ else()
       endif()
 
       if(CUDAToolkit_NVCC_EXECUTABLE)
-        get_filename_component(CUDAToolkit_BIN_DIR "${CUDAToolkit_NVCC_EXECUTABLE}" DIRECTORY)
+        # If NVCC is a symlink due to a wrapper script (e.g. ccache or colornvcc), then invoke it to find the
+        # real non-scattered toolkit.
+        if(IS_SYMLINK ${CUDAToolkit_NVCC_EXECUTABLE})
+          execute_process(COMMAND ${CUDAToolkit_NVCC_EXECUTABLE} "-v" "__cmake_determine_cuda" ERROR_VARIABLE NVCC_ERR)
+          if(NVCC_ERR MATCHES " _HERE_=([^\r\n]*)")
+            set(CUDAToolkit_BIN_DIR "${CMAKE_MATCH_1}")
+          else()
+            message(FATAL_ERROR "Could not execute nvcc with -v.")
+          endif()
+          unset(NVCC_ERR)
+        else()
+          get_filename_component(CUDAToolkit_BIN_DIR "${CUDAToolkit_NVCC_EXECUTABLE}" DIRECTORY)
+        endif()
 
         set(CUDAToolkit_BIN_DIR "${CUDAToolkit_BIN_DIR}" CACHE PATH "" FORCE)
         mark_as_advanced(CUDAToolkit_BIN_DIR)