$ cmake -S . -B build$ cmake --build build$ ./build/appHello, CMake!# you edit greet.cpp# rebuilt: 3 of 4 files# you edit greet.h# rebuilt: 4 of 4 files$ cmake -S . -B rel \ -DCMAKE_BUILD_TYPE=Release$ cmake --build relapplibgreet.amain.ogreet.o1greet.o: greet.cpp greet.h2libgreet.a: greet.o3main.o: main.cpp greet.h4app: main.o libgreet.a1cmake_minimum_required(VERSION 3.20)2project(hello CXX)3set(CMAKE_CXX_STANDARD 20)4add_library(greet greet.cpp)5add_executable(app main.cpp)6target_link_libraries(app greet)main.cppgreet.cppgreet.h01010101010101-O3
Violet: what you write (CMakeLists.txt and the source files); khaki card: the build graph CMake writesSand blocks: the tools (CMake, the compiler); plum blocks: built files, faint until they existTokens: files hopping into the tools, machine code (01) hopping out; a pencil marks an editIn front: the recipe CMakeLists.txt and the source files main.cpp, greet.cpp and greet.h. In the middle: CMake, the build graph it writes into build/, and the compiler. At the back: the terminal and the outputs app, libgreet.a, main.o and greet.o. cmake -S . -B build configures: the recipe goes through CMake into the build graph. cmake --build build follows the graph: both .cpp files are compiled (they do not depend on each other, so with Ninja they compile at the same time), greet.o is packed into libgreet.a, and the linker makes app. After an edit, only files older than their inputs are rebuilt: 3 of 4 after changing greet.cpp, all 4 after changing greet.h. The build graph card is a simplified view. CMake writes it as Makefiles (the default on Linux and macOS) or as build.ninja (with -G Ninja), with more rules and longer names: the object files are really build/CMakeFiles/greet.dir/greet.cpp.o and build/CMakeFiles/app.dir/main.cpp.o.

The recipe

  1. A real project has many files. Typing a compiler command for each one is slow and easy to get wrong. With CMake you describe the project once, in a file called CMakeLists.txt, and CMake works out the commands.

Configure

Build

Rebuild fast

Fast code

What happens

;; step 1/10 · recipe
CMakeLists.txt   the recipe, next to the source files
  1  cmake_minimum_required(VERSION 3.20)
  2  project(hello CXX)
  3  set(CMAKE_CXX_STANDARD 20)
  4  add_library(greet greet.cpp)
  5  add_executable(app main.cpp)
  6  target_link_libraries(app greet)
project folder: CMakeLists.txt  main.cpp  greet.cpp  greet.h

The build graph card is a simplified view. CMake writes it as Makefiles (the default on Linux and macOS) or as build.ninja (with -G Ninja), with more rules and longer names: the object files are really build/CMakeFiles/greet.dir/greet.cpp.o and build/CMakeFiles/app.dir/main.cpp.o. Header dependencies (greet.h) are not written in the recipe or in the generated files: the compiler reports them during the first build (GCC and Clang -MD depfiles), and the build tool remembers them.