CMake project directory structure


Nested / recursive CMake

It’s a good idea to breakup project code into distinct subdirectories. It can be useful to have a CMakeLists.txt for each of these directories, that are included from the top-level CMakeLists.txt.

Let’s say you have C code in a main directory, with a subdirectory io/.

Top-level CMakeLists.txt:

cmake_minimum_required(VERSION 3.3)
project(benchmarks C)


add_executable(benchIO bench.c)
target_link_libraries(benchIO iohdf)

and then you have in io/CMakeLists.txt:

cmake_minimum_required(VERSION 3.10) # 3.10 required for HDF5 1.10
project(io C)

add_library(iohdf ...)

add_executable(testh5 testh5.c)
target_link_libraries(testh5 iohdf)


add_test(NAME h5io COMMAND testh5)

You can then build a little test script in io/ directory to test just HDF5 I/O, and compile the whole program from the top level directory, and use a single

make test

from the top-level directory to test the main program and subdirectory libraries.

Cmake Directory variables

To reliably control relative path operations, use

  • ${PROJECT_SOURCE_DIR} to refer to individual subdirectories where the various CMakeLists.txt are
  • ${CMAKE_SOURCE_DIR} to refer to the highest level CMakeLists.txt directory

Edit all CMakeLists.txt recursively

On Linux/Unix systems, I edit all CMakeLists.txt in a project with a command like

gedit $(find -name CMakeLists.txt)