From 82521e359f9afbb1644d1b8eae58f27a51407df3 Mon Sep 17 00:00:00 2001
From: Brad King <brad.king@kitware.com>
Date: Tue, 7 Mar 2017 14:32:35 -0500
Subject: [PATCH] VS: Add support for determining CUDA compiler id

Teach `CMakeDetermineCompilerId` how to generate a vcxproj file using
the `CMAKE_VS_PLATFORM_TOOLSET_CUDA`.
---
 Modules/CMakeDetermineCUDACompiler.cmake | 51 ++++++++++++++----------
 Modules/CMakeDetermineCompilerId.cmake   | 14 +++++++
 2 files changed, 44 insertions(+), 21 deletions(-)

diff --git a/Modules/CMakeDetermineCUDACompiler.cmake b/Modules/CMakeDetermineCUDACompiler.cmake
index 375e2307de..55a6f0ceb5 100644
--- a/Modules/CMakeDetermineCUDACompiler.cmake
+++ b/Modules/CMakeDetermineCUDACompiler.cmake
@@ -5,36 +5,40 @@ include(${CMAKE_ROOT}/Modules/CMakeDetermineCompiler.cmake)
 include(${CMAKE_ROOT}/Modules//CMakeParseImplicitLinkInfo.cmake)
 
 if( NOT ( ("${CMAKE_GENERATOR}" MATCHES "Make") OR
-          ("${CMAKE_GENERATOR}" MATCHES "Ninja") ) )
+          ("${CMAKE_GENERATOR}" MATCHES "Ninja") OR
+          ("${CMAKE_GENERATOR}" MATCHES "Visual Studio (1|[7-9][0-9])") ) )
   message(FATAL_ERROR "CUDA language not currently supported by \"${CMAKE_GENERATOR}\" generator")
 endif()
 
-if(NOT CMAKE_CUDA_COMPILER)
-  set(CMAKE_CUDA_COMPILER_INIT NOTFOUND)
-
-    # prefer the environment variable CUDACXX
-    if(NOT $ENV{CUDACXX} STREQUAL "")
-      get_filename_component(CMAKE_CUDA_COMPILER_INIT $ENV{CUDACXX} PROGRAM PROGRAM_ARGS CMAKE_CUDA_FLAGS_ENV_INIT)
-      if(CMAKE_CUDA_FLAGS_ENV_INIT)
-        set(CMAKE_CUDA_COMPILER_ARG1 "${CMAKE_CUDA_FLAGS_ENV_INIT}" CACHE STRING "First argument to CXX compiler")
-      endif()
-      if(NOT EXISTS ${CMAKE_CUDA_COMPILER_INIT})
-        message(FATAL_ERROR "Could not find compiler set in environment variable CUDACXX:\n$ENV{CUDACXX}.\n${CMAKE_CUDA_COMPILER_INIT}")
+if(${CMAKE_GENERATOR} MATCHES "Visual Studio")
+else()
+  if(NOT CMAKE_CUDA_COMPILER)
+    set(CMAKE_CUDA_COMPILER_INIT NOTFOUND)
+
+      # prefer the environment variable CUDACXX
+      if(NOT $ENV{CUDACXX} STREQUAL "")
+        get_filename_component(CMAKE_CUDA_COMPILER_INIT $ENV{CUDACXX} PROGRAM PROGRAM_ARGS CMAKE_CUDA_FLAGS_ENV_INIT)
+        if(CMAKE_CUDA_FLAGS_ENV_INIT)
+          set(CMAKE_CUDA_COMPILER_ARG1 "${CMAKE_CUDA_FLAGS_ENV_INIT}" CACHE STRING "First argument to CXX compiler")
+        endif()
+        if(NOT EXISTS ${CMAKE_CUDA_COMPILER_INIT})
+          message(FATAL_ERROR "Could not find compiler set in environment variable CUDACXX:\n$ENV{CUDACXX}.\n${CMAKE_CUDA_COMPILER_INIT}")
+        endif()
       endif()
+
+    # finally list compilers to try
+    if(NOT CMAKE_CUDA_COMPILER_INIT)
+      set(CMAKE_CUDA_COMPILER_LIST nvcc)
     endif()
 
-  # finally list compilers to try
-  if(NOT CMAKE_CUDA_COMPILER_INIT)
-    set(CMAKE_CUDA_COMPILER_LIST nvcc)
+    _cmake_find_compiler(CUDA)
+  else()
+    _cmake_find_compiler_path(CUDA)
   endif()
 
-  _cmake_find_compiler(CUDA)
-else()
-  _cmake_find_compiler_path(CUDA)
+  mark_as_advanced(CMAKE_CUDA_COMPILER)
 endif()
 
-mark_as_advanced(CMAKE_CUDA_COMPILER)
-
 #Allow the user to specify a host compiler
 set(CMAKE_CUDA_HOST_COMPILER "" CACHE FILEPATH "Host compiler to be used by nvcc")
 if(NOT $ENV{CUDAHOSTCXX} STREQUAL "")
@@ -75,7 +79,12 @@ if(MSVC_CUDA_ARCHITECTURE_ID)
     "set(MSVC_CUDA_ARCHITECTURE_ID ${MSVC_CUDA_ARCHITECTURE_ID})")
 endif()
 
-if(CMAKE_CUDA_COMPILER_ID STREQUAL NVIDIA)
+if(${CMAKE_GENERATOR} MATCHES "Visual Studio")
+  set(CMAKE_CUDA_HOST_LINK_LAUNCHER "${CMAKE_LINKER}")
+  set(CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES "")
+  set(CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES "")
+  set(CMAKE_CUDA_HOST_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "")
+elseif(CMAKE_CUDA_COMPILER_ID STREQUAL NVIDIA)
   set(_nvcc_log "")
   string(REPLACE "\r" "" _nvcc_output_orig "${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}")
   if(_nvcc_output_orig MATCHES "#\\\$ +LIBRARIES= *([^\n]*)\n")
diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake
index 5d85186e48..6fce8e2072 100644
--- a/Modules/CMakeDetermineCompilerId.cmake
+++ b/Modules/CMakeDetermineCompilerId.cmake
@@ -241,6 +241,20 @@ Id flags: ${testflags} ${CMAKE_${lang}_COMPILER_ID_FLAGS_ALWAYS}
     set(id_Import_targets "")
     set(id_ItemDefinitionGroup_entry "")
     set(id_Link_AdditionalDependencies "")
+    if(lang STREQUAL CUDA)
+      if(NOT CMAKE_VS_PLATFORM_TOOLSET_CUDA)
+        message(FATAL_ERROR "No CUDA toolset found.")
+      endif()
+      set(cuda_tools "CUDA ${CMAKE_VS_PLATFORM_TOOLSET_CUDA}")
+      set(id_compile "CudaCompile")
+      set(id_PostBuildEvent_Command [[echo CMAKE_CUDA_COMPILER=$(CudaToolkitBinDir)\nvcc.exe]])
+      string(CONCAT id_Import_props [[<Import Project="$(VCTargetsPath)\BuildCustomizations\]] "${cuda_tools}" [[.props" />]])
+      string(CONCAT id_Import_targets [[<Import Project="$(VCTargetsPath)\BuildCustomizations\]] "${cuda_tools}" [[.targets" />]])
+      if(CMAKE_VS_PLATFORM_NAME STREQUAL x64)
+        set(id_ItemDefinitionGroup_entry "<CudaCompile><TargetMachinePlatform>64</TargetMachinePlatform></CudaCompile>")
+      endif()
+      set(id_Link_AdditionalDependencies "<AdditionalDependencies>cudart.lib</AdditionalDependencies>")
+    endif()
     configure_file(${CMAKE_ROOT}/Modules/CompilerId/VS-${v}.${ext}.in
       ${id_dir}/CompilerId${lang}.${ext} @ONLY)
     if(CMAKE_VS_MSBUILD_COMMAND AND NOT lang STREQUAL "Fortran")
-- 
GitLab