CMake >= 3.15 Fails to compile C++ executables when CUDA is enabled and CMAKE_CUDA_SEPARABLE_COMPILATION is ON
Please consider the following project:
CMakeLists.txt:
project(SeparableCompCPPOnly LANGUAGES CXX CUDA)
set(CMAKE_CUDA_SEPARABLE_COMPILATION ON)
add_executable(helloworld main.cpp)
main.cpp:
#include <iostream>
int main() { std::cout << "Helloworld!\n"; return 0; }
With CMake 3.14, this project compiles. With CMake 3.15 and newer, compilation fails:
Scanning dependencies of target helloworld
[ 33%] Building CXX object CMakeFiles/helloworld.dir/main.cpp.o
[ 66%] Linking CUDA device code CMakeFiles/helloworld.dir/cmake_device_link.o
[100%] Linking CXX executable helloworld
/opt/RCPE/gcc/8.3.0/lib/gcc/x86_64-pc-linux-gnu/8.3.0/../../../../x86_64-pc-linux-gnu/bin/ld: CMakeFiles/helloworld.dir/cmake_device_link.o: in function `__cudaUnregisterBinaryUtil':
link.stub:(.text+0xf): undefined reference to `__cudaUnregisterFatBinary'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/helloworld.dir/build.make:103: helloworld] Fehler 1
make[1]: *** [CMakeFiles/Makefile2:76: CMakeFiles/helloworld.dir/all] Fehler 2
make: *** [Makefile:84: all] Fehler 2
It seems that CMake >= 3.15 tries to unconditionally do a device link, even if no CUDA code is involved. My guess is that either !3320 (merged) or !3491 (merged) is involved, but that is for you to decide.
In case you are wondering why I would enable the CUDA language and CMAKE_CUDA_SEPARABLE_COMPILATION if I don't even have CUDA sources:
This is just a minimal reproduction example. My real project has multiple CUDA targets and multiple C++-only targets and I had CMAKE_CUDA_SEPARABLE_COMPILATION set to on globally, to not have to set it individually on all CUDA targets (see issue #7478). This worked in 3.14 and lower, but broke in 3.15.