Problem with CMake when compiling a project with Clang and CUDA support

Hello,

I’m trying to build an open-source project called VORTEX on Windows using CLANG as the compiler. However, when I run the CMake command, it seems that the NVCC (CUDA) compiler is not being detected. Could you please assist me in resolving this issue? I’m not sure if there is a bug in CMake.

Thank you for your help.

cmake -S vortex -B vortex/build -T ClangCL -DPython3_EXECUTABLE:FILEPATH="C:/Users/audia/AppData/Local/Programs/Python/Python311/python.exe" -DCMAKE_TOOLCHAIN_FILE:FILEPATH="C:/Users/audia/freelance/vortex/build/vcpkg/scripts/buildsystems/vcpkg.cmake" -DENABLE_BUILD_PYTHON_WHEEL:BOOL=ON -DENABLE_INSTALL_PYTHON_WHEEL:BOOL=ON -DENABLE_OUT_OF_TREE_PACKAGING:BOOL=OFF -DWITH_CUDA:BOOL=ON -DCMAKE_CUDA_COMPILER:FILEPATH="C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v11.6/bin/nvcc.exe" -DWITH_DAQMX:BOOL=OFF -DWITH_ALAZAR:BOOL=OFF -DCUDA_TOOLKIT_ROOT_DIR="C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v11.6"

-- Building for: Visual Studio 16 2019
-- Selecting Windows SDK version 10.0.19041.0 to target Windows 10.0.22631.
-- The C compiler identification is Clang 12.0.0 with MSVC-like command-line
-- The CXX compiler identification is Clang 12.0.0 with MSVC-like command-line
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/Llvm/x64/bin/clang-cl.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/Llvm/x64/bin/clang-cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
CMake Error at C:/Program Files/CMake/share/cmake-3.30/Modules/CMakeDetermineCompilerId.cmake:838 (message):
  Compiling the CUDA compiler identification source file
  "CMakeCUDACompilerId.cu" failed.

  Compiler: C:/Program Files/NVIDIA GPU Computing
  Toolkit/CUDA/v11.8/bin/nvcc.exe

  Build flags:

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



  The output was:
  1
  Microsoft (R) Build Engine version 16.11.2+f32259642 for .NET Framework
  Copyright (C) Microsoft Corporation.  All rights reserved.
  Build started 19/09/2024 2:43:21 PM.
  Project
  "C:\Users\audia\freelance\vortex\build\CMakeFiles\3.30.3\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.

  C:\Program Files (x86)\Microsoft Visual
  Studio\2019\Community\MSBuild\Microsoft\VC\v160\BuildCustomizations\CUDA
  11.8.targets(278,17): error MSB4023: Cannot evaluate the item metadata
  "%()".  Parameter "metadataName" cannot have zero length.
  [C:\Users\audia\freelance\vortex\build\CMakeFiles\3.30.3\CompilerIdCUDA\CompilerIdCUDA.vcxproj]

  Done Building Project
  "C:\Users\audia\freelance\vortex\build\CMakeFiles\3.30.3\CompilerIdCUDA\CompilerIdCUDA.vcxproj"
  (default targets) -- FAILED.

Im using Visual studio 2017 (16.11.40) and CUDA 11.6 and my CmakeLists.txt is

cmake_minimum_required(VERSION 3.17.0)

project(vortex)

set (CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS true)

set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")

set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install")

set(CMAKE_DEBUG_POSTFIX "d")

set(CMAKE_VERBOSE_MAKEFILE ON)

list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")

set(CMAKE_CXX_STANDARD 20 CACHE STRING "")
set(CMAKE_CXX_STANDARD_REQUIRED ON CACHE STRING "")
set(CMAKE_CXX_EXTENSIONS OFF CACHE STRING "")

option(WITH_CUDA "Build features dependent on CUDA" on)
option(WITH_ALAZAR "Build features dependent on Alazar ATS-SDK" on)
option(WITH_ALAZAR_GPU "Build features dependent on Alazar ATS-GPU" off)
option(WITH_DAQMX "Build features dependent on DAQmx" on)
option(WITH_IMAQ "Build features dependent on IMAQ" off)
option(WITH_REFLEXXES "Build features dependent on Reflexxes" on)
option(WITH_FFTW "Build features dependent on FFTW" off)
option(WITH_HDF5 "Build features dependent on HDF5" on)
option(WITH_PYTHON "Build Python bindings" on)

if (WITH_CUDA)
    enable_language(CUDA)
    set(CMAKE_CUDA_ARCHITECTURES 86)
endif()

option(ENABLE_BUILD_PYTHON_WHEEL "Build Python wheel for installation" on)
option(ENABLE_INSTALL_PYTHON_WHEEL "Install Python wheel after build" on)
option(ENABLE_DEPENDENCY_PACKAGING "Include binary dependencies in Python wheel" on)
option(ENABLE_OUT_OF_TREE_PACKAGING "Include binary dependencies from outside the build tree in Python wheel" on)

option(ENABLE_CUDA_KERNEL_SERIALIZATION "Synchronize the CUDA device after every kernel launch (turn on for debugging)" off)
option(ENABLE_EXCEPTION_GUARDS "Handle exceptions (turn off for debugging)" on)
option(ENABLE_MODULAR_BUILD "Build hardware modules in seperate libraries" ${ENABLE_BUILD_PYTHON_WHEEL})
option(ENABLE_DEMOS "Build demos" off)


# windows version detection
# ref: https://stackoverflow.com/questions/9742003/platform-detection-in-cmake
if (WIN32)
    macro(get_WIN32_WINNT version)
        if (CMAKE_SYSTEM_VERSION)
            set(ver ${CMAKE_SYSTEM_VERSION})
            string(REGEX MATCH "^([0-9]+).([0-9])" ver ${ver})
            string(REGEX MATCH "^([0-9]+)" verMajor ${ver})
            # Check for Windows 10, b/c we'll need to convert to hex 'A'.
            if ("${verMajor}" MATCHES "10")
                set(verMajor "A")
                string(REGEX REPLACE "^([0-9]+)" ${verMajor} ver ${ver})
            endif ("${verMajor}" MATCHES "10")
            # Remove all remaining '.' characters.
            string(REPLACE "." "" ver ${ver})
            # Prepend each digit with a zero.
            string(REGEX REPLACE "([0-9A-Z])" "0\\1" ver ${ver})
            set(${version} "0x${ver}")
        endif(CMAKE_SYSTEM_VERSION)
    endmacro(get_WIN32_WINNT)

    get_WIN32_WINNT(ver)
    add_definitions(-D_WIN32_WINNT=${ver})
endif(WIN32)

# Vortex version detection
if(NOT VORTEX_VERSION_STRING)
    find_package(Git QUIET)
    if(Git_FOUND AND EXISTS "${CMAKE_SOURCE_DIR}/.git/index")
        execute_process(
            COMMAND "${GIT_EXECUTABLE}" describe --tags --always HEAD
            WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
            RESULT_VARIABLE IGNORE
            OUTPUT_VARIABLE OUT
            ERROR_QUIET
            OUTPUT_STRIP_TRAILING_WHITESPACE
        )

        set_property(GLOBAL APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${CMAKE_SOURCE_DIR}/.git/index")

        string(REGEX MATCH "v?([0-9]+\\.[0-9]+\\.[0-9]+)-?([0-9]*)-?([0-9a-z]*)" "\\1+\\2" IGNORE ${OUT})
        set(VORTEX_VERSION_STRING "${CMAKE_MATCH_1}")
        if(CMAKE_MATCH_2)
            string(APPEND VORTEX_VERSION_STRING "+${CMAKE_MATCH_2}.${CMAKE_MATCH_3}")
        endif()
    endif()
endif()
if(NOT VORTEX_VERSION_STRING)
    set(VORTEX_VERSION_STRING "0.0.0")
    message(WARNING "Unable to detect Vortex version so using ${VORTEX_VERSION} -> Define VORTEX_VERSION=XX.YY.ZZ for CMake")
endif()
message(STATUS "Detected Vortex v${VORTEX_VERSION_STRING}")

string(REGEX MATCH "^([0-9]+)\\.([0-9]+)\\.([0-9]+)" IGNORE ${VORTEX_VERSION_STRING})
set(VORTEX_VERSION_MAJOR ${CMAKE_MATCH_1})
set(VORTEX_VERSION_MINOR ${CMAKE_MATCH_2})
set(VORTEX_VERSION_PATCH ${CMAKE_MATCH_3})
math(EXPR VORTEX_VERSION "${CMAKE_MATCH_1} * 10000 + ${CMAKE_MATCH_2} * 100 + ${CMAKE_MATCH_3}")

# wrap compiler flags to pass through to NVCC
function(cuda_convert_flags EXISTING_TARGET)
    if(NOT ${CMAKE_CUDA_COMPILER_ID} STREQUAL "Clang")
        get_property(old_flags TARGET ${EXISTING_TARGET} PROPERTY INTERFACE_COMPILE_OPTIONS)
        if(NOT "${old_flags}" STREQUAL "")
            string(REPLACE ";" "," CUDA_flags "${old_flags}")
            set_property(TARGET ${EXISTING_TARGET} PROPERTY INTERFACE_COMPILE_OPTIONS
                "$<$<BUILD_INTERFACE:$<COMPILE_LANGUAGE:CXX>>:${old_flags}>$<$<BUILD_INTERFACE:$<COMPILE_LANGUAGE:CUDA>>:-Xcompiler=${CUDA_flags}>"
                )
        endif()
    endif()
endfunction()

set_property(GLOBAL PROPERTY USE_FOLDERS ON)
set_property(GLOBAL PROPERTY AUTOGEN_TARGETS_FOLDER AutoGen)

add_subdirectory(src)
if(ENABLE_DEMOS)
    add_subdirectory(demo)
endif()

# generate package files
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
    VortexVersion.cmake
    VERSION "${VORTEX_VERSION}"
    COMPATIBILITY AnyNewerVersion
)

configure_package_config_file(
    VortexConfig.cmake.in VortexConfig.cmake
    INSTALL_DESTINATION lib/cmake/vortex
)

configure_file(doc/Doxyfile.in ${PROJECT_BINARY_DIR}/doc/_doxygen/Doxyfile @ONLY)
configure_file(doc/conf.py.in ${PROJECT_BINARY_DIR}/doc/_sphinx/conf.py @ONLY)

install(
    FILES "${CMAKE_CURRENT_BINARY_DIR}/VortexConfig.cmake"
          "${CMAKE_CURRENT_BINARY_DIR}/VortexVersion.cmake"
    DESTINATION lib/cmake/vortex
)

install(
    EXPORT VortexTargets
    FILE VortexTargets.cmake
    NAMESPACE vortex::
    DESTINATION lib/cmake/vortex
)