CMake selects Visual Studio CL compiler for CUDA, despite finding nvcc?

This issue is bizarre and I have no idea why it’s happening. I’m trying to compile ArrayFire from source, using vcpkg to find all the dependencies. I’ve installed all the required dependencies, and have a CUDA toolkit with visual studio integration.

From the output below, you can see that it correctly identifies the compiler as nvcc.exe

CMake Error at C:/Program Files/CMake/share/cmake-3.25/Modules/CMakeDetermineCompilerId.cmake:739 (message):
  Compiling the CUDA compiler identification source file
  "CMakeCUDACompilerId.cu" failed.

Compiler: C:/Program Files/NVIDIA GPU Computing
  Toolkit/CUDA/v12.3/bin/nvcc.exe

Build flags:

Id flags: --keep;--keep-dir;tmp -v

But then later it uses the Microsoft c++ compiler for some reason.

  Microsoft (R) Build Engine version 16.11.2+f32259642 for .NET Framework

  Copyright (C) Microsoft Corporation.  All rights reserved.



  Build started 11/1/2023 11:19:11 AM.

  Project
  "C:\Users\kivik\Desktop\project\external\arrayfire\build\CMakeFiles\3.25.2\CompilerIdCUDA\CompilerIdCUDA.vcxproj"
  on node 1 (default targets).

  PrepareForBuild:

    Creating directory "Debug\".
    Creating directory "Debug\CompilerIdCUDA.tlog\".

  InitializeBuildStatus:

    Creating "Debug\CompilerIdCUDA.tlog\unsuccessfulbuild" because "AlwaysCreate" was specified.

  VcpkgTripletSelection:

    Using triplet "x64-windows" from "C:\vcpkg\installed\x64-windows\"
    Using normalized configuration "Release"

  VcpkgCheckManifestRoot:

    The vcpkg manifest was disabled, but we found a manifest file in C:\Users\kivik\Desktop\project\external\arrayfire\. You may want to enable vcpkg manifests in your properties page or pass /p:VcpkgEnableManifest=true to the msbuild invocation.

  ClCompile:

    C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.29.30133\bin\HostX64\x64\CL.exe /c /I"C:\vcpkg\installed\x64-windows\include" /nologo /W0 /WX- /diagnostics:column /Od /D _MBCS /Gm- /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Zc:inline /Fo"Debug\\" /Fd"Debug\vc142.pdb" /external:W0 /Gd /TP /FC /errorReport:queue CMakeCUDACompilerId.cu
    CMakeCUDACompilerId.cu


  C:\Users\kivik\Desktop\project\external\arrayfire\build\CMakeFiles\3.25.2\CompilerIdCUDA\CMakeCUDACompilerId.cu(2,1):
  fatal error C1189: #error: "A C or C++ compiler has been selected for CUDA"
  [C:\Users\kivik\Desktop\project\external\arrayfire\build\CMakeFiles\3.25.2\CompilerIdCUDA\CompilerIdCUDA.vcxproj]


  Done Building Project
  "C:\Users\kivik\Desktop\project\external\arrayfire\build\CMakeFiles\3.25.2\CompilerIdCUDA\CompilerIdCUDA.vcxproj"
  (default targets) -- FAILED.

I’ve set the tool chain as expected in my user presets file:
"CMAKE_TOOLCHAIN_FILE": "C:/vcpkg/scripts/buildsystems/vcpkg.cmake"

I’ve tried setting several different variables, one after another (not all at the same time) for CUDA:

"CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR": "C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v12.3"
"CMAKE_VS_PLATFORM_TOOLSET_CUDA_DIR": "C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v12.3"
"CUDA": "C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v12.3"
"CMAKE_CUDA_COMPILER": "C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v12.3/bin/nvcc.exe"

But I don’t think that is the issue here, because it is finding the CUDA compiler. I think there’s something else going on, I just don’t know what. I’m not building it in the Visual Studio IDE, I’m trying to configure it using powershell and CMake.

My cmake version is 3.25.2.
CUDA is 12.3.
Visual Studio Community 2022, 17.7.6
Visual Studio Build Tools 2019, 16.11.31
Windows 10 Pro, 10.0.19045 Build 19045
Windows SDK version 10.0.22621

Other important CMake preset configuration values:

     "generator": "Visual Studio 16 2019",
     "architecture": "x64"

CMakeSystem.cmake generated in build/CMakeFiles/3.25.2 contains:

set(CMAKE_HOST_SYSTEM "Windows-10.0.19045")
set(CMAKE_HOST_SYSTEM_NAME "Windows")
set(CMAKE_HOST_SYSTEM_VERSION "10.0.19045")
set(CMAKE_HOST_SYSTEM_PROCESSOR "AMD64")

include("C:/vcpkg/scripts/buildsystems/vcpkg.cmake")

set(CMAKE_SYSTEM "Windows-10.0.19045")
set(CMAKE_SYSTEM_NAME "Windows")
set(CMAKE_SYSTEM_VERSION "10.0.19045")
set(CMAKE_SYSTEM_PROCESSOR "AMD64")

set(CMAKE_CROSSCOMPILING "FALSE")

set(CMAKE_SYSTEM_LOADED 1)

VCTargetsPath.txt contains:
C:/Program Files (x86)/Microsoft Visual Studio/2019/BuildTools/MSBuild/Microsoft/VC/v160

The lib directory in my CUDA toolkit has a x64 subdirectory, so it should be x64 compatible.

In the CMakeFiles, the CompilerIdCUDA.vcxproj file contains:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup Label="ProjectConfigurations">
    <ProjectConfiguration Include="Debug|x64">
      <Configuration>Debug</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
  </ItemGroup>
  <PropertyGroup Label="Globals">
    <ProjectGuid>{CAE07175-D007-4FC3-BFE8-47B392814159}</ProjectGuid>
    <RootNamespace>CompilerIdCUDA</RootNamespace>
    <Keyword>Win32Proj</Keyword>
    
    
    <WindowsTargetPlatformVersion>10.0.22621.0</WindowsTargetPlatformVersion>
    
    
    
    
  </PropertyGroup>
  
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
  <PropertyGroup>
    <PreferredToolArchitecture>x64</PreferredToolArchitecture>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
    <ConfigurationType>Application</ConfigurationType>
    <PlatformToolset>v142</PlatformToolset>
    <CharacterSet>MultiByte</CharacterSet>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
  <ImportGroup Label="ExtensionSettings">
    
  </ImportGroup>
  <PropertyGroup>
    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\</OutDir>
    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\</IntDir>
    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkIncremental>
  </PropertyGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <ClCompile>
      <Optimization>Disabled</Optimization>
      <PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <MinimalRebuild>false</MinimalRebuild>
      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
      <PrecompiledHeader>
      </PrecompiledHeader>
      <WarningLevel>TurnOffAllWarnings</WarningLevel>
      <DebugInformationFormat>
      </DebugInformationFormat>
    </ClCompile>
    
    <Link>
      <GenerateDebugInformation>false</GenerateDebugInformation>
      <SubSystem>Console</SubSystem>
      
    </Link>
    <PostBuildEvent>
      <Command>for %%i in (cl.exe) do %40echo CMAKE_CUDA_COMPILER=%%~$PATH:i</Command>
    </PostBuildEvent>
  </ItemDefinitionGroup>
  <ItemGroup>
    <ClCompile Include="CMakeCUDACompilerId.cu" />
  </ItemGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
  <ImportGroup Label="ExtensionTargets">
    
  </ImportGroup>
</Project>

If someone can make sense of this, I’d really appreciate it.

Well, switching to Visual Studio 17 2022 as the generator appears to work. No idea why the older generator didn’t, it’s supposed to be supported.

Any thoughts @robert.maynard?