xtask-no-warnings
Silence warnings in xtask builds without invalidating the dependency cache.
Purpose
The standard way to silence compiler warnings during development is to set
RUSTFLAGS=-Awarnings. It works, but it has a painful side effect: RUSTFLAGS is part of the
compiler fingerprint for every crate in the build graph. Toggling it forces Cargo to
recompile the entire project from scratch, including all dependencies. On machines with limited
resources (e.g. low-specs laptops, handheld devices, ...) this means minutes of wasted build
time every single time you flip the flag.
This crate solves the problem by using RUSTC_WORKSPACE_WRAPPER instead.
RUSTC_WORKSPACE_WRAPPER routes rustc invocations through a wrapper binary but only for
workspace members. Dependencies are compiled by rustc directly and their cached artifacts
remain valid regardless of whether the wrapper is active.
The wrapper here is the xtask binary itself. At startup, [init] checks for a sentinel
environment variable. When Cargo invokes the xtask as a rustc wrapper, init forwards all
arguments to the real rustc with -Awarnings prepended and then exits. When the developer
invokes the xtask normally, init is a no-op and the rest of the main function runs as
usual.
Because RUSTC_WORKSPACE_WRAPPER produces artifacts under a separate fingerprint from a
plain rustc run, the two modes (warning on or off) maintain independent caches for workspace
members. The very first toggle in each direction recompiles those crates, every subsequent
toggle hits the cache immediately.
Usage
1. Add the dependency to your xtask
xtask/Cargo.toml
[]
= "0.1"
2. Call init at the top of main
xtask/src/main.rs
init must be the very first statement so that when Cargo invokes the xtask as a rustc
wrapper, it exits immediately before any of your setup code runs.
3. Spawn Cargo with or without warnings
Option A - cargo_command
This function returns a Command for Cargo with the wrapper environment variable already set.
Append your subcommand and flags before running it.
Option B - setup
This function configures an existing Command in place. Useful when you are building the
Command yourself and only want to add the wrapper conditionally.
Basic xtask setup
A typical project using a xtask workspace member looks like this:
.cargo/
To create it the xtask, you can use cargo new xtask in the root of your project, you can
then create the .cargo/config.toml that should contains the following:
[]
= "run --package xtask --"
You should be able to invoke your xtask with cargo xtask <task>. For more information, check
the xtask repository.
Trade-offs
RUSTFLAGS=-Awarnings |
xtask_no_warnings |
|
|---|---|---|
| Silence warnings | Yes | Yes |
| Dependencies recompiled on toggle | Always | Never |
| Workspace members recompiled on first toggle | Always | Once per mode |
| Workspace members recompiled on subsequent toggle | Always | Never (cached) |
| Extra setup required | None | init + one function call |
The extra setup is a one-time cost. After that, every toggle is free for dependencies and free for workspace members after the first time each mode is entered.