cargo-build-rx
Compile-time diagnostic and prescription tool for Rust projects.
Slow Rust builds usually trace back to a short list of fixable causes: a slow
default linker, an over-broad feature set, a few crates compiled in several
versions, or a dev profile tuned for the wrong thing. cargo-build-rx reads
your project's metadata and configuration (it does not compile your code) and
prints a ranked list of concrete changes, each with the exact edit to make.
Installation
Usage
Severity levels
- FIX: nearly always correct to change (e.g. a fast linker is installed but unused).
- WARN: a real win that depends on the project; worth reviewing.
- INFO: surfaced for awareness.
By default the tool always exits 0. Pass --deny <fix|warn|info> to turn it
into a failing gate (see CI usage).
Proof: real output
These are the actual outputs of the current build, reproducible by anyone.
Running on itself
cargo-build-rx — 3 prescriptions for cargo-build-rx
WARN [Medium] Missing build-override opt-level for proc-macros
Proc-macros and build scripts run at opt-level 0 by default. Compiling them with opt-level 3 makes them run faster during builds.
-> In Cargo.toml [profile.dev.build-override]:
opt-level = 3
INFO [Low] split-debuginfo not set on macOS
Setting split-debuginfo = "unpacked" avoids bundling debug info during linking. Recent toolchains may already default to this for dev.
-> In Cargo.toml [profile.dev]:
split-debuginfo = "unpacked"
INFO [Low] 9 crates with build scripts
9 crates have build.rs scripts.
Summary: 1 warning, 2 info
Running on a fixture with a slow dev profile
The repository ships tests/fixtures/bloated, a crate whose dev profile sets
opt-level = 2 and debug = 2. Run cargo build-rx --manifest-path tests/fixtures/bloated/Cargo.toml:
cargo-build-rx — 4 prescriptions for bloated-fixture
WARN [Medium] Full debuginfo in dev profile
debug = 2 (full) slows compilation. Consider debug = 1 (line tables only) unless you need full variable inspection.
-> In Cargo.toml [profile.dev]:
debug = 1
WARN [Medium] opt-level = 2 in dev profile
Optimization in dev slows compile times significantly. Consider using opt-level = 0 for dev builds.
-> In Cargo.toml [profile.dev]:
opt-level = 0
WARN [Medium] Missing build-override opt-level for proc-macros
Proc-macros and build scripts run at opt-level 0 by default. Compiling them with opt-level 3 makes them run faster during builds.
-> In Cargo.toml [profile.dev.build-override]:
opt-level = 3
INFO [Low] split-debuginfo not set on macOS
Setting split-debuginfo = "unpacked" avoids bundling debug info during linking. Recent toolchains may already default to this for dev.
-> In Cargo.toml [profile.dev]:
split-debuginfo = "unpacked"
Summary: 3 warnings, 1 info
Linker and toolchain findings depend on the host, so output varies by machine.
The 10 checks
| # | Check | What it detects |
|---|---|---|
| 1 | linker | Default ld on Linux (recommends mold/lld, targeting the real host triple). On macOS, an unset dev split-debuginfo. |
| 2 | profile | debug = 2, opt-level > 0 in dev (integer or "s"/"z"), missing build-override opt-level for proc-macros. |
| 3 | duplicates | The same crate compiled in several distinct versions (escalates for syn, serde, tokio, ...). |
| 4 | proc-macros | syn 1.x and 2.x both present; a high total proc-macro count. |
| 5 | build-scripts | Inventory of build.rs crates, flagging those with native links. |
| 6 | features | tokio/full, reqwest/default-tls, and other heavy default feature sets. |
| 7 | dev-deps | criterion, proptest, and other heavy dev-dependencies. |
| 8 | toolchain | Installed rustc older than the project's rust-version (MSRV); a dated hint when far behind stable. |
| 9 | workspace | Multi-crate workspace without a workspace-hack crate. |
| 10 | incremental | CARGO_INCREMENTAL=0 set in the local dev environment. |
How it works
cargo-build-rx runs cargo metadata and reads your Cargo.toml,
.cargo/config.toml, and a few environment variables. Every check is a pure
function over this gathered data. No compilation of your project happens, so a
run finishes in roughly a second on a typical crate.
The check engine is also exposed as a library (cargo_build_rx) for embedding
or testing; see the crate docs.
CI usage
- name: Check build hygiene
run: |
cargo install cargo-build-rx
cargo build-rx --deny fix
--deny fix exits non-zero only when a Fix-severity finding exists, so the
step fails just for the strongest recommendations. Use --deny warn for a
stricter gate. Without --deny, the tool reports and exits 0.
JSON output
Returns an array of findings with severity, category, impact, title,
description, and an optional fix carrying a structured kind
(CargoConfig, CargoToml, ShellCommand, or Manual).
Minimum supported Rust version
1.85, verified against the committed Cargo.lock. Newer dependency versions may
raise the effective floor when the lockfile is not used.
License
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT license (LICENSE-MIT)
at your option.