A fast, correct CMake formatter
Project description
cmakefmt
A lightning-fast, workflow-first CMake formatter — built in Rust, built to last.
The above demo was generated with VHS.
cmakefmt replaces the aging Python cmake-format tool with a
single native binary. Same spirit. No Python.
- crates.io:
cmakefmt-rust - CLI name:
cmakefmt
[!NOTE]
This project is independent from other Rust implementations, including:
azais-corentin/cmakefmtandyamadapc/cmakefmt.
Contents
- Why
cmakefmt? - Performance
- Installation
- Quick Start
- Common Workflows
- Configuration
- Formatter Disable Regions
- Library Usage
- Documentation
- Project Layout
- Development
- Status
- License
Why cmakefmt?
- 25× faster — not a typo. Geometric-mean speedup of
25.33xovercmake-formaton real-world corpora. Pre-commit hooks that once made you wince now finish before you blink. - Zero dependencies. One binary. No Python environment, no virtualenv bootstrap, no dependency drift. Drop it in CI and forget about it.
- Built for actual workflows.
--check,--diff,--staged,--changed,--files-from,--show-config,--explain-config, semantic verification, JSON reporting — all first-class, not scripted workarounds. - Knows your commands. Teach
cmakefmtthe argument structure of your project's custom CMake functions and macros. No more generic token-wrapping for code you wrote. - Errors that actually help. Parse and config failures come with file/line context, source snippets, and reproduction hints — not opaque parser noise.
- Designed for real repositories. Comment preservation, disable-region passthrough, config discovery, ignore files, Git-aware file selection, and opt-in parallelism are core features, not afterthoughts.
Performance
| Fixture | Lines | cmakefmt ms |
cmake-format ms |
Speedup |
|---|---|---|---|---|
abseil/CMakeLists.txt |
280 | 5.358 | 172.882 | 32.27× |
catch2/CMakeLists.txt |
230 | 5.177 | 110.495 | 21.34× |
cli11/CMakeLists.txt |
283 | 5.174 | 125.992 | 24.35× |
cmake_cmbzip2/CMakeLists.txt |
25 | 4.563 | 63.034 | 13.81× |
googletest/CMakeLists.txt |
36 | 4.376 | 65.244 | 14.91× |
ggml/CMakeLists.txt |
498 | 7.371 | 216.193 | 29.33× |
llama_cpp/CMakeLists.txt |
286 | 5.755 | 131.230 | 22.80× |
llvm_tablegen/CMakeLists.txt |
83 | 4.439 | 79.608 | 17.93× |
mariadb_server/CMakeLists.txt |
656 | 9.097 | 489.035 | 53.76× |
nlohmann_json/CMakeLists.txt |
237 | 5.035 | 140.580 | 27.92× |
opencv_flann/CMakeLists.txt |
2 | 4.263 | 54.812 | 12.86× |
protobuf/CMakeLists.txt |
351 | 5.478 | 114.711 | 20.94× |
spdlog/CMakeLists.txt |
413 | 6.461 | 220.804 | 34.17× |
qtbase_network/CMakeLists.txt |
420 | 7.852 | 293.745 | 37.41× |
xnnpack/CMakeLists.txt |
1354 | 26.965 | 1432.939 | 53.14× |
Geometric-mean speedup across the full corpus: 25.33×.
On a 220-file batch, --parallel 8 improves throughput by 3.80× vs serial.
Full methodology and profiler notes: cmakefmt.dev/performance/.
Update the pinned local corpus and generate local before/after review artifacts with:
python3 scripts/fetch-real-world-corpus.py
scripts/review-real-world-corpus.sh
Installation
Homebrew (macOS):
brew install cmakefmt/cmakefmt/cmakefmt
Cargo (any platform):
cargo install cmakefmt-rust
pip (any platform with Python):
pip install cmakefmt
conda-forge:
conda install -c conda-forge cmakefmt
Pre-built binaries (Linux, macOS, and Windows):
Download the .zip / .tar.gz for your platform from
GitHub Releases,
extract, and place the binary on your PATH.
Build from source:
git clone https://github.com/cmakefmt/cmakefmt
cd cmakefmt
cargo install --path .
Verify:
cmakefmt --version
Release channels and support levels are documented at cmakefmt.dev/release/. Shell completion installation instructions are available at cmakefmt.dev/install/.
Quick Start
1. Generate a starter config in your project root:
cmakefmt --dump-config > .cmakefmt.yaml
2. Dry-run — check your whole project without touching any files:
cmakefmt --check .
3. Apply formatting:
cmakefmt --in-place .
4. Format only the files you're about to commit:
cmakefmt --staged --check
Common Workflows
| Task | Command |
|---|---|
| Format file to stdout | cmakefmt CMakeLists.txt |
| Rewrite files in place | cmakefmt --in-place . |
| CI check | cmakefmt --check . |
| Preview which files would change | cmakefmt --list-changed-files . |
| See the exact patch | cmakefmt --diff CMakeLists.txt |
| Verify semantics while formatting to stdout | cmakefmt --verify CMakeLists.txt |
| Pre-commit guard (staged files only) | cmakefmt --staged --check |
| PR-scoped check | cmakefmt --changed --since origin/main --check |
| Machine-readable CI output | cmakefmt --check --report-format json . |
| GitHub Actions annotations | cmakefmt --check --report-format github . |
| Checkstyle / JUnit / SARIF output | cmakefmt --check --report-format checkstyle . |
| Pin the required binary version in CI | cmakefmt --required-version 1.0.0 --check . |
| Speed up repeated large-repo checks | cmakefmt --cache --check . |
| Roll out formatting file-by-file | cmakefmt --require-pragma --check . |
| Find project-specific commands | cmakefmt --list-unknown-commands . |
| Watch and auto-format on save | cmakefmt --watch . |
| Explain formatting decisions | cmakefmt --explain CMakeLists.txt |
| Read from stdin | cat CMakeLists.txt | cmakefmt - |
Configuration
cmakefmt searches upward from each file for .cmakefmt.yaml, .cmakefmt.yml, or .cmakefmt.toml.
YAML is recommended for larger configs.
Example .cmakefmt.yaml:
format:
line_width: 100
tab_size: 4
style:
command_case: lower
keyword_case: upper
markup:
enable_markup: true
Debug which config a file is actually using:
cmakefmt --show-config-path src/CMakeLists.txt
cmakefmt --show-config src/CMakeLists.txt
cmakefmt --explain-config
Migrate from an existing cmake-format config:
cmakefmt --convert-legacy-config .cmake-format.py > .cmakefmt.yaml
Full config reference: cmakefmt.dev/config/.
Formatter Disable Regions
Selectively opt out of formatting with barrier comments.
There are three barrier styles:
-
Legacy
cmake-formatdirectives:# cmake-format: off set(MESSY_THING a b c) # kept verbatim # cmake-format: on
-
Native directive barriers, using either
cmakefmtor the shorterfmtspelling:# cmakefmt: off set(MESSY_THING a b c) # kept verbatim # cmakefmt: on # fmt: off set(MESSY_THING a b c) # kept verbatim # fmt: on
-
Fence barriers, which toggle formatting on and off each time
# ~~~appears:# ~~~ set(MESSY_THING a b c) # kept verbatim # ~~~
Use directive barriers when you want an explicit start/end marker, and fence barriers when you want a shorter toggle-style block.
Library Usage
cmakefmt is also available as a Rust library:
use cmakefmt::{format_source, Config};
fn main() -> Result<(), cmakefmt::Error> {
let src = r#"target_link_libraries(foo PUBLIC bar baz)"#;
let out = format_source(src, &Config::default())?;
println!("{out}");
Ok(())
}
Full API docs: cmakefmt.dev/api/.
Documentation
Start here: https://cmakefmt.dev.
| Doc | Description |
|---|---|
| Install | Install options, first-project setup, CI wiring |
| Coverage | How coverage is measured, published, and interpreted |
| Release Channels | Release contract, support levels, and release artifacts |
| CLI Reference | Every flag, exit code, and discovery rule |
| Config Reference | Full config schema with examples |
| Formatter Behavior | How the formatter makes layout decisions |
Migration from cmake-format |
Incremental rollout guide and CLI mapping |
| Library API | Embedding cmakefmt in your own Rust tools |
| Troubleshooting | Common issues and debug workflow |
| Performance | Benchmark methodology and profiler notes |
| Contributing | How to contribute, run tests, and open PRs |
| Changelog | What's changed in each release |
Preview the full docs locally:
cd docs && npm install && npm run dev
Project Layout
cmakefmt/
├── docs/ # Astro + Starlight source published to cmakefmt.dev
├── src/ # CLI, library API, parser, config, spec, formatter
├── tests/ # integration tests, snapshots, and fixtures
├── benches/ # Criterion benchmarks
├── scripts/ # repo maintenance and docs helpers
└── .github/ # CI and Pages workflows
Key modules under src/:
main.rs: CLI entry point and workflow orchestrationlib.rs: public library APIconfig/: config loading, merging, and legacy conversionparser/:pestgrammar, AST, and parse pipelinespec/: built-in and user-defined command registryformatter/: AST-to-doc formatting logic and comment handlingfiles.rs: file discovery and ignore handling
Development
cargo fmt --check # formatting
cargo clippy --all-targets -- -D warnings # lints
cargo test # all tests
cargo llvm-cov --workspace --all-targets # coverage
cargo bench # benchmarks
Install pre-commit hooks:
pre-commit install
pre-commit install --hook-type pre-push
Status
The repository is stable and actively maintained. cmakefmt is still
pre-1.0, so release packaging, package-manager distribution, and some output
or API details may continue to evolve. The built-in command registry is audited
through CMake 4.3.1.
Hit something unexpected? See Troubleshooting or run:
cmakefmt --debug --check path/to/CMakeLists.txt
License
cmakefmt is dual-licensed under MIT or Apache-2.0 at your option.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cmakefmt-1.0.0.tar.gz.
File metadata
- Download URL: cmakefmt-1.0.0.tar.gz
- Upload date:
- Size: 139.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4a2db66c765328dd6ea2f4d1b0465ae8fc1b6e92a2a84e04ae7e487c43570849
|
|
| MD5 |
609bf4369db7e862d26e26e0379b3eaa
|
|
| BLAKE2b-256 |
ec10953d3ec7d0bb27081af8bc3e40f01f63ab131a3d5d940cc8279e5c9dec7f
|
Provenance
The following attestation bundles were made for cmakefmt-1.0.0.tar.gz:
Publisher:
release.yml on cmakefmt/cmakefmt
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cmakefmt-1.0.0.tar.gz -
Subject digest:
4a2db66c765328dd6ea2f4d1b0465ae8fc1b6e92a2a84e04ae7e487c43570849 - Sigstore transparency entry: 1290835293
- Sigstore integration time:
-
Permalink:
cmakefmt/cmakefmt@41dd0de7058f27525e54339b67dde65970d1c068 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/cmakefmt
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@41dd0de7058f27525e54339b67dde65970d1c068 -
Trigger Event:
push
-
Statement type:
File details
Details for the file cmakefmt-1.0.0-py3-none-win_amd64.whl.
File metadata
- Download URL: cmakefmt-1.0.0-py3-none-win_amd64.whl
- Upload date:
- Size: 2.8 MB
- Tags: Python 3, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
53af024ba1b724b04966c043990316c58dd057f4592c2308e551461455ae32a5
|
|
| MD5 |
5111a6f9d252b6ec623f99be3f87f362
|
|
| BLAKE2b-256 |
3eab6b713d3d22f64fd7f96ee0d4e20c1423ec56d9f350d0017060a70ffad9cd
|
Provenance
The following attestation bundles were made for cmakefmt-1.0.0-py3-none-win_amd64.whl:
Publisher:
release.yml on cmakefmt/cmakefmt
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cmakefmt-1.0.0-py3-none-win_amd64.whl -
Subject digest:
53af024ba1b724b04966c043990316c58dd057f4592c2308e551461455ae32a5 - Sigstore transparency entry: 1290835684
- Sigstore integration time:
-
Permalink:
cmakefmt/cmakefmt@41dd0de7058f27525e54339b67dde65970d1c068 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/cmakefmt
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@41dd0de7058f27525e54339b67dde65970d1c068 -
Trigger Event:
push
-
Statement type:
File details
Details for the file cmakefmt-1.0.0-py3-none-manylinux_2_39_x86_64.whl.
File metadata
- Download URL: cmakefmt-1.0.0-py3-none-manylinux_2_39_x86_64.whl
- Upload date:
- Size: 2.9 MB
- Tags: Python 3, manylinux: glibc 2.39+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
068fb7a29f74edb6f85a4bbcf38486fc66663b74b8ba1b3902a605eb59a80ab5
|
|
| MD5 |
ca2e8439b0ed33a9adb0d34c1ee377ef
|
|
| BLAKE2b-256 |
0067fb0496a0c8afc3df46d46d5045e8feba124689e9ff6cb9d47c608269fc01
|
Provenance
The following attestation bundles were made for cmakefmt-1.0.0-py3-none-manylinux_2_39_x86_64.whl:
Publisher:
release.yml on cmakefmt/cmakefmt
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cmakefmt-1.0.0-py3-none-manylinux_2_39_x86_64.whl -
Subject digest:
068fb7a29f74edb6f85a4bbcf38486fc66663b74b8ba1b3902a605eb59a80ab5 - Sigstore transparency entry: 1290835804
- Sigstore integration time:
-
Permalink:
cmakefmt/cmakefmt@41dd0de7058f27525e54339b67dde65970d1c068 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/cmakefmt
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@41dd0de7058f27525e54339b67dde65970d1c068 -
Trigger Event:
push
-
Statement type:
File details
Details for the file cmakefmt-1.0.0-py3-none-manylinux_2_39_aarch64.whl.
File metadata
- Download URL: cmakefmt-1.0.0-py3-none-manylinux_2_39_aarch64.whl
- Upload date:
- Size: 2.8 MB
- Tags: Python 3, manylinux: glibc 2.39+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
326055de0831f1777c34f51c33fe1479be38cf1312f82f5b780c18a2e5eca59d
|
|
| MD5 |
72fe3f363801af8e2cd92fe16be17b0a
|
|
| BLAKE2b-256 |
0b4302d0ff9cf7c842a579764d17d52dc3297e7fc2d8e493809f7fedd5c6a51a
|
Provenance
The following attestation bundles were made for cmakefmt-1.0.0-py3-none-manylinux_2_39_aarch64.whl:
Publisher:
release.yml on cmakefmt/cmakefmt
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cmakefmt-1.0.0-py3-none-manylinux_2_39_aarch64.whl -
Subject digest:
326055de0831f1777c34f51c33fe1479be38cf1312f82f5b780c18a2e5eca59d - Sigstore transparency entry: 1290835939
- Sigstore integration time:
-
Permalink:
cmakefmt/cmakefmt@41dd0de7058f27525e54339b67dde65970d1c068 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/cmakefmt
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@41dd0de7058f27525e54339b67dde65970d1c068 -
Trigger Event:
push
-
Statement type:
File details
Details for the file cmakefmt-1.0.0-py3-none-macosx_11_0_arm64.whl.
File metadata
- Download URL: cmakefmt-1.0.0-py3-none-macosx_11_0_arm64.whl
- Upload date:
- Size: 2.7 MB
- Tags: Python 3, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
13450e4eabf6f35963cd188098de860f14ef894d47cc9a0fb3d6e238aa20bb9a
|
|
| MD5 |
1db478c4033a6eca29666e330429cb7c
|
|
| BLAKE2b-256 |
a2c99aff30c1dc34c66702721b4094c26629d759bc07fea2233532a95058e332
|
Provenance
The following attestation bundles were made for cmakefmt-1.0.0-py3-none-macosx_11_0_arm64.whl:
Publisher:
release.yml on cmakefmt/cmakefmt
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cmakefmt-1.0.0-py3-none-macosx_11_0_arm64.whl -
Subject digest:
13450e4eabf6f35963cd188098de860f14ef894d47cc9a0fb3d6e238aa20bb9a - Sigstore transparency entry: 1290835436
- Sigstore integration time:
-
Permalink:
cmakefmt/cmakefmt@41dd0de7058f27525e54339b67dde65970d1c068 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/cmakefmt
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@41dd0de7058f27525e54339b67dde65970d1c068 -
Trigger Event:
push
-
Statement type:
File details
Details for the file cmakefmt-1.0.0-py3-none-macosx_10_12_x86_64.whl.
File metadata
- Download URL: cmakefmt-1.0.0-py3-none-macosx_10_12_x86_64.whl
- Upload date:
- Size: 2.9 MB
- Tags: Python 3, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
aff425fb10ec1c1ff8eb85c50bb57890c853a159a8adb01e5119af647277f4ec
|
|
| MD5 |
40ea0d5c0520e2f0223c971ab6c64ef1
|
|
| BLAKE2b-256 |
58d07cdec4afea53144628f99f757229e2ccd73ad8d8691973f6995b9a950e6e
|
Provenance
The following attestation bundles were made for cmakefmt-1.0.0-py3-none-macosx_10_12_x86_64.whl:
Publisher:
release.yml on cmakefmt/cmakefmt
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cmakefmt-1.0.0-py3-none-macosx_10_12_x86_64.whl -
Subject digest:
aff425fb10ec1c1ff8eb85c50bb57890c853a159a8adb01e5119af647277f4ec - Sigstore transparency entry: 1290835563
- Sigstore integration time:
-
Permalink:
cmakefmt/cmakefmt@41dd0de7058f27525e54339b67dde65970d1c068 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/cmakefmt
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@41dd0de7058f27525e54339b67dde65970d1c068 -
Trigger Event:
push
-
Statement type: