Run cmake straight inside your source tree and you will spend the next afternoon untangling generated files from real code. This walks through configuring, building and installing a project the safe way, in a separate build directory you can delete without a second thought. It matches CMake 3.28.3 from the cmake package.
Allow 15 to 30 minutes for a small project, plus whatever time it takes to fetch or inspect its source. You need a shell and a readable source tree with a top-level CMakeLists.txt, plus the compiler and build tools the project expects. None of this needs sudo: installing into a system prefix is a separate, privileged step that is deliberately not part of the first run.
Two read-only checks before you touch anything, so you are not debugging a command copied for a different release or a directory that is not a CMake project at all.
cmake --version
test -f /path/to/project/CMakeLists.txt && echo "CMake project found"
On this machine the first command reports cmake version 3.28.3. Replace /path/to/project with the real source directory: if the second command prints nothing, stop and find the directory that actually holds the top-level file rather than pointing -S at a parent directory and hoping.
Use explicit source and build paths: -S names the source tree, -B names the build tree. CMake creates the build directory as needed and stores its persistent configuration in CMakeCache.txt.
cmake -S /path/to/project -B /path/to/project-build
A successful configure ends with generator-specific output and a line like Build files have been written to: /path/to/project-build. Confirm it:
test -f /path/to/project-build/CMakeCache.txt && echo "Build tree is configured"
Unix Makefiles, with Ninja also available.-G Ninja or similar, but only when that generator is installed and the rest of your workflow expects it. A build tree belongs to one generator; do not reuse it casually after changing -G.Pass project configuration as cache entries with -D. A single-configuration build type is the common example:
cmake -S /path/to/project \
-B /path/to/project-build \
-DCMAKE_BUILD_TYPE=Release
CMAKE_BUILD_TYPE only applies to single-configuration generators such as Unix Makefiles; multi-configuration generators pick a configuration at build time instead. Check the project's own documentation before adding project-specific variables, since CMake will happily accept a cache name the project ignores.
Repeated configure commands reuse the existing cache, which is convenient but can hide an old choice. See the current non-advanced values without editing anything:
cmake -L /path/to/project-build
Checkpoint: after changing an important option, rerun the configure command and read the summary rather than assuming the value stuck. If the project ships a preset, list them first with cmake --list-presets, then use one with cmake --preset NAME: a preset sets source, build, generator and cache together, so do not mix it with ad-hoc values unless the project documents that combination.
Once configuration succeeds, let CMake call the generated build tool. That keeps the command stable if the project ever switches from Makefiles to Ninja.
cmake --build /path/to/project-build
Zero means the native build finished; the progress text varies. Verify the target exists rather than trusting a quiet exit:
cmake --build /path/to/project-build --target help
cmake --build /path/to/project-build --parallel 2
--target help form asks the generated build system what it can build.--parallel 2 rebuilds with two jobs; size the count to the machine, since parallel builds eat memory as well as CPU.--target TARGET_NAME, or --config Debug for a multi-configuration generator that actually provides it.Anything after a standalone -- goes straight to the native build tool: treat that as an escape hatch for generator-specific behaviour, not a portable default. If a build fails, keep the first error, rerun with the same configuration, and read the compiler and dependency messages before you delete the build tree.
Installation changes the filesystem, so rehearse it somewhere under /tmp before you go near a system prefix. Set it during configuration:
cmake -S /path/to/project \
-B /path/to/project-build \
-DCMAKE_INSTALL_PREFIX=/tmp/cmake-guide-prefix
cmake --build /path/to/project-build
cmake --install /path/to/project-build
The install step runs the generated install rules without calling the native build tool directly. Check what landed:
find /tmp/cmake-guide-prefix -maxdepth 3 -type f -print
Some projects install nothing; some need a particular target or configuration. The prefix must be an absolute path when set through CMake's option, though you can override it for one install with cmake --install /path/to/project-build --prefix /tmp/cmake-guide-prefix.
Warning: cleaning up this disposable example means running rm -rf /tmp/cmake-guide-prefix, which is irreversible. Confirm the exact path first, never substitute a variable you have not inspected, and never reuse this pattern against a system directory.
Most CMake confusion traces back to a cache still holding an earlier source path, generator or option. Rerun the explicit -S/-B command and read the output first. If the build tree is disposable and you want a clean slate, CMake 3.28.3 has --fresh:
cmake --fresh -S /path/to/project -B /path/to/project-build
That deletes the existing cache file and recreates it: any cache selections you did not put on the command line need supplying again, and project-specific generated state may need regenerating too. Rename the old tree first, or configure a fresh build directory, if you want to keep it for comparison.
Warning: do not reach for sudo cmake to fix a compiler, dependency or cache error. Elevated configuration can leave root-owned files that break later unprivileged builds. Fix the actual toolchain or permissions problem, and save privilege for the one install step that genuinely needs it.
cmake --version identified the installed release.CMakeLists.txt.CMakeCache.txt and generated files.cmake --build finished for the intended target and configuration.