Learn CMake

The de facto build system generator for C and C++ projects

17 lessons · 3 hours · 4 levels · covers CMake 4.1

CMake describes a C or C++ project as targets with their sources, dependencies and requirements, then generates Ninja, Makefile or Visual Studio builds for any platform. It is what most open-source and commercial C++ uses, and what IDEs and package managers expect.

Before you start

CMake builds on these; the tree links to the exact lessons you need.

How deep do you want to go?

1. EssentialsRead and write simple code, do the everyday basics5 lessons · 54 min in total
2. PracticalUse it productively at work, with the usual idioms11 lessons · 2 hours in total
3. AdvancedThe less common features, performance and trade-offs14 lessons · 3 hours in total
4. ExpertInternals and the edge cases experts know17 lessons · 3 hours in total

The CMake tree

CMakeWhat CMake is: a build generatorWhat CMake is: abuild generatorA first CMakeLists.txtA first CMakeLists.txtThe CMake language: variables, lists, ifThe CMakelanguage: variables…Libraries and linking targetsLibraries and linkingtargetsPUBLIC, PRIVATE and INTERFACEPUBLIC, PRIVATE andINTERFACEProject structure and add_subdirectoryProject structure andadd_subdirectoryBuild types: Debug, Release and multi-configBuild types: Debug,Release and multi-c…C++ standard, warnings and definitionsC++ standard,warnings and defini…Using installed libraries: find_packageUsing installedlibraries: find_pack…Bringing dependencies in with FetchContentBringingdependencies in wi…Testing with CTestTesting with CTestCompiling and runningCompiling andrunningHeaders, namespaces and the ODRHeaders,namespaces and th…Linking, libraries and the ABILinking, libraries andthe ABI
Essentials and Practical shown (11 of 17 lessons); the full list is below. Click a lesson to read it.

All 17 lessons, in order

First builds

  1. What CMake is: a build generator · Essentials · 8 min

    CMake reads CMakeLists.txt and generates a native build (Ninja, Makefiles, Visual Studio); you configure once, then build many times.

  2. A first CMakeLists.txt · Essentials · 10 min

    Write the minimal project: cmake_minimum_required, project, add_executable and a C++ standard, then build and run it.

  3. The CMake language: variables, lists, if · Essentials · 12 min

    Read and write CMake script: set and ${VAR}, lists as semicolon-separated strings, message, if conditions, foreach and functions.

Targets and structure

  1. Libraries and linking targets · Essentials · 12 min

    Split code into libraries with add_library (STATIC, SHARED, or by BUILD_SHARED_LIBS) and connect targets with target_link_libraries.

  2. PUBLIC, PRIVATE and INTERFACE · Essentials · 12 min

    Attach include paths, definitions and options to targets with target_* commands, and control what propagates to dependents with PUBLIC, PRIVATE and INTERFACE.

  3. Project structure and add_subdirectory · Practical · 10 min

    Organise a project into directories, each with its own CMakeLists.txt, and understand how add_subdirectory scopes variables and paths.

Configurations and presets

  1. Build types: Debug, Release and multi-config · Practical · 10 min

    Pick optimisation and debug info with CMAKE_BUILD_TYPE (Ninja, Makefiles) or --config at build time (Visual Studio, Ninja Multi-Config).

  2. C++ standard, warnings and definitions · Practical · 10 min

    Set the C++ standard with target_compile_features or CMAKE_CXX_STANDARD, add warnings per compiler, and pass definitions to the code.

  3. CMakePresets.json · Advanced · 12 min

    Share configure, build and test settings in CMakePresets.json, keep personal ones in CMakeUserPresets.json, and run them with --preset or a workflow.

  4. Generator expressions · Advanced · 15 min

    Use $<...> generator expressions to vary settings by configuration, compiler, platform or target, evaluated when the build is generated.

Dependencies

  1. Using installed libraries: find_package · Practical · 12 min

    Locate installed dependencies with find_package, link their imported targets like fmt::fmt, and point CMake at them with CMAKE_PREFIX_PATH.

  2. Bringing dependencies in with FetchContent · Practical · 12 min

    Download and build dependencies as part of your project with FetchContent_Declare and FetchContent_MakeAvailable, and know when a package manager is better.

Testing and installing

  1. Testing with CTest · Practical · 10 min

    Register tests with enable_testing and add_test, run them with ctest, and discover GoogleTest cases automatically.

  2. Installing and exporting a package · Advanced · 15 min

    Install targets and headers with install(), export them with a namespace and generate Config files so others can find_package your library.

Under the hood

  1. Configure, generate, cache and policies · Expert · 15 min

    Know what happens in each CMake phase, how CMakeCache.txt and cache variables persist settings, and how policies keep old projects working.

  2. Toolchain files and cross-compiling · Expert · 15 min

    Describe a target platform in a toolchain file (compilers, sysroot, search modes) to cross-compile, and understand how package managers hook in the same way.

  3. Shared libraries, symbol visibility and RPATH · Expert · 15 min

    Hide symbols by default with GenerateExportHeader, set VERSION and SOVERSION, and make installed binaries find their libraries via RPATH.