Skip to content

Linking with a mixed CUDA/CXX library with default LINKER_LANGUAGE fails if VERSION is specified.

Using the following CMakeLists.txt

cmake_minimum_required(VERSION 3.8 FATAL_ERROR)
project(cmake_and_cuda LANGUAGES CXX CUDA)
 
SET(CMAKE_CXX_STANDARD 11)
SET(CMAKE_CUDA_STANDARD 11)
 
ADD_LIBRARY(dummy_lib SHARED dummy_cuda.cu dummy_cxx.cc)
 SET_TARGET_PROPERTIES(dummy_lib
      PROPERTIES
      VERSION "1"
      LINKER_LANGUAGE "CXX")
 
ADD_EXECUTABLE(cuda_test cuda.cu)
TARGET_LINK_LIBRARIES(cuda_test dummy_lib)
 
ADD_EXECUTABLE(cxx_test cxx.cc)
TARGET_LINK_LIBRARIES(cxx_test dummy_lib)

compiling fails with

/usr/bin/g++  CMakeFiles/cuda_test.dir/cuda.cu.o CMakeFiles/cuda_test.dir/cmake_device_link.o -o cuda_test -Wl,-rpath,/mnt/data/darndt/test_cmake_sonaming/build libdummy_lib.so.1  -L"/mnt/data/darndt/cuda-9.0/lib64/stubs" -L"/mnt/data/darndt/cuda-9.0/lib64" -lcudadevrt -lcudart_static -lrt -lpthread -ldl
CMakeFiles/cuda_test.dir/cmake_device_link.o: In function `__cudaRegisterLinkedBinary__NV_MODULE_ID':
link.stub:(.text+0x5a): undefined reference to `__fatbinwrap__NV_MODULE_ID'

using cuda-9 while it works with cuda-8 just fine. For CMake versions prior to 3.12 this works both for cuda-9 and cuda-8.

For recent CMake versions the difference between using LINKER_LANGUAGE CXX and LINKER_LANGUAGE CUDA is

/mnt/data/darndt/cuda-9.0/bin/nvcc   -Xcompiler=-fPIC -Wno-deprecated-gpu-targets -shared -dlink CMakeFiles/dummy_lib.dir/dummy_cuda.cu.o CMakeFiles/dummy_lib.dir/dummy_cxx.cc.o -o CMakeFiles/dummy_lib.dir/cmake_device_link.o  -L/mnt/data/darndt/cuda-9.0/lib64/stubs  -L/mnt/data/darndt/cuda-9.0/lib64 -lcudadevrt -lcudart_static -lrt -lpthread -ldl

/usr/bin/c++ -fPIC   -shared -Wl,-soname,libdummy_lib.so.1 -o libdummy_lib.so.1 CMakeFiles/dummy_lib.dir/dummy_cuda.cu.o CMakeFiles/dummy_lib.dir/dummy_cxx.cc.o CMakeFiles/dummy_lib.dir/cmake_device_link.o  -L/mnt/data/darndt/cuda-9.0/lib64 -lcudadevrt -lcudart_static -lrt -lpthread -ldl

vs

/mnt/data/darndt/cuda-9.0/bin/nvcc   -Xcompiler=-fPIC -Wno-deprecated-gpu-targets -shared -dlink CMakeFiles/dummy_lib.dir/dummy_cuda.cu.o CMakeFiles/dummy_lib.dir/dummy_cxx.cc.o -o CMakeFiles/dummy_lib.dir/cmake_device_link.o  -L/mnt/data/darndt/cuda-9.0/lib64/stubs

 /usr/bin/g++ -fPIC  -shared -Wl,-soname,libdummy_lib.so.1 -o libdummy_lib.so.1 CMakeFiles/dummy_lib.dir/dummy_cuda.cu.o CMakeFiles/dummy_lib.dir/dummy_cxx.cc.o CMakeFiles/dummy_lib.dir/cmake_device_link.o  -L"/mnt/data/darndt/cuda-9.0/lib64" -lcudadevrt -lcudart_static -lrt -lpthread -ldl

The essential difference to older (<3.12) CMake versions is an additional -Xnvlink libdummy_lib.so.1 in the nvcc invocation probably related to R2RT/cmake@41eab150. If VERSION is not used everything works fine as well for all combinations of CUDA Toolkit versions and CMake versions. It seems that CUDA versions 9.0+ choke on the ".1" postfix.

Is this expected behavior?

If so, it it slightly annoying to have to change LINKER LANGUAGE depending on the linked target or always specify LINKER_LANGUAGE CUDA also for CXX targets.

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information