CMake failes to configure with clang as cuda compiler -> CMakeDetermineCompilerABI failure
If I want to configure a simple CUDA project with Clang as CUDA compiler I get the following error:
$ cmake .. -DCMAKE_CUDA_COMPILER=clang++ -DCMAKE_CUDA_ARCHITECTURES=70
-- The CUDA compiler identification is unknown
-- Detecting CUDA compiler ABI info
CMake Error: Error required internal CMake variable not set, cmake may not be built correctly.
Missing variable is:
_CMAKE_CUDA_WHOLE_FLAG
CMake Error at /opt/spack-modules/opt/spack/linux-ubuntu22.04-zen2/gcc-11.3.0/cmake-3.29.1-jkdn5x5hfq4dow5g6hlycuo23mj5zj3o/share/cmake-3.29/Modules/CMakeDetermineCompilerABI.cmake:64 (try_compile):
Failed to generate test project build system.
Call Stack (most recent call first):
/opt/spack-modules/opt/spack/linux-ubuntu22.04-zen2/gcc-11.3.0/cmake-3.29.1-jkdn5x5hfq4dow5g6hlycuo23mj5zj3o/share/cmake-3.29/Modules/CMakeTestCUDACompiler.cmake:19 (CMAKE_DETERMINE_COMPILER_ABI)
CMakeLists.txt:3 (project)
-- Configuring incomplete, errors occurred!
I use the following CMakeLists.txt
:
cmake_minimum_required(VERSION 3.29)
project(cmake_clang_cuda_reproducer LANGUAGES CUDA)
add_executable(${CMAKE_PROJECT_NAME})
target_sources(${CMAKE_PROJECT_NAME}
PRIVATE
main.cu
)
and this is the main.cu
:
int main(int argc, char **argv){
return 0;
}
My used software is:
- CMake 3.29.1
- Clang 18.1.1
- CUDA 12.0.1
If found the following workaround which is working: https://discourse.cmake.org/t/cmake-cuda-clang-fails/8657/10 .
Therefore if I configure the project with following parameters everything is fine: cmake .. -DCMAKE_CUDA_COMPILER=clang++ -DCMAKE_CUDA_ARCHITECTURES=70 -DCMAKE_CUDA_FLAGS="-std=c++98"
By the way, cmake .. -DCMAKE_CUDA_COMPILER=clang++ -DCMAKE_CUDA_FLAGS="-std=c++98"
is also working. Therefore defining the CUDA architecture is not necessary anymore.
A "permanent" workaround in my CMakeLists.txt looks like this:
cmake_minimum_required(VERSION 3.29)
project(foo)
if("${CMAKE_CUDA_COMPILER}" MATCHES "clang*")
message(STATUS "use clang as CUDA compiler")
# Because of a bug, we need to set the C++ standard manually for clang
# as cuda compiler. Otherwise the check if clang can compile some
# example code fails.
# Because of another bug, we cannot reuse the C++ standard later via
# CUDA_STANDARD. But nobody should use C++98 ;-)
set(_CMAKE_CUDA_FLAGS_BEFORE ${CMAKE_CUDA_FLAGS})
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -std=c++98")
enable_language(CUDA)
set(CMAKE_CUDA_FLAGS ${_CMAKE_CUDA_FLAGS_BEFORE})
unset(_CMAKE_CUDA_FLAGS_BEFORE)
else()
message(STATUS "use nvcc as CUDA compiler")
enable_language(CUDA)
endif()
add_executable(${CMAKE_PROJECT_NAME})
target_sources(${CMAKE_PROJECT_NAME}
PRIVATE
main.cu
)
set_target_properties(${CMAKE_PROJECT_NAME} PROPERTIES
CUDA_STANDARD 17
CUDA_EXTENSIONS OFF
)
Another bug, which could be related to this is that if I set "${CMAKE_CUDA_FLAGS} -std=c++17"
and remove the argument afterwards from the CMAKE_CUDA_FLAGS
, set_target_properties(${CMAKE_PROJECT_NAME} PROPERTIES CUDA_STANDARD 17)
is not working anymore. CMake will not set -std=c++17
or -std=gnu17
in the compiler command anymore. Other standards like 11 or 20 are working. It really depends which standard I set via CMAKE_CUDA_FLAGS
. Therefore I used C++98 ;-) Because the bug appears in my workaround I didn't open a second issue. If you wish, I can do it.