Site Tools


wiki:cmake-subdirectories

Table of Contents

CMake Subdirectories

add_subdirectory(subdir) includes another CMakeLists.txt from a subdirectory, creating a new scope for variables. Targets declared in subdirectories are visible in the parent, but variables are not (unless explicitly propagated with PARENT_SCOPE).

Basic usage:

# Top-level CMakeLists.txt
project(MyApp)
 
add_subdirectory(src)
add_subdirectory(tests)
 
# src/CMakeLists.txt
add_library(mylib lib.cpp)
 
# tests/CMakeLists.txt
add_executable(test_app test.cpp)
target_link_libraries(test_app PRIVATE mylib)

Typical project structure:

CMakeLists.txt       # main build configuration
src/
  CMakeLists.txt     # declares mylib target
  lib.cpp
tests/
  CMakeLists.txt     # declares test_app target
  test.cpp
include/
  mylib.h

Variable scope:

# Top-level
set(VERSION 1.0)
 
add_subdirectory(src)
message("In parent: ${LOCAL_VAR}")  # undefined (declared in src/CMakeLists.txt)
 
# src/CMakeLists.txt
set(LOCAL_VAR "value")             # local: doesn't escape
 
# To propagate a variable up:
set(RESULT 42 PARENT_SCOPE)

Targets are always visible to the parent (unlike variables):

# src/CMakeLists.txt
add_library(mylib lib.cpp)
 
# tests/CMakeLists.txt
target_link_libraries(test_app PRIVATE mylib)  # works!

Nested subdirectories:

# CMakeLists.txt
add_subdirectory(lib)
 
# lib/CMakeLists.txt
add_subdirectory(core)
add_subdirectory(utils)
 
# lib/core/CMakeLists.txt
add_library(core_lib core.cpp)

Conditional subdirectories:

if(BUILD_TESTS)
  add_subdirectory(tests)
endif()

Build with:

cmake -DBUILD_TESTS=ON ..

Organizing large projects:

  • Top-level — project setup, version, find packages, subdirs
  • src/ — main library/executable targets
  • tests/ — test targets (optional, enable via flag)
  • tools/ — utility programs
  • examples/ — example code

Each subdirectory is self-contained: it declares its own targets, sets its own compiler options, manages its own dependencies. The parent orchestrates which subdirectories to build.

Subdirectories prevent variable pollution and make projects modular. Use them to organize code logically and separate concerns (library, tests, examples). Each CMakeLists.txt should be understandable independently.

wiki/cmake-subdirectories.md · Last modified: by 127.0.0.1