CMake build script for Cuda. FindCuda.cmake script available.

Hi everyone,

I’ve been using CMake (Kitware’s cross platform build system) with Cuda for quite some time now. CMake eliminates the need to modify visual studio build configuration manually to invoke nvcc.

I’ve finally posted a build script called FindCuda.cmake. This script locates Cuda/Cut and defines several macros for adding cuda executables or libraries. This version performs fully dependency checking by parsing the output of “nvcc -M” in a separate cmake script. I use WinXP with the script but it should work in linux too.

More information is available at: http://www.sci.utah.edu/~abe/FindCuda.html

Abe

Abe, thanks for your helpful contribution to the CUDA developer community.

Mark

Thanks for your code, it might come in handy.
I just posted a script for QMake here. However it is much less advanced than yours…

Abe, thanks for your scipt.

A small fix under linux / cmake 2.4.3 : replace

IF (NOT depend_text EQUAL “”)
by
IF (NOT depend_text STREQUAL “”)
and idem in the corresponding ENDIF
in the make2cmake.cmake file.

It fixes a bug in the depfile not being well generated

Stephane

Thanks for the note. This problem was fixed in r187 using a regex.

Since the original posting the script has been updated. I’ve added the ability to automatically parse -cubin generated files and output stats each kernel. This prints out the number of registers etc. on the build console. Details and changelog are on the web page above.

Abe

Hi, I’ve updated (to r537) the FindCuda.cmake script and tested it with the current version on WinXP, Linux and Mac OSX. Thanks to everyone who has provided feedback; I think the update should address most issues. See the notes in the script for usage.

Abe

see below

Hi,

I use your package successfully, thanks for your effort.

What I am trying now, is to compile *.cu files in my project, which are not located under ${CMAKE_CURRENT_SOURCE_DIR}.

The macro

MACRO(CUDA_add_custom_commands cuda_target) // Line 277

in FindCuda.cmake adds the base directory to every passed file path

SET(source_file {CMAKE_CURRENT_SOURCE_DIR}/{file}) // Line 293

which makes it impossible to access any file outside of ${CMAKE_CURRENT_SOURCE_DIR}. Has anyone an idea / workaround to this issue?

Thanks in advance.

I have made the needed modifications, but it was so long ago I don’t remember what I did :( What I have now works in linux and windows, but I remember it being tricky to get it working in both simultaneously.

I’ve attached the FindCUDA.cmake that I’ve been using. Bu it is based on an older version of the file so it doesn’t have some of the features of the latest one (like Mac support). Maybe you can merge my changes into the new version. Otherwise, I will get around to making the merge myself in a few days: I’m looking forward to adding Mac support to my application.

neo,

your file did solve the inital problem but threw up several other issues on my system. So I just took the actual version of FindCUDA.cmake and removed additional prefixes from the filenames (see attached file).

Now every *.cu file has to be passed with its absolute path in CmakeLists.txt, which seems to be a sufficient workaround for my problem.

br

As I said, my version was based on a very old version of FindCUDA.cmake which is probably why you had trouble getting it to work on your system.

What I don’t like about the quick and dirty method you did is that you have
SET(generated_target “${file}_target”)
which populates the source directory with generated files: a no-no in CMake out-of-source builds because it makes a mess.

I’ve merged my changes into the latest r537 FindCUDA.cmake from Abe’s repository. The file is attached here. I’ve tested it and it works in linux. I assume it will work in Windows still, since it is the same modification I made before.

Note: I also had to change the generated file from {stripped_file}_{cuda_target}_generated.cc to {stripped_file}_{cuda_target}_generated.c (note the extension change). With the generated file as .cc I got lots of undefined references for all of my functions in .cu files. I noticed the old version of FindCUDA.cmake I used generated a .c file so I made the change to the new one to get it to work.

By the way, I forgot to add: Thank you very much Abe, for providing FindCUDA.cmake. I’ve been using it for a year now in a very large project and it has never let me down (except for this minor little file path issue, I guess).

Thanks for sharing the cmake script! I just checked from the trunk, but currently I’m unable to compile the sample project. I would welcome any hints from anyone…

I am currently running on ubuntu 7.10 and the generate file that gives the linking error is:

/usr/bin/c++ -O3 -DNDEBUG -fPIC (test_OBJECTS) (test_EXTERNAL_OBJECTS) -o test -rdynamic -L/usr/local/cuda/lib -lcuda -lcudart -Wl,-rpath,/usr/local/cuda/lib

thanks,

Pedro

-- Configuring done

-- Generating done

-- Build files have been written to: /home/pedro/Projects/CMake-cuda/build

[  8%] Building NVCC Dependency File: /home/pedro/Projects/CMake-cuda/build/src/cuda/test_lib.cu_test_lib_generated.cc.NVCC-depend

[ 16%] Building NVCC -cubin File: /home/pedro/Projects/CMake-cuda/build/src/cuda/test_lib.cu_test_lib_generated.cc.NVCC-cubin.txt

Kernel:    _Z6kernelPjS_

Local:     0

Shared:    24

Registers: 6

[ 25%] Building NVCC /home/pedro/Projects/CMake-cuda/src/test_lib.cu: /home/pedro/Projects/CMake-cuda/build/src/cuda/test_lib.cu_test_lib_generated.cc

Scanning dependencies of target test_lib

[ 33%] Building CXX object src/CMakeFiles/test_lib.dir/cuda/test_lib.cu_test_lib_generated.o

Linking CXX static library libtest_lib.a

[ 41%] Built target test_lib

[ 50%] Building CXX object src/CMakeFiles/lib_example.dir/main.o

/home/pedro/Projects/CMake-cuda/src/main.cc:9:3: warning: no newline at end of file

Linking CXX executable lib_example

[ 50%] Built target lib_example

[ 58%] Building NVCC Dependency File: /home/pedro/Projects/CMake-cuda/build/src/cuda/test_bin.cu_test_generated.cc.NVCC-depend

[ 66%] Converting NVCC dependency to CMake (/home/pedro/Projects/CMake-cuda/build/src/cuda/test_bin.cu_test_generated.cc.depend)

[ 75%] Building NVCC -cubin File: /home/pedro/Projects/CMake-cuda/build/src/cuda/test_bin.cu_test_generated.cc.NVCC-cubin.txt

Kernel:    _Z6kernelPjS_

Local:     0

Shared:    24

Registers: 6

[ 83%] Building NVCC /home/pedro/Projects/CMake-cuda/src/test_bin.cu: /home/pedro/Projects/CMake-cuda/build/src/cuda/test_bin.cu_test_generated.cc

Scanning dependencies of target test

[ 91%] Building CXX object src/CMakeFiles/test.dir/cuda/test_bin.cu_test_generated.o

[100%] Building CXX object src/CMakeFiles/test.dir/main.o

/home/pedro/Projects/CMake-cuda/src/main.cc:9:3: warning: no newline at end of file

Linking CXX executable test

CMakeFiles/test.dir/cuda/test_bin.cu_test_generated.o: In function `__sti____cudaRegisterAll_16_test_bin_cpp1_ii_dde60ace()':

test_bin.cu_test_generated.cc:(.text+0x5ee): undefined reference to `__cudaRegisterFatBinary(void*)'

test_bin.cu_test_generated.cc:(.text+0x63b): undefined reference to `__cudaRegisterFunction(void**, char const*, char*, char const*, int, uint3*, uint3*, dim3*, dim3*)'

CMakeFiles/test.dir/cuda/test_bin.cu_test_generated.o: In function `__device_stub__Z6kernelPjS_(unsigned int*, unsigned int*)':

test_bin.cu_test_generated.cc:(.text+0x66d): undefined reference to `cudaSetupArgument(void const*, unsigned int, unsigned int)'

test_bin.cu_test_generated.cc:(.text+0x68e): undefined reference to `cudaSetupArgument(void const*, unsigned int, unsigned int)'

test_bin.cu_test_generated.cc:(.text+0x69f): undefined reference to `cudaLaunch(char const*)'

CMakeFiles/test.dir/cuda/test_bin.cu_test_generated.o: In function `__cudaUnregisterBinary()':

test_bin.cu_test_generated.cc:(.text+0x9bf): undefined reference to `__cudaUnregisterFatBinary(void**)'

CMakeFiles/test.dir/cuda/test_bin.cu_test_generated.o: In function `global destructors keyed to _Z36__sti___16_test_bin_cpp1_ii_dde60acev':

test_bin.cu_test_generated.cc:(.text+0x432f): undefined reference to `__cudaUnregisterFatBinary(void**)'

CMakeFiles/test.dir/cuda/test_bin.cu_test_generated.o: In function `global constructors keyed to _Z36__sti___16_test_bin_cpp1_ii_dde60acev':

test_bin.cu_test_generated.cc:(.text+0x45fe): undefined reference to `__cudaRegisterFatBinary(void*)'

test_bin.cu_test_generated.cc:(.text+0x464b): undefined reference to `__cudaRegisterFunction(void**, char const*, char*, char const*, int, uint3*, uint3*, dim3*, dim3*)'

collect2: ld returned 1 exit status

make[2]: *** [src/test] Error 1

make[1]: *** [src/CMakeFiles/test.dir/all] Error 2

make: *** [all] Error 2

I am having the exact same problem as you Pedro (on Fedora Core 6), did you manage to solve it ?

thanks,

Amael

I try since yesterday to fix the same problem but until now without being successful.

For me it seems that something goes wrong with libcudart.so. This lib should contain the functions which are not found by the linker but I do not know why.
Even if link by myself it does not work. Could that be an issue on x86 system which mine is?

Markus

I’m also having this problem, I’ll post an update if I get it figured out.

I am having problems to compile the example project from FindCuda.cmake.

I am using VS2005 on XP64. Can anybody help me?

The error:

1>C:\CUDA\bin/…/include\crt/host_runtime.h(57) : error C2632: ‘char’ followed by ‘bool’ is illegal
1>C:\CUDA\bin/…/include\crt/host_runtime.h(57) : warning C4091: 'typedef ’ : ignored on left of ‘char’ when no variable is declared

Any help?
Thanks a lot

I’m seeing the same problem (also using VS2005, XP64, compiling as 32bit)

Looking at host_runtime.h, the error is caused by __cplusplus not being defined. My understanding is that the compiler should automatically set this definition… but for some reason its undefined.

I tried copying the preprocessor block into another src file in my project, and it evaluated correctly. It seems like this is caused by something in the nvcc generated source.

Anyone have any ideas?

Looking at this a little more, I think I am slightly off target.

CMake uses NVCC to generate cc source from the cu files. These files are C code. The Visual Studio compiler is treating them as C++ though. If I force the compiler to treat them as C, then they compile correctly. However, now the linker reports “unresolved external symbol” for the functions in the cu files :blink:

Okay, this is my solution. I’d love to hear comments on this though.

In FindCuda.CMake, change:

Add a custom target to generate a cpp file.

SET(generated_file “{CMAKE_BINARY_DIR}/src/cuda/{file}_${cuda_target}_generated.cpp”)

to:

Add a custom target to generate a cpp file.

SET(generated_file “{CMAKE_BINARY_DIR}/src/cuda/{file}_${cuda_target}_generated.c”)

and just below the line:

SET_SOURCE_FILES_PROPERTIES(${source_file} PROPERTIES CPLUSPLUS ON)

add:

SET_SOURCE_FILES_PROPERTIES(${generated_file} PROPERTIES C ON)

This will force the NVCC generated files to compile as C under VS 2005.

My other issues were unrelated to this.