cargo_dependencies

Cargo dependency graph consumed by Rust targets.

Description#

During graph loading, Once reads a checked-in Cargo metadata snapshot or runs cargo metadata --locked --offline against the configured Cargo manifest. Every resolved registry or Git package becomes a synthetic rust_crate or rust_proc_macro target. Normal dependencies remain deps, while packages needed by Cargo build scripts use the build_deps role.

The cargo_dependencies target does not compile those packages itself. It aggregates the providers from the generated target graph, so independent packages can compile concurrently and Cargo's dependency topology remains visible to queries, validation, caching, and scheduling.

Cargo.toml and Cargo.lock stay the source of truth. Live resolution is locked and fails when the lockfile does not match the manifest. Every external package in checked-in metadata is cross-checked against an exact lock entry. The snapshot must also carry once_snapshot provenance that binds every other resolver input, the selected features and target, and the compiler host triple. Graph loading rejects any provenance mismatch. First-party Rust targets depend on this aggregate target and identify their Cargo package via CARGO_PKG_NAME or the cargo_package attribute. Once then exposes only the direct external dependencies Cargo reported for that workspace package. The configured manifest and lockfile must both be covered by resolver_inputs, together with any workspace member manifests Cargo needs to inspect. When resolver_inputs is empty or omitted, srcs supplies those files instead. When the declared inputs include .cargo/config.toml or .cargo/config, Once passes that file to Cargo explicitly. Vendored source replacement therefore works even when Once loads the graph from a different process directory.

Generated target names include the destination target triple when target is set. Native and cross-compiled dependency graphs can therefore coexist in one package without synthetic target collisions.

Attributes#

AttributeTypeRequiredDefaultDescription
manifeststringnoCargo.tomlPackage-relative Cargo manifest path passed to cargo metadata --manifest-path
lockfilestringnoCargo.lockPackage-relative Cargo lockfile path read as a declared resolver input
resolver_inputslist<string>nosrcsPackage-relative text globs supplied to the resolver
metadata_filestringnoChecked-in JavaScript Object Notation output from Cargo metadata with once_snapshot input and selection provenance
host_metadata_filestringnoCargo metadata snapshot with host selection provenance for the execution host. Required when metadata_file is combined with an explicit target
vendor_dirstringnothird_party/rust/vendorPackage-relative directory containing vendored crate sources
packageslist<string>no[]Optional package names to expose from this dependency set. Defaults to all resolved external packages
featureslist<string>no[]Cargo features passed to cargo metadata --features
all_featuresboolnofalsePass --all-features to Cargo metadata
no_default_featuresboolnofalsePass --no-default-features to Cargo metadata
targetstringnohost targetRust target triple passed to Cargo as --filter-platform
dep_rustc_flagslist<string>no[]Additional rustc flags applied to resolved crate builds. Panic strategy flags are stripped for procedural macro and host-tool crates so they keep the compiler's unwind strategy
_cargo_resolvedboolresolver-ownedfalseMarks an owner whose locked packages were expanded into graph targets
_cargo_workspace_depsmap<string, list<string>>resolver-owned{}Records generated direct dependency target names by workspace package
_cargo_workspace_dep_aliasesmap<string, map<string, string>>resolver-owned{}Records Cargo dependency renames by workspace package and generated target

The underscore-prefixed attributes are part of the typed resolver contract. They are produced by Once and should not be set in once.toml.

Dependency Edges#

EdgeAcceptsDescription
depsrust_crate, rust_proc_macroLocked packages emitted by the resolver and aggregated into rust_dependency_set

Providers#

The target emits rust_dependency_set.

Capabilities#

CapabilityOutput groups
buildnone

Checked Snapshot Example#

The portable bundled starter omits metadata_file and resolves live in locked, offline mode. This variant shows how to opt into a compiler-host-specific checked snapshot:

toml
[[target]]
name = "cargo_dependencies"
kind = "cargo_dependencies"
srcs = [
"Cargo.toml",
"Cargo.lock",
".cargo/config.toml",
"cargo-metadata.json",
"apps/*/Cargo.toml",
]
[target.attrs]
manifest = "Cargo.toml"
lockfile = "Cargo.lock"
resolver_inputs = [
"Cargo.toml",
"Cargo.lock",
".cargo/config.toml",
"cargo-metadata.json",
"apps/*/Cargo.toml",
]
metadata_file = "cargo-metadata.json"
vendor_dir = "third_party/rust/vendor"
packages = ["itoa"]
[[target]]
name = "hello"
kind = "rust_binary"
deps = ["cargo_dependencies"]
srcs = ["src/**/*.rs"]
[target.attrs]
crate_name = "hello"
[target.attrs.rustc_env]
CARGO_MANIFEST_DIR = "apps/hello"
CARGO_PKG_NAME = "hello"
CARGO_PKG_VERSION = "0.0.0"

The optional packages filter limits what the aggregate provider exposes. It does not alter Cargo's version or feature resolution. Transitive dependencies remain ordinary generated graph edges of the selected package.

Regenerate the snapshot with the same features and target selection used by the Once target whenever Cargo.toml or Cargo.lock changes. Without metadata_file, graph loading runs Cargo in locked, offline mode. When a snapshot target sets target, also provide host_metadata_file so procedural macros and build dependencies use the execution-host graph.

Augment each checked-in Cargo metadata object with an once_snapshot object:

json
{
"once_snapshot": {
"inputs": {
"Cargo.toml": "exact manifest text",
"Cargo.lock": "exact lockfile text",
".cargo/config.toml": "exact Cargo configuration text",
"apps/hello/Cargo.toml": "exact workspace member manifest text"
},
"selection": {
"features": [],
"all_features": false,
"no_default_features": false,
"target": "",
"host": false,
"host_triple": "x86_64-unknown-linux-gnu"
}
}
}

The input keys and contents must match every resolver_inputs file except the target and host metadata snapshots. Set host to true only in host_metadata_file. Set target to the target attribute value, including an empty string when the target uses the execution host. Set host_triple to the exact host reported by the selected Rust compiler for a native snapshot and for every host metadata snapshot. Use an empty string for destination metadata when target is explicit. This makes a manifest, configuration, feature, target, or compiler host change fail during graph loading instead of silently reusing stale metadata.

Every generated package declares its complete vendored source tree as an input. This covers files read through Rust source inclusion macros as well as Rust sources, manifests, build scripts, licenses, and package data.

Sources#

  • Cargo metadata defines the package graph and the failure behavior of --locked.
  • The Cargo lockfile defines the resolved package versions and checksums Once preserves.
  • Bazel rules for Rust, Crate Universe documents the upstream pattern of translating a Cargo manifest and lockfile into generated build targets with distinct normal, procedural macro, and build-script dependencies.