Understanding the configure/build split explains most of CMake's commands and errors.
CMake is not a compiler and not quite a build tool. It is a build system generator: you describe the project once in CMakeLists.txt, and CMake writes the files for a real build tool on the current platform, such as Ninja, Unix Makefiles, Visual Studio or Xcode projects. The build tool then calls the compiler.
The workflow has two steps:
- Configure (and generate):
cmake -S . -B buildreads the source directory, detects compilers, finds dependencies and writes a build tree intobuild/. - Build:
cmake --build buildruns the generated build tool. You can callninjaormakedirectly, butcmake --buildworks with any generator.
Always use an out-of-source build: everything generated goes into the build directory, the sources stay clean, and deleting build/ resets everything. You can have several build trees for one source tree, for example build-debug and build-release.
You only need to reconfigure explicitly when you change options. If you edit CMakeLists.txt, the next build notices and reruns the configure step automatically.
Pick the generator with -G: cmake -S . -B build -G Ninja. Ninja is fast and the usual choice on all platforms; without -G CMake picks a platform default (Makefiles on Unix, Visual Studio on Windows).
Example
# project layout
# hello/
# CMakeLists.txt
# main.cpp
cmake -S hello -B hello/build -G Ninja # configure + generate
# -- The CXX compiler identification is GNU 13.3.0
# -- Configuring done
# -- Generating done
# -- Build files have been written to: hello/build
cmake --build hello/build # build with Ninja
./hello/build/hello # run the program
# edit a .cpp file: just build again, only that file recompiles
cmake --build hello/build
rm -rf hello/build # start completely freshRemember
- CMake generates a build for Ninja, Make or Visual Studio
- Configure with cmake -S src -B build, build with cmake --build build
- Keep builds out of source so deleting build/ resets everything
Watch out for
- Running cmake . inside the source directory, which litters it with generated files that are hard to clean up.