CMake does not find CUDA if not in $PATH if CUDA is a project LANGUAGE

Dear all,

I am pretty confused: since 3.10 CUDA is a first class language and one need not to use find_package(CUDA) nor find_package(CUDAToolkit).

A minimal setup you can find at https://github.com/paskino/cmake-cuda
My CMakeLists.txt is:

make_minimum_required(VERSION 3.10 FATAL_ERROR)

# THIS IS DEFAULT AND FAILS
project(prova LANGUAGES CUDA)
add_executable(jacobi ${CMAKE_CURRENT_SOURCE_DIR}/example.cu)

However, I recently stumbled upon the problem that because nvcc was not found in the $PATH, cmake would fail as

-- The CUDA compiler identification is unknown
CMake Error at CMakeLists.txt:2 (project):
  No CMAKE_CUDA_COMPILER could be found.

Solution to this is to add the path to nvcc to $PATH or to specify the environment variable CUDACXX or pass -DCMAKE_CUDA_COMPILER.

If I change my CMakeLists.txt to use the deprecated method CMake finds nvcc and compiles correctly.

# THIS IS DEPRECATED AND WORKS PERFECTLY
# project(prova LANGUAGES CXX)
# find_package(CUDA REQUIRED)
#  CUDA_ADD_EXECUTABLE(jacobi ${CMAKE_CURRENT_SOURCE_DIR}/example.cu)

So in conclusion, if I use the deprecated method CMake works as expected: is able to find a suitable nvcc compiler, while the more modern approach is not able to find nvcc and I have to provide it manually, which I find bizzarre. Probably I’m missing something…

I tried this on a variety of systems, windows and linux with CMake 3.17 or 3.18.

Thanks

Edoardo

I don’t think CMake supports finding just the CUDA language. I think one needs C and/or C++ in order to get the system linker information going. @robert.maynard is that true?

You mean changing the LANGUAGES line to the following?

project(prova LANGUAGES C CXX CUDA)

Unfortunately it doesn’t help:

cmake ..

-- The C compiler identification is GNU 7.5.0
-- The CXX compiler identification is GNU 7.5.0
-- The CUDA compiler identification is unknown

Edoardo

The modern approach means that the CUDA language follows CMake default behavior for finding a compiler. This approach searches the system env PATH or the CUDACXX env variable.
Since compiler detection is done as part of platform detection, CMake can’t use find_ calls during this step, meaning we don’t know about or able to search places such as /usr/local/cuda/ or can we safely presume nvcc is the desired CUDA compiler ( we support clang as well ).

CMake fully supports CUDA being the only enabled language.

Ah, that’s good to hear.

@robert.maynard are you saying that CMake won’t be able to find the nvcc compiler if it sits in a default location but it’s not in the PATH?

I don’t think this is satisfactory. The CUDA Toolkit is not often part of the OS, so it’s binaries may well not be in the PATH.

I suppose there is nothing like a free lunch: with the old method it is more difficult to create targets for CUDA, while with the modern approach it’s easy to create targets but more difficult to find the compiler even if it’s in “standard” locations.

Thanks

Edoardo