Code Yarns ‍👨‍💻
Tech BlogPersonal Blog

How to build CUDA programs using CMake

📅 2013-Sep-13 ⬩ ✍️ Ashwin Nanjappa ⬩ 📚 Archive

CMake is a popular option for cross-platform compilation of code. CMake has support for CUDA built in, so it is pretty easy to build CUDA source files using it.

Let us assume that we want to build a CUDA source file named src/hellocuda.cu. To build this using CMake, we create a file named CMakeLists.txt containing these lines:

# CMakeLists.txt to build hellocuda.cu
cmake_minimum_required(VERSION 2.8)
find_package(CUDA QUIET REQUIRED)

# Specify binary name and source file to build it from
cuda_add_executable(
    hellocuda
    src/hellocuda.cu)

To build our program on Linux, we first run cmake to generate a Makefile and use that Makefile to build and run. On Windows, cmake would generate a Visual Studio solution, that can be used to build the code.

Steps to build and run program on Linux:

$ mkdir build
$ cd build
$ cmake ..
$ cmake --build .
$ ./hellocuda

Any non-trivial CUDA program will need special compilation flags, include directories, library directories and multiple source files. The CMakeLists.txt shown below is an example of how to configure all these features:

### CMakeLists.txt for CUDA

cmake_minimum_required(VERSION 2.8)
find_package(CUDA QUIET REQUIRED)

# Pass options to NVCC
set(
    CUDA_NVCC_FLAGS
    ${CUDA_NVCC_FLAGS};
    -O3 -gencode arch=compute_22,code=sm_22
    )

# Specify include directories
include_directories(
    kernels
    utility
    )

# Specify library paths
link_directories(
    /opt/foobar/lib
    /opt/joestuff/lib
    )

# For compilation ...
# Specify target & source files to compile it from
cuda_add_executable(
    hellocuda
    hellocuda.cu
    hellocuda.h
    kernels/hellokernels.cu
    kernels/hellokernels.h
    utility/wrapper.cpp
    utility/wrapper.h
    )

# For linking ...
# Specify target & libraries to link it with
target_link_libraries(
    hellocuda
    -lfoobar
    -ljoestuff
    )

Typically nvcc calls both the host compiler and device compiler by itself on both .cu and .cpp files. The behavior of the Makefile generated by CMake is slightly different: it calls the default C++ compiler for .cpp files and calls nvcc for .cu files. This does not cause any problems, just something you might need to be aware of.

For information about other CMake commands for CUDA see the file /usr/share/cmake-2.8/Modules/FindCUDA.cmake and the files inside /usr/share/cmake-2.8/Modules/FindCUDA/.

Note: Include directories cannot be specified for a particular target using target_include_directories. This is a known limitation of the CUDA module of CMake currently. More details here.

Tried with: CMake 2.8.7, CUDA 5.0 and Ubuntu 12.04 LTS