Skip to content

/flags/cmake/cmake-s-b-source-build-directory

cmake -S . -B build: set the source and build directories

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash)updated
tool
CMake
command
cmake
flag
-S <path-to-source> -B <path-to-build>
default
source = the directory given as argument, build = the current directory
since
3.13

cmake -S . -B build configures the project whose top-level CMakeLists.txt is in . (the source directory) and writes all generated files into build (the build directory), creating it if needed. It replaces the older mkdir build && cd build && cmake ... Then build with cmake --build build. Both options exist since CMake 3.13.

Configure and build

bash
cat > CMakeLists.txt <<'EOF'
cmake_minimum_required(VERSION 3.20)
project(demo LANGUAGES NONE)
add_custom_target(hello ALL COMMAND ${CMAKE_COMMAND} -E echo "hello from the build step")
EOF
CM="uv run -q --no-project --python 3.13 --with cmake==4.4.4 --with ninja cmake"
$CM -G Ninja -S . -B build | grep -v 'Build files have been written' | sed 's/ ([0-9.]*s)$//'
$CM --build build | grep -x 'hello from the build step'
ls build | grep -E 'CMakeCache.txt|build.ninja'

Output

-- Configuring done
-- Generating done
hello from the build step
CMakeCache.txt
build.ninja

The source directory stays clean: everything generated is under build/, which you can delete at any time to start over.

Common combinations

bash
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release        # single-config generators (Ninja, Makefiles)
cmake --build build -j 8
cmake -S . -B build-debug -DCMAKE_BUILD_TYPE=Debug    # a second build tree from the same source
cmake -S . -B build -G "Visual Studio 17 2022"
cmake --build build --config Release                  # multi-config generators (Visual Studio, Xcode)
cmake --install build --prefix "$HOME/.local"
cmake --fresh -S . -B build                           # discard the cache and reconfigure (3.24+)

Rules

FormMeaning
cmake -S src -B buildExplicit source and build directories (3.13+)
cmake -B buildSource = current directory
cmake -S srcBuild directory = current directory
cmake ..Old form: source = .., build = current directory
cmake buildIf build already has a CMakeCache.txt, reconfigure that existing build tree
cmake --build buildRun the native build tool (ninja, make, MSBuild) in that tree

Why a separate build directory

Without -B, CMake writes CMakeCache.txt, CMakeFiles/ and the generated build files into the current directory. Run from the project root, that is an in-source build: generated files mix with your sources, git status fills up, and cleaning means deleting files one by one. With -B build everything lives in one directory that you add to .gitignore and remove when you want a clean start. You can also keep several trees from one checkout (Debug and Release, two compilers, two generators) side by side.

Options that go with -S and -B

OptionPhaseWhat it does
-G "Ninja"configurechoose the generator; fixed for the life of the build tree
-D VAR=valueconfigureset a cache variable such as CMAKE_BUILD_TYPE or CMAKE_INSTALL_PREFIX
--preset nameconfigureread generator, build directory and variables from CMakePresets.json
--freshconfigurerebuild the cache from scratch, keeping the directory (3.24+)
--build build -j Nbuildrun the native tool with N parallel jobs (3.12+); --parallel is the long form
--build build --target namebuildbuild one target instead of the default ones; --target clean only cleans
--build build --clean-firstbuildclean, then build
--build build -vbuildprint the compiler commands that are run

Errors you may meet

  • -S points to a directory without CMakeLists.txt: CMake stops with does not appear to contain CMakeLists.txt. Check the path is the project root, not a subdirectory.
  • The build directory was created with another generator or another source directory: CMake refuses to reuse it. Delete the directory, choose a new -B name, or pass --fresh.
  • No compiler found while configuring: see No CMAKE_C_COMPILER could be found. The build directory then holds a failed cache; reconfigure after fixing the toolchain.
  • An old project fails under CMake 4 with Compatibility with CMake < 3.5 has been removed; that is unrelated to -S and -B.

Paths given to -S and -B are relative to the current directory, and both may be absolute. On Windows, quote paths that contain spaces.

FAQ

What is the difference between cmake -B build and mkdir build && cd build && cmake ..?

The result is the same build tree. -S and -B (CMake 3.13+) do it in one command without changing directory, which is easier to script.

Do I have to run cmake -S -B again after editing CMakeLists.txt?

No. cmake --build build notices the change and reconfigures automatically. Run the configure step again only to change cache variables or after deleting the directory.

Where does the compiled program end up?

Inside the build directory, in the subdirectory that matches the source layout unless the project sets output directories. Multi-config generators add a Debug or Release subdirectory.

Sources