CUDA CMake Project

Published:
1 minute read

Modern CMake is straightforward to use, but it was not easy to find a good example of a project that builds CUDA. This post is a simple example of a CMake project that uses CUDA.

If you want more information about CMake, read this.

CMakeLists.txt

cmake_minimum_required(VERSION 3.20 FATAL_ERROR)
include(CheckLanguage)

project(
  "CMakeCUDA"
  VERSION "0.1.0"
  LANGUAGES CXX CUDA)

add_custom_target("${PROJECT_NAME}")

# Check for CUDA
check_language(CUDA)

# Check if CUDA is found
if(CMAKE_CUDA_COMPILER)
  enable_language(CUDA)
  message(STATUS "Found CUDA: ${CMAKE_CUDA_COMPILER}")
  message(STATUS "CUDA Version: ${CMAKE_CUDA_COMPILER_VERSION}")
  message(STATUS "CUDA Include dirs: ${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES}")
  message(STATUS "CUDA Library dirs: ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES}")

  include_directories("${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES}")
  link_directories("${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES}")

  set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -Xcompiler -Wall")
  set(CMAKE_CUDA_HOST_COMPILER "${CMAKE_CUDA_COMPILER}")
  set(CMAKE_CUDA_STANDARD 17)
  set(CMAKE_CUDA_STANDARD_REQUIRED ON)
  set(CMAKE_CUDA_ARCHITECTURES "70;75;80;86")
else()
  message(FATAL_ERROR "CUDA not found.")
endif()

# Set the source directory
set(SOURCE_DIR "${PROJECT_SOURCE_DIR}/src")

# If you want build the targets seperately:

function(add_target TARGET_NAME)
  # Add the target
  add_dependencies("${PROJECT_NAME}" "${TARGET_NAME}")
  add_executable("${TARGET_NAME}" "${SOURCE_DIR}/${TARGET_NAME}.cu")
  target_link_libraries(${TARGET_NAME} PRIVATE cuda cudart)
  message(STATUS "Added target: ${TARGET_NAME}")
endfunction()

add_target("main")

Then you can build the project with:


# Create a build directory
mkdir build
cd build

# Configure
cmake ..

# Build
make -j8

And the main source can be as simple as this:

// main.cu
#include <iostream>

__global__ void hello() {
  printf("Hello World from GPU!\n");
}

int main() {
  std::cout << "Hello World from CPU!" << std::endl;

  hello<<<1, 1>>>();
  cudaDeviceSynchronize();

  return 0;
}