Skip to main content

A fast, correct CMake formatter

Project description

cmakefmt banner

cmakefmt

CI
CI Pages Coverage CodSpeed

Package
Crates.io dependency status

Security & Quality
REUSE status OpenSSF Scorecard OpenSSF Best Practices

A lightning-fast, workflow-first CMake formatter — built in Rust, built to last.

cmakefmt demo

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/cmakefmt and yamadapc/cmakefmt.

Contents

Why cmakefmt?

  • 104× faster — not a typo. Geometric-mean speedup of 104× over cmake-format on real-world per-file corpora, rising to 2,853× on whole-repository runs. 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 cmakefmt the 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
opencv_flann/CMakeLists.txt 2 6.3 55.8 8.9×
googletest/CMakeLists.txt 36 5.4 68.2 12.6×
llvm_tablegen/CMakeLists.txt 83 6.4 83.8 13.1×
abseil/CMakeLists.txt 280 6.8 186.1 27.4×
spdlog/CMakeLists.txt 413 7.7 239.1 31.1×
mariadb_server/CMakeLists.txt 656 7.1 532.0 75.0×
xnnpack/CMakeLists.txt 1,354 8.6 1,568.9 182.2×
opencv/CMakeLists.txt (root) 2,039 9.8 43,158.4 4,417.2×
blender/CMakeLists.txt (root) 2,650 8.6 2,922.7 338.5×
llvm/libc/.../CMakeLists.txt 6,688 8.9 2,473.7 279.3×
grpc/CMakeLists.txt (root) 54,834 39.4 84,489.2 2,146.2×

Geometric-mean per-file speedup: 104×. Whole-repository parallel runs (across 14 large open-source repos including LLVM, blender, opencv, gRPC, and oomph-lib) average 150× faster than cmake-format geo-mean (95× serial), with parallel mode delivering up to 2.9× over cmakefmt serial on large repositories.

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

cmakefmt config init               # generate a starter .cmakefmt.yaml
cmakefmt --check .                 # dry-run: just show which files would change
cmakefmt .                         # dry-run: preview formatted output; changed lines shown in blue
cmakefmt --diff .                  # dry-run: view a unified diff of what would change (like `git diff`)
cmakefmt --in-place .              # apply formatting across the whole project
cmakefmt --staged --check          # use in pre-commit hooks
cmakefmt --path-regex 'src/.*' .   # format CMake files only under src/

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.3.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:

  1. Legacy cmake-format directives:

    # cmake-format: off
    set(MESSY_THING  a   b   c)   # kept verbatim
    # cmake-format: on
    
  2. Native directive barriers, using either cmakefmt or the shorter fmt spelling:

    # cmakefmt: off
    set(MESSY_THING  a   b   c)   # kept verbatim
    # cmakefmt: on
    
    # fmt: off
    set(MESSY_THING  a   b   c)   # kept verbatim
    # fmt: on
    
  3. 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 orchestration
  • lib.rs: public library API
  • config/: config loading, merging, and legacy conversion
  • parser/: hand-written parser, AST, and lowering pipeline
  • spec/: built-in and user-defined command registry
  • formatter/: AST-to-doc formatting logic and comment handling
  • files.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

cmakefmt-1.3.0.tar.gz (156.8 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

cmakefmt-1.3.0-py3-none-win_amd64.whl (2.8 MB view details)

Uploaded Python 3Windows x86-64

cmakefmt-1.3.0-py3-none-manylinux_2_39_x86_64.whl (2.7 MB view details)

Uploaded Python 3manylinux: glibc 2.39+ x86-64

cmakefmt-1.3.0-py3-none-manylinux_2_39_aarch64.whl (2.5 MB view details)

Uploaded Python 3manylinux: glibc 2.39+ ARM64

cmakefmt-1.3.0-py3-none-macosx_11_0_arm64.whl (2.4 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

cmakefmt-1.3.0-py3-none-macosx_10_12_x86_64.whl (2.6 MB view details)

Uploaded Python 3macOS 10.12+ x86-64

File details

Details for the file cmakefmt-1.3.0.tar.gz.

File metadata

  • Download URL: cmakefmt-1.3.0.tar.gz
  • Upload date:
  • Size: 156.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for cmakefmt-1.3.0.tar.gz
Algorithm Hash digest
SHA256 b8854a769207424801637d8455e2f6bcc61cd96b753b39aec2ac93d0445473e8
MD5 a746a6bf30f20433c2594cc90b9caff0
BLAKE2b-256 5d4f474b8a3e885143ae3796526edcc43c869543bceeaf2a2dbdd538775eaca8

See more details on using hashes here.

Provenance

The following attestation bundles were made for cmakefmt-1.3.0.tar.gz:

Publisher: release.yml on cmakefmt/cmakefmt

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file cmakefmt-1.3.0-py3-none-win_amd64.whl.

File metadata

  • Download URL: cmakefmt-1.3.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

Hashes for cmakefmt-1.3.0-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 b464207736bf8eebc332c8e70e3303e300678c960a0da0696a5aee56298a0ba4
MD5 6be61b10b211f576e3bdc6409626d1b0
BLAKE2b-256 7dbd1c7f87832aff59c784737cf45cbb063b7b1893b8cfa424bc5db6a562d98a

See more details on using hashes here.

Provenance

The following attestation bundles were made for cmakefmt-1.3.0-py3-none-win_amd64.whl:

Publisher: release.yml on cmakefmt/cmakefmt

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file cmakefmt-1.3.0-py3-none-manylinux_2_39_x86_64.whl.

File metadata

File hashes

Hashes for cmakefmt-1.3.0-py3-none-manylinux_2_39_x86_64.whl
Algorithm Hash digest
SHA256 997499e4a5c58a4d69901ffd62ac7bab8b691a98fad1a044796bb679e24b0c19
MD5 35d9e1e76d638da0dbe0f50e64e7ba38
BLAKE2b-256 dce49dfdac5fb4bd06cd43e636d85b3d927837b73bf6d300a1e41f59de3709d6

See more details on using hashes here.

Provenance

The following attestation bundles were made for cmakefmt-1.3.0-py3-none-manylinux_2_39_x86_64.whl:

Publisher: release.yml on cmakefmt/cmakefmt

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file cmakefmt-1.3.0-py3-none-manylinux_2_39_aarch64.whl.

File metadata

File hashes

Hashes for cmakefmt-1.3.0-py3-none-manylinux_2_39_aarch64.whl
Algorithm Hash digest
SHA256 43b05e49afbe63a8e32b2224e4e1186c4eb5bbb714f95452468b9d0f47c8535f
MD5 7d26772f55c3f6bc077a154e0e1843ba
BLAKE2b-256 a45b0ac1e021ea5edcf4dcdf7d2212c25cae13cf881a7d06d74bc98c1fca04e1

See more details on using hashes here.

Provenance

The following attestation bundles were made for cmakefmt-1.3.0-py3-none-manylinux_2_39_aarch64.whl:

Publisher: release.yml on cmakefmt/cmakefmt

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file cmakefmt-1.3.0-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for cmakefmt-1.3.0-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 254081d333a75e14bdbc4ff812ef4377bf4eff367e54c0c1e01a44f4dd57baf0
MD5 19aca8b4272998f49ec784af79ec16dc
BLAKE2b-256 e5b1a715d6e5db77ea03fd9659c87a21abcf3f9c2e40a4da48f1e42f57d6ac6d

See more details on using hashes here.

Provenance

The following attestation bundles were made for cmakefmt-1.3.0-py3-none-macosx_11_0_arm64.whl:

Publisher: release.yml on cmakefmt/cmakefmt

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file cmakefmt-1.3.0-py3-none-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for cmakefmt-1.3.0-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 1289c5b865e7b986099ce5f7315b4ddcc3be6696346effdc916603eded0e82ca
MD5 917ad82b94cbdae58b752913857c154c
BLAKE2b-256 fc7a8a6bc520b75f1e7cd5a80a956daf061925599aff27465df712128bcc4f35

See more details on using hashes here.

Provenance

The following attestation bundles were made for cmakefmt-1.3.0-py3-none-macosx_10_12_x86_64.whl:

Publisher: release.yml on cmakefmt/cmakefmt

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page