Migration from cmake-format
Switching to cmakefmt is designed to be straightforward. The goal is easy
adoption, not a risky repository-wide rewrite — roll out incrementally, compare
output at each step, and commit to full migration once you are satisfied.
Recommended Rollout
Section titled “Recommended Rollout”-
Start with
--checkon a small, low-risk directory to get a feel for the output before touching anything:Terminal window cmakefmt --check cmake/ -
Generate a starter config. YAML is the recommended default:
Terminal window cmakefmt config init -
If you already have a
cmake-formatconfig file, convert it automatically:Terminal window cmakefmt config convert .cmake-format.py > .cmakefmt.yamlYAML is the default output format. For TOML instead, pass
--format tomlto the same command. -
Compare output on a representative sample. Use
--diffto see exactly what would change without touching any files:Terminal window cmakefmt --diff path/to/CMakeLists.txt -
When the output looks good across your sample, expand to
--check .on the full repository:Terminal window cmakefmt --check . -
Switch pre-commit and CI once you are happy with the full-repository output.
If you want to roll out formatting gradually — file by file — use
--require-pragma to opt individual files in before going repository-wide.
See Formatter Behavior for the pragma syntax.
CLI Mapping
Section titled “CLI Mapping”cmake-format intent |
cmakefmt equivalent |
|---|---|
| format file to stdout | cmakefmt FILE |
| in-place format | cmakefmt -i FILE |
| CI check | cmakefmt --check PATH |
| recursive target filtering | cmakefmt --path-regex REGEX PATH |
--separate-fn-name-with-space true |
Same flag; adds spaces before ordinary call parentheses |
--separate-ctrl-name-with-space true |
Same flag; adds spaces before structural command parentheses, including definitions |
| convert old config file | cmakefmt config convert OLD.py > .cmakefmt.yaml |
| disable formatting regions | supports both cmake-format and cmakefmt spellings |
Spaces before parentheses
Section titled “Spaces before parentheses”cmake-format’s separate_fn_name_with_space controls ordinary command calls,
such as project (foo). The converter maps it to
format.separate_fn_name_with_space, including break, continue, and
return. Its separate_ctrl_name_with_space
also covers function/macro definitions, so conversion sets
separate_ctrl_name_with_space. There are two spacing controls: ordinary calls
and structural commands, including definitions.
If you previously converted a config using separate_fn_name_with_space,
convert it again to restore spacing on ordinary calls. Earlier conversions
incorrectly mapped this setting to definition spacing only.
space_before_definition_paren remains accepted as a deprecated fallback for
separate_ctrl_name_with_space. An explicit control setting takes precedence,
including the released space_before_control_paren alias. Replace old keys
with separate_ctrl_name_with_space to configure spacing on definitions and
other structural commands together.
Key Differences
Section titled “Key Differences”| Area | cmake-format | cmakefmt |
|---|---|---|
| Default command casing | Preserves source casing | Lowercases commands |
| Indentation key | tab_width |
tab_size |
| Config format | YAML, JSON, or Python | YAML or TOML |
| Disable regions | # cmake-format: off/on |
# cmakefmt: off/on (also accepts cmake-format and fmt spellings) |
| Custom commands | [parse].additional_commands |
commands: section in config |
Unsupported Legacy Options
Section titled “Unsupported Legacy Options”These cmake-format options are intentionally not carried forward:
| Option / Section | Reason |
|---|---|
[lint] (all 17 options) |
cmakefmt is a formatter only; linting is a separate concern |
[encode] (emit_byteorder_mark, input_encoding, output_encoding) |
UTF-8 is the modern default |
[parse].vartags / [parse].proptags |
Used only for linting |
[format].layout_passes |
Covered by always_wrap and per-command overrides |
When converting a legacy config, unsupported options are noted in comments in the output so you can see exactly what was skipped and why.
Compatibility Notes
Section titled “Compatibility Notes”- the goal is easy adoption, not output identity
- the built-in command registry is audited through CMake 4.3.1
--configis still accepted as an alias for--config-file--path-regexreplaces the older--file-regex- any compatibility gaps should be reported as bugs, not silently worked around
Operational Advice
Section titled “Operational Advice”Start small, build confidence, then go wide. Formatter migrations become painful when the first exposure is a large repository-wide rewrite with no comparison data. The recommended pattern:
-
Run
--diffor--checkon a representative subset before committing to anything. -
Capture a before/after snapshot on a branch so you can review the delta as a normal diff.
-
Use
--require-pragmaif you want to phase the rollout file-by-file rather than all at once. -
Pin an explicit version in CI once you are happy:
Terminal window cmakefmt --required-version 2.3.1 --check .
Output will not be identical to cmake-format. The goal is a clean,
correct, stable result — not byte-for-byte reproduction. Judge the migration by
readability, idempotency, and ease of automation rather than by whether every
wrapped line matches historical output exactly. See Formatter Behavior
for a concrete summary of what cmakefmt preserves and what it intentionally changes.
Docs track main. For historical docs, check out a release tag inthe repository and builddocs/ locally.
