CMake Knowledge Base
CMake is a build-system generator: you describe your project once in CMakeLists.txt, and CMake
emits the native build files (Makefiles, Ninja, Visual Studio, Xcode) for whatever platform you're
on. These docs cover modern, target-based CMake (3.15+) — the target_* style that replaced the
old global-variable approach — from first project to dependencies, testing, and the advanced bits.
How this is organised
Roughly in learning order: Intro → Basics → Targets is the core you use every day; Dependencies, Organization, Advanced, and Testing are the layers you add as projects grow. Each folder is self-contained — follow the cross-links.
Sections
| Section | What it covers | |
|---|---|---|
| Introduction | What CMake is, installing it, your first project | |
| Basics | CMakeLists.txt structure, variables, commands, build types, presets | |
| Targets | Executables, libraries, target properties, linking | |
| Dependencies | find_package, FetchContent, ExternalProject | |
| Project Organization | Multi-directory layouts, add_subdirectory, modern patterns | |
| Advanced | Generator expressions, functions/macros, find modules, custom commands | |
| Testing | CTest basics and integrating tests into the build |
Suggested reading paths
- New to CMake: Introduction → Basics → Targets. Enough to build a real app.
- Pulling in a library: find_package → FetchContent, then linking.
- Scaling a project: Subdirectories → Multi-Directory → Best Practices.
Quick reference
CMakeLists.txt essentials
cmake_minimum_required(VERSION 3.15)
project(MyProject VERSION 1.0 LANGUAGES CXX)
add_executable(myapp main.cpp)
add_library(mylib STATIC lib.cpp)
target_link_libraries(myapp PRIVATE mylib) # who depends on whom
target_include_directories(myapp PRIVATE include/) # scoped to this target
target_compile_features(myapp PRIVATE cxx_std_17) # request a standard
find_package(Threads REQUIRED)
Build workflow
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release # configure
cmake --build build -j # build (parallel)
ctest --test-dir build # test
cmake --install build --prefix /usr/local # install
Conventions used across these docs
- Examples target CMake 3.15+ and the modern target-based style (
target_*over globalset()). - The golden rule throughout: set properties on targets with
PRIVATE/PUBLIC/INTERFACEscope, not globally. - Admonitions flag the important bits:
infocontext,tipguidance,warning/dangerfoot-guns.