Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CMake does not properly find CUDA library

I'm trying to build a program that requires CUDA. To the CMake script I supply:

cmake -D CUDA_TOOLKIT_ROOT_DIR=/usr/local/cuda ..

CUDA is found and CMake runs normally:

staudt ~/workspace/clutbb/cluster/build $ cmake -D CUDA_TOOLKIT_ROOT_DIR=/usr/local/cuda ..                                                                                  
-- Found CUDA: /usr/local/cuda (found version "6.5") 
-- Found Intel TBB
-- Boost version: 1.56.0
-- Found the following Boost libraries:
--   iostreams
--   program_options
-- Looking for include file pthread.h
-- Looking for include file pthread.h - found
-- Looking for pthread_create
-- Looking for pthread_create - not found
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE  
-- Could NOT find SDL (missing:  SDL_LIBRARY SDL_INCLUDE_DIR) 
-- Configuring done
-- Generating done
-- Build files have been written to: /home/i11/staudt/workspace/clutbb/cluster/build

But then the linker step fails:

staudt ~/workspace/clutbb/cluster/build $ make
[ 69%] Built target cluster
Linking CXX executable clu
CMakeFiles/clu.dir/clu.cpp.o: In function `initCUDA(int&, CUctx_st*&, int const&)':
clu.cpp:(.text+0x517): undefined reference to `cuInit'
clu.cpp:(.text+0x52b): undefined reference to `cuDeviceGet'
clu.cpp:(.text+0x53f): undefined reference to `cuCtxCreate_v2'
clu.cpp:(.text+0x559): undefined reference to `cuDeviceGetName'
clu.cpp:(.text+0x55e): undefined reference to `cuCtxSynchronize'
CMakeFiles/clu.dir/clu.cpp.o: In function `exitCUDA(int&, CUctx_st*&)':
clu.cpp:(.text+0x684): undefined reference to `cuCtxDestroy_v2'
CMakeFiles/clu.dir/clu.cpp.o: In function `main':
clu.cpp:(.text.startup+0x1092): undefined reference to `cuCtxDestroy_v2'
clu.cpp:(.text.startup+0x10d1): undefined reference to `cuCtxSynchronize'
clu.cpp:(.text.startup+0x10e1): undefined reference to `cuCtxSynchronize'
collect2: error: ld returned 1 exit status
make[2]: *** [bin/clu] Fehler 1
make[1]: *** [bin/CMakeFiles/clu.dir/all] Fehler 2
make: *** [all] Fehler 2

The required library is at /usr/local/cuda/lib64/stubs/libcuda.so, but how can I point that out to cmake or make?

like image 385
clstaudt Avatar asked Nov 19 '14 13:11

clstaudt


2 Answers

In the archive you have now posted, there are multiple project hierarchies. The actual error you have posted in the question is occurring during compile and linking of the clu project based on clu.cpp in the clutbb/cluster/bin directory.

In this same directory, there is a CMakeLists.txt file. This file governs this particular level of the project hierarchy.

In this particular CMakeLists.txt file, there is the following section:

cuda_add_executable(clu clu.cpp)
target_link_libraries(clu ${CUDA_LIBRARY} ${TBB_LIBRARY} ${Boost_LIBRARIES} rt)
target_link_libraries(clu cluster)

Try modifying the middle line above to:

target_link_libraries(clu ${CUDA_LIBRARY} ${TBB_LIBRARY} ${Boost_LIBRARIES} rt cuda)

This should fix the missing -lcuda in the linker command line. It may still be necessary to give it the path to libcuda.so on your machine, but it may not be necessary, depending on how your machine environment is set up.

like image 68
Robert Crovella Avatar answered Sep 19 '22 10:09

Robert Crovella


The correct way of doing this on CMake 3.17+ is to use the FindCUDAToolkit module, like so:

find_package(CUDAToolkit REQUIRED)
target_link_libraries(my_target PRIVATE CUDA::cudart CUDA::cuda_driver)

The CUDA::cuda_driver target is equivalent to -lcuda when the linker would find it, and is otherwise an absolute path to the correct library. You should avoid adding system libraries via target_link_libraries to ensure portability.


If you have an older version (CMake 3.0+), you can use the (now-deprecated) FindCUDA module to imitate the 3.17 module, like so:

find_package(CUDA REQUIRED)

# Do what the new package does
find_library(CUDA_DRIVER_LIBRARY
             NAMES cuda_driver cuda
             HINTS ${CUDA_TOOLKIT_ROOT_DIR}
                   ENV CUDA_PATH
             PATH_SUFFIXES nvidia/current lib64 lib/x64 lib)
if (NOT CUDA_DRIVER_LIBRARY)
    # Don't try any stub directories until we have exhausted all other search locations.
    find_library(CUDA_DRIVER_LIBRARY
                 NAMES cuda_driver cuda
                 HINTS ${CUDA_TOOLKIT_ROOT_DIR}
                       ENV CUDA_PATH
                 PATH_SUFFIXES lib64/stubs lib/x64/stubs lib/stubs stubs)
endif ()
mark_as_advanced(CUDA_DRIVER_LIBRARY)
##

target_include_directories(my_target PRIVATE ${CUDA_INCLUDE_DIRS})
target_link_libraries(my_target PRIVATE ${CUDA_LIBRARIES} ${CUDA_DRIVER_LIBRARY})

This is adapted from the official sources, here.

like image 24
Alex Reinking Avatar answered Sep 22 '22 10:09

Alex Reinking