CargoConfig
How a Cargo is configured. image and source are required, so
interface in bldr/rust-tools
How a Cargo is configured. image and source are required, so
omitting either is a compile error rather than a failure at build time.
Properties
binary: boolean | CargoBinaryOptions | WithId<CargoBinaryOptions>[]
property
The binaries this crate produces, registered as output directories.
- omitted — none, because a crate that produces no binary is ordinary
and guessing a
[[bin]]name would be worse than saying nothing; - an options object — one output at
<scope>/binary; - a list — one per entry at
<scope>/binary/<id>.
Declaring them here is also what lets Cargo.binary be asked for
one by name rather than re-described at every call: the set is known,
so an unknown name is an error with the real list in it.
See CargoBinaryOptions, WithId.
cache: false
property
Set false to run every command with a cold /target, instead of the
per-command incremental cache volume this builder mounts by default.
The crates a command compiles are not a cache: they are the fetch step's output, an input like the source tree, and are mounted either way.
A cache cannot change what a build produces — its content never reaches an invocation cache key — so this exists for the case where that guarantee is the thing under test, not for correctness in ordinary builds.
check: boolean | CargoOptions | WithId<CargoOptions>[]
property
The check targets to register on scope, automatically.
Every crate wants one and almost none wants a different one, so it is a default rather than a line in each member's build file. Eight members wrote the identical check registration by hand before this existed.
- omitted — one target at
<scope>/check, with the default options; false— none, for a member whose sources cannot be checked in isolation;- an options object — one target at
<scope>/check, with those options; - a list — one target per entry at
<scope>/check/<id>, for a crate that must compile several ways (feature combinations, target triples) and wants each to fail separately.
A list rather than a map keyed by name, because a map and a single
options object cannot be told apart without guessing at their contents —
{ features: … } and { features: { … } } differ only in a nesting
level. Array.isArray needs no guess, and the name rides along as id.
See CargoOptions, WithId.
clippy: boolean | CargoClippyOptions | WithId<CargoClippyOptions>[]
property
The cargo clippy gates to register on scope, in the same shapes
as check — true for one at <scope>/clippy with the defaults,
an options object to configure it, a list for one per entry at
<scope>/clippy/<id>.
Opt-in rather than on by default, unlike check: clippy is a
style gate whose findings move with the toolchain, so switching it on
for every crate at once would turn a rustup bump into a repo-wide build
failure. A crate opts in when its lints are clean and it intends to keep
them that way.
See CargoClippyOptions, WithId.
coverage: boolean | CargoCoverageOptions | WithId<CargoCoverageOptions>[]
property
The coverage-data outputs to register on scope.
- omitted or
false— none; true— one output at<scope>/coverage, with the defaults;- an options object — one output at
<scope>/coverage, measured that way; - a list — one per entry at
<scope>/coverage/<id>, for a crate whose coverage is worth measuring under more than one feature set.
Opt-in, like clippy and fmt rather than default-on
like check — and for a blunter reason than either. Instrumented
code is markedly slower to compile and slower to run: every crate in the
graph is rebuilt with -C instrument-coverage, and each test binary
writes a profile as it goes. Switching that on for every Rust member in
the repo would roughly double what a full build costs, permanently, to
produce a number most of those members have nobody to read. A crate opts
in when someone is actually using the figure.
The output is data, not a gate. It is registered as an output
directory, not a test, so it never fails a build for being low — and
failing tests do not suppress it either, since coverage of a red run is
still the measurement that was asked for. Whether the tests passed is the
test target's answer, and duplicating that verdict here would only
create a second place for it to disagree with itself.
See CargoCoverageOptions, WithId.
defaults: CargoOptions
property
Options every command inherits, unless it overrides them.
For the settings that are a property of the crate rather than of one
command. A crate that only ever builds for one target triple says so once
here, instead of repeating it on check, test, doc and binary and
getting it wrong on the fifth.
See CargoOptions.
defaults: { target: "x86_64-unknown-linux-musl" },
binary: { binaryName: "init", profile: "release" }, // musl, inherited
test: { bins: true }, // musl tooMerged per key, not deeply: a command that names features replaces the
default list rather than adding to it, because a half-inherited feature
set is far harder to reason about than an explicit one.
dependencies: CargoDependency[]
property
Sibling crates to build against — see CargoDependency.
Each one is mounted and patched in, so the crate's own manifest can keep
depending on it by version alone and stay publishable. Pass another
Cargo directly, or any { crateName, source } for a crate that
has no builder of its own.
dependencies: [protoLib, { crateName: "helper", source: helper.rootDirectory }],Works for a single crate and for a workspace alike: the patches are
written at config level rather than into a manifest, so a source tree that
already declares its own [patch.crates-io] is left untouched.
doc: boolean | CargoDocOptions | WithId<CargoDocOptions>[]
property
The rustdoc output to register on scope, in the same shapes as
check. Registered as a documentation output, so a consumer
can find it by role rather than by guessing its name.
See CargoDocOptions, WithId.
environment: Record<string, string>
property
Environment variables set on every cargo pod this builder runs — the
pod-level sibling of mounts, for values that belong to the build
rather than the image (BLDR_PROTO_DIR pointing at a mounted proto
tree, say). Image-wide env — PATH, anything an image layer's own
commands need — stays on CargoToolchainOptions.env.
fmt: boolean | CargoOptions | WithId<CargoOptions>[]
property
The cargo fmt --all --check gates to register on scope, in the
same shapes as clippy, and opt-in for the same reason.
Check only — this never rewrites the source tree. A build runs on a content-addressed copy of the sources, so formatting them there would produce a tree nobody sees; the useful answer is whether what is committed is formatted.
See CargoOptions, WithId.
lsp: boolean | CargoOptions | WithId<CargoOptions>[]
property
The editor language servers to register, in the same shapes as
check.
On by default, because an editor wants one for every Rust crate and the analyzer has to agree with the build about toolchain, source layout and manifest location — which this builder already knows and an editor does not. A list is for a crate whose feature combinations disagree enough that one analyzer view would be wrong for half of them.
See CargoOptions, WithId.
manifestDir: string
property
The crate or workspace root within source, when the manifest is not at
the mount root.
This is what lets an existing multi-crate workspace be built as it
stands. CargoConfig.deps cannot, because it wraps the crate in a
generated workspace and cargo forbids nesting one workspace inside
another. A workspace that already patches its siblings by relative path
just needs them present at those paths, which is a matter of laying the
tree out — Directory.merge(a.at("x"), b.at("y")) — and pointing this at
the root crate.
// source holds `engine/`, `engine-macros/` and `util/` side by side
manifestDir: "engine",mounts: Record<string, Directory>
property
Extra read-only trees to mount, by absolute container path → tree. For
inputs a build reads from outside the source tree (a include_str! that
escapes the crate, a fixture directory).
See Directory.
package: boolean | CargoOptions | WithId<CargoOptions>[]
property
The package outputs to register, in the same shapes as check.
Off by default: most crates are built, not published, and a packaging run that nobody consumes is cost with no reader.
See CargoOptions, WithId.
resources: DagResources
property
What each of this builder's runs is admitted against and held to — see
DagResources.
Worth setting for a large workspace, for the same reason
CargoOptions.jobs is. A node admits every DAG that declares
nothing against its default share (a quarter of what it can hand out),
and holds it to that as a hard limit, page cache included: a compile
that wants more has its cache reclaimed over and over and, when its
compilers alone exceed the share, is killed. Per command,
CargoOptions.resources wins over this.
See DagResources.
sccache: false | "read-only"
property
The node's shared compile cache (sccache — see docs/sccache.md), on by default wherever the node can serve it.
Every compiling command's pod asks the node for sccache, and cargo runs
rustc through the wrapper (build.rustc-wrapper in the pod's own
$CARGO_HOME/config.toml, so the source tree is never touched and a
build that sets RUSTC_WRAPPER itself keeps it). Entries live in the
node's store, so a crate compiled by any pod of any build on the cluster
is a download for the next one with the same inputs.
- omitted — read-write, on a node that advertises
pod.sccache; on one that does not, the build runs exactly as it did before sccache existed; "read-only"— use entries, never store any;false— off.cache: false(cache) turns it off too: that setting asks for every command to run cold, and a compile cache is a cache.
It coexists with the /target cache volume rather than replacing it.
The volume keeps one command's whole target dir on one node — fresh
crates are not recompiled at all, and workspace members build
incrementally. sccache shares compiled crates across crate graphs,
commands and nodes, which is what a cold or evicted volume needs.
Incremental compiles are not cacheable: sccache declines any rustc
invocation carrying -C incremental, which cargo passes for workspace
members in the dev profile. Those stay the volume's job; dependencies
(and every release-profile crate) go through sccache. A builder whose
environment sets CARGO_INCREMENTAL=1 gets no sccache at all —
the wrapper refuses to run under it, and would fail every compile.
Like a cache volume it cannot change what a build produces: only the request reaches a pod's spec, never the cache's content.
scope: Scope
property
Where this Cargo's work appears in the build tree.
A Cargo makes its own Cargo child of whatever it is given, and one
subscope per command (build, test, clippy, doc, package), so a
member that runs several of them gets a readable subtree.
Required. There is no sensible default: a builder with nowhere to put its work ends up wherever its first consumer happens to be, which is how a shared task came to be attributed to an unrelated part of the tree.
See Scope.
source: Directory
property
The source tree: a single crate's root, or a workspace root.
See Directory.
test: boolean | CargoTestOptions | WithId<CargoTestOptions>[]
property
The test targets to register on scope, automatically.
The same shapes as check, and for the same reason: every
crate wants its tests run and almost none wants them run differently,
so it is a default rather than a line in each build file.
- omitted — one target at
<scope>/test; false— none, for a crate whose tests cannot run here;- an options object — one target at
<scope>/test, run that way; - a list — one per entry at
<scope>/test/<id>, so a crate that must be tested several ways gets a separate verdict for each rather than one that stops at the first failure.
See CargoTestOptions, WithId.
toolchain: any
property
The toolchain to build with.
A CargoToolchain normally; a bare container image is accepted for
a toolchain assembled some other way, as long as cargo is on its PATH.
workspace: boolean
property
Scope every command to the whole workspace (--workspace). Ignored when
CargoConfig.package is set.
For a test target this is the safe default: Cargo resolves the member list
from the workspace manifest at build time — including glob members
(crates/*) and path dependencies pulled in implicitly — so a crate added
tomorrow is selected with no build definition to update.