0. Design principle: drop-in syntax
The strongest argument for adding rustup to soldr's known-tool registry isn't ergonomics — it's preserving muscle memory. soldr already follows a strict drop-in convention: soldr cargo build is identical to cargo build except scoped to the pin and routed through zccache. The same contract should hold for rustup: soldr rustup target add x86_64-unknown-linux-musl should be identical to rustup target add x86_64-unknown-linux-musl except scoped to the project's pinned toolchain.
This rules out an entire class of "convenience" surface. No soldr target add, no soldr component add, no soldr-only verb that re-invents something rustup already spells. Every new verb soldr introduces has to earn its keep against this test. The only soldr-native verbs that earn it are the ones with no rustup equivalent: soldr toolchain prepare (reads soldr's project manifest; has no rustup analog) and soldr doctor (diagnostic). Everything else stays as soldr <wrapped-tool> <args> and behaves exactly like the underlying tool.
1. The proposal, in one paragraph
Make rustup a first-class soldr subcommand alongside cargo, rustc, clippy-driver, and rustfmt. soldr rustup <args> shells out to the system rustup binary with the same arguments, but with soldr in charge of which toolchain the call targets — so soldr rustup target add x86_64-unknown-linux-musl always installs against the pinned toolchain that soldr is enforcing, not against whatever rustup considers "active." On top of that passthrough, add soldr toolchain prepare: read the project's declared toolchain footprint and preload everything in one shot, before any build runs.
2. Ramifications
2.1 Toolchain-pin coherence (correctness, not just ergonomics)
A developer machine usually has more than one Rust toolchain installed: a stable from rustup-init, a project-pinned 1.94.1, maybe a nightly for fuzzing, maybe an older pin held open by another project. When a user runs bare rustup target add x86_64-unknown-linux-musl, rustup picks the active toolchain — whatever the user last set as default, or whatever rust-toolchain.toml resolves in the current directory. This is fragile. If the user is one directory up, or a parent has a rust-toolchain.toml that shadows the project's pin, the target lands on the wrong toolchain. The build then fails with a confusing "target not installed" error, and rustup target list --installed shows the target is installed — just somewhere else. soldr rustup target add ... removes this whole failure mode by forcing the call to be rustup target add --toolchain <pinned> <triple>. The pin is the source of truth; soldr enforces it.
2.2 Eager preparation eliminates mid-build ambush failures
Today, the discovery loop for a missing cross target is:
- Run
cargo build --target x86_64-unknown-linux-musl.
- Cargo invokes rustc.
- Rustc errors:
can't find crate for 'std'.
- Developer runs
rustup target add ..., retries.
- Now a different target is missing because a build-script targets the host and the binary targets musl, or a component like
rust-src is required by a plugin that wasn't installed.
Every one of these failures costs minutes on a slow machine and a re-queued job in CI. They're all preventable: the project already knows which targets, components, and plugins it needs. A soldr toolchain prepare step run before any compilation moves these costs from "discovered painfully mid-build" to "paid once during a known setup phase." Same shift cargo fetch made for dependencies: not magic, just doing the inevitable work in the right place.
2.3 Single source of truth for a project's toolchain footprint
A non-trivial Rust project's toolchain footprint is more than "rustc." It's: a specific toolchain pin, clippy + rustfmt for CI, rust-src for cargo-fuzz / cargo-careful, one or more cross targets, possibly a nightly for miri, and a handful of cargo plugins (cargo-zigbuild, cargo-deny, cargo-nextest). Today, that footprint is scattered across rust-toolchain.toml, .cargo/config.toml, CI workflow YAML files, README setup blocks, and tribal knowledge. New contributors hit a different missing piece every time they try a different command. A soldr-recognized manifest — rust-toolchain.toml (which already supports targets and components natively in its [toolchain] table) plus an optional [soldr.plugins] section for cargo plugins — collapses that into one auditable spec, and soldr toolchain prepare enforces it.
2.4 Better error surface
soldr: tool not found: rustup: no repository on crates.io is technically accurate and entirely useless. A user typing soldr rustup target add ... expects either success or a clear "rustup doesn't ship from crates.io, install it from rustup.rs" — not a message that suggests soldr looked for rustup as if it were serde. Making rustup a known special case lets soldr produce errors at the right semantic level: "rustup binary not found on PATH," "pinned toolchain 1.94.1 isn't installed; run soldr toolchain install," "rustup >= 1.26 required, found 1.20."
2.5 Reproducibility across machines
"Does this build work on your machine?" today depends on off-band state: which rustup toolchains are installed, which targets and components those toolchains have, which cargo plugins are on PATH, which zig is installed. A soldr-mediated bootstrap that owns rustup means the answer to "what state does this project need from the toolchain layer?" is a single command's output, identical on every machine that runs it. setup-soldr already provides this property for CI; bringing it home to local dev closes a real reproducibility gap.
3. Examples
3.1 The dev-docker loop that motivated this
The ./dev script in the project that motivated this issue today reads:
if command -v rustup >/dev/null 2>&1; then
rustup target add "${TARGET_TRIPLE}"
else
echo "WARN: rustup not on PATH..." >&2
fi
soldr cargo install cargo-zigbuild --locked
( cd core && soldr cargo zigbuild --release --target "${TARGET_TRIPLE}" --locked )
Three setup checks and one bare-rustup invocation because soldr doesn't own toolchain prep yet. With drop-in soldr rustup plus a small project manifest, the intermediate form is every command consistently prefixed:
soldr rustup target add "${TARGET_TRIPLE}"
soldr cargo install cargo-zigbuild --locked
( cd core && soldr cargo zigbuild --release --target "${TARGET_TRIPLE}" --locked )
And once a manifest exists, the bootstrap collapses to:
soldr toolchain prepare
( cd core && soldr cargo zigbuild --release --target x86_64-unknown-linux-musl --locked )
3.2 CI via setup-soldr
Multi-target CI today, in full:
- uses: zackees/setup-soldr@v0
with: { cache: true }
- run: rustup target add x86_64-unknown-linux-musl
- run: rustup target add x86_64-pc-windows-gnu
- run: rustup component add clippy rustfmt
- run: cargo install cargo-zigbuild --locked
- run: cargo install cargo-nextest --locked
- run: pip install ziglang
- run: cargo zigbuild --release --target x86_64-unknown-linux-musl
- run: cargo zigbuild --release --target x86_64-pc-windows-gnu
- run: cargo nextest run
- run: cargo clippy -- -D warnings
The drop-in form preserves the shape but routes every tool through soldr:
- uses: zackees/setup-soldr@v0
with: { cache: true }
- run: soldr rustup target add x86_64-unknown-linux-musl
- run: soldr rustup target add x86_64-pc-windows-gnu
- run: soldr rustup component add clippy rustfmt
- run: soldr cargo install cargo-zigbuild --locked
- run: soldr cargo install cargo-nextest --locked
- run: pip install ziglang
- run: soldr cargo zigbuild --release --target x86_64-unknown-linux-musl
- run: soldr cargo zigbuild --release --target x86_64-pc-windows-gnu
- run: soldr cargo nextest run
- run: soldr cargo clippy -- -D warnings
With manifest + prepare, the provisioning lines collapse:
- uses: zackees/setup-soldr@v0
with: { cache: true, prepare-toolchain: true }
- run: soldr cargo zigbuild --release --target x86_64-unknown-linux-musl
- run: soldr cargo zigbuild --release --target x86_64-pc-windows-gnu
- run: soldr cargo nextest run
- run: soldr cargo clippy -- -D warnings
3.3 New-contributor onboarding
Today: clone, cargo build works, try ./dev, fails because pin is wrong, install rustup, re-run, target missing, install target, re-run, plugin missing, install, re-run, ziglang missing, install, finally works. Five distinct discovery failures.
With soldr toolchain prepare: clone, one bootstrap command (installs rustup-via-soldr if missing, pins toolchain, adds declared targets and components, installs declared cargo plugins, fetches zig), ./dev works.
3.4 Multi-target release workflow
A release producing musl-Linux, Windows-GNU, and macOS binaries today has to remember three rustup target add calls, the cargo-zigbuild install, and the right env vars per target. With a manifest declaring the three triples, the release is soldr toolchain prepare followed by three soldr cargo zigbuild --target <triple> calls. "Which targets are part of this release?" lives in one place rather than three CI scripts that have to be kept in sync.
4. How this fits the existing feature set
4.1 The "well-known managed tools" registry pattern
soldr already treats cargo / rustc / clippy-driver / rustfmt as well-known names that aren't fetched from crates.io. Adding rustup to that registry is a small, principled extension of an existing pattern. The same registry could absorb other commonly-needed-but-not-on-crates.io tools (zig, sccache, mold, the wasm-pack installer) in future expansions, each carrying the same "soldr knows how to find or fetch this; you don't have to know the install command" property — and each obeying the drop-in rule.
4.2 Composes with soldr cargo install
soldr already routes cargo install through itself, which means cargo plugins installed via soldr can land in a soldr-managed location instead of ~/.cargo/bin and be pinned per project. soldr toolchain prepare reads the manifest's plugin list and calls the existing soldr cargo install primitive in a loop. No new install path, no second source of truth — one orchestrator over an existing primitive.
4.3 zccache parallel: cache the toolchain layer the way we cache compilation
zccache already caches compile output across cargo build, cargo test, and cargo clippy so switching between them isn't wasteful. Toolchain artifacts — downloaded targets, downloaded components, downloaded cargo-plugin binaries — are the same shape of problem: expensive to fetch, rarely changing, shared across invocations. soldr is already in the cache-management business; extending zccache (or a sibling cache) to hold these artifacts is a natural step.
4.4 setup-soldr exposes a declarative subset
The companion issue at zackees/setup-soldr#104 already proposes auto-bootstrap on CI. With soldr toolchain prepare as the underlying primitive, setup-soldr becomes the declarative front end (YAML inputs → spec) and soldr becomes the engine (spec → installed state). The action stays the relaxed/CI-friendly side of the pair; the CLI stays the strict/explicit side. Same division of labor; sharper boundary between front end and engine.
5. Subcommand surface (minimal)
soldr rustup <args> # drop-in passthrough, scoped to the project pin
soldr toolchain install # ensure the pinned toolchain itself is installed
soldr toolchain prepare # read manifest, install everything declared in one shot
soldr doctor # report drift between manifest and installed state
That's it. No soldr target add, no soldr component add — those are soldr rustup target add and soldr rustup component add and behave identically to bare rustup except for the pin scoping. The manifest is the existing rust-toolchain.toml (already supports targets and components in [toolchain]) plus an optional [soldr.plugins] section. No new file needed for the common case.
6. Target storage: global, not project-scoped
When soldr rustup target add x86_64-unknown-linux-musl installs a cross-compile target, where on disk should the rustlib live? Three plausible answers:
- (A) Project-level: install into a project-private rustup home.
- (B) Global: rustup's native layout —
~/.rustup/toolchains/<channel>-<host>/lib/rustlib/<target>/.
- (C) soldr-owned cache + symlinks: dedup centrally, link into per-project rustup homes.
Answer: (B). Global, rustup-native, no symlinks.
Why not project-level (A)
A rustlib is keyed by (toolchain_version, target_triple) — that tuple is already globally unique, with no project-specific variant possible. Project A using 1.94.1 + musl and project B using 1.94.1 + musl would store the exact same bytes twice. Five projects × three targets × two toolchains is roughly 1.5 GB of duplicated std rustlibs for a class of artifact (50–150 MB each) where dedup is free if you don't fight rustup. Cold install per project, no sharing.
Why not symlinks-into-project (C)
The symlink approach buys nothing meaningful and breaks real invariants:
- Rustup writes into the toolchain directory during component/target operations and expects to own it. Symlinking a "shared" rustlib into multiple project-private homes risks one project's
rustup component add mutating another's expected state.
- Cross-volume symlinks on Windows are restricted (require elevation or developer mode).
- The only thing the symlink would buy is
ls visibility — but rustup target list --installed --toolchain <pin> already answers "what's installed for this pin" and the manifest answers "what should be." Two clear sources of truth beats a symlink farm.
Why global (B) is right
Rustup natively dedupes by toolchain. A target rustlib at ~/.rustup/toolchains/1.94.1-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-musl/ is shared by every project on that machine using 1.94.1 + musl. That's the property you want — fighting it costs complexity for no win on a class of artifact too small to matter (50–150 MB vs. multi-GB registry-src / workspace target trees).
What soldr earns at this layer
Not storage. Authority and reaping.
- Authority:
soldr toolchain prepare reads each project's manifest (rust-toolchain.toml + [soldr.plugins]) and shells out rustup target add --toolchain <pin> <triple> for missing entries. Global install, project-scoped enforcement.
- Reaping: soldr's target registry (
~/.soldr/state.redb, already tracking workspace target/ dirs for GC) gets extended to record which (toolchain, target) pairs each project's manifest references. That gives GC a signal it doesn't have today.
- New GC kind under soldr#323's taxonomy:
rustup_target_rustlib, safety class derived (re-fetchable from dist server). Eligibility: rustlib for a (toolchain, target) pair where no registered project manifest references that pair AND last-used > some threshold. Belongs in soldr gc sweep's aggressive tier — the reclaim volume is small relative to other kinds, so the value is correctness (cleaning up after deprecated cross-compile targets) rather than reclaim bytes.
Disk-cost framing
| Class |
Typical per-machine size |
GC priority |
Workspace target/ (per workspace) |
200 MB – 4 GB |
high |
~/.cargo/registry/src/ |
1 – 8 GB |
high |
~/.cargo/git/checkouts/ |
0 – 2 GB |
medium |
Target rustlibs (rustup_target_rustlib) |
50 MB – 1 GB total |
low — but adds correctness signal |
Adding rustup_target_rustlib to GC is mostly about hygiene (manifest-driven cleanup), not pressure relief.
7. Non-goals
- Replacing rustup. soldr shells out to the system rustup binary; it does not reimplement toolchain installation.
- Implicit toolchain installs at build time.
soldr cargo build --target <triple> should still fail loudly if the target isn't installed. Bootstrap is a separate, explicit step — that's the whole point of the eager-prep model. Implicit installs would re-introduce the ambush failure mode in a new disguise.
- Convenience verbs that duplicate rustup spellings. Excluded by the design principle in §0.
- Project-local rustup homes or symlink-based target sharing. See §6 — global storage in rustup's native layout, with soldr acting as authority + reaper.
- Managing non-Rust language toolchains as a general framework. The
rustup / zig / sccache extensions are pragmatic exceptions for tools that are functionally part of a Rust cross-compile pipeline. soldr isn't trying to become asdf.
Related
0. Design principle: drop-in syntax
The strongest argument for adding
rustupto soldr's known-tool registry isn't ergonomics — it's preserving muscle memory. soldr already follows a strict drop-in convention:soldr cargo buildis identical tocargo buildexcept scoped to the pin and routed through zccache. The same contract should hold for rustup:soldr rustup target add x86_64-unknown-linux-muslshould be identical torustup target add x86_64-unknown-linux-muslexcept scoped to the project's pinned toolchain.This rules out an entire class of "convenience" surface. No
soldr target add, nosoldr component add, no soldr-only verb that re-invents something rustup already spells. Every new verb soldr introduces has to earn its keep against this test. The only soldr-native verbs that earn it are the ones with no rustup equivalent:soldr toolchain prepare(reads soldr's project manifest; has no rustup analog) andsoldr doctor(diagnostic). Everything else stays assoldr <wrapped-tool> <args>and behaves exactly like the underlying tool.1. The proposal, in one paragraph
Make
rustupa first-class soldr subcommand alongsidecargo,rustc,clippy-driver, andrustfmt.soldr rustup <args>shells out to the systemrustupbinary with the same arguments, but with soldr in charge of which toolchain the call targets — sosoldr rustup target add x86_64-unknown-linux-muslalways installs against the pinned toolchain that soldr is enforcing, not against whatever rustup considers "active." On top of that passthrough, addsoldr toolchain prepare: read the project's declared toolchain footprint and preload everything in one shot, before any build runs.2. Ramifications
2.1 Toolchain-pin coherence (correctness, not just ergonomics)
A developer machine usually has more than one Rust toolchain installed: a stable from
rustup-init, a project-pinned 1.94.1, maybe a nightly for fuzzing, maybe an older pin held open by another project. When a user runs barerustup target add x86_64-unknown-linux-musl, rustup picks the active toolchain — whatever the user last set as default, or whateverrust-toolchain.tomlresolves in the current directory. This is fragile. If the user is one directory up, or a parent has arust-toolchain.tomlthat shadows the project's pin, the target lands on the wrong toolchain. The build then fails with a confusing "target not installed" error, andrustup target list --installedshows the target is installed — just somewhere else.soldr rustup target add ...removes this whole failure mode by forcing the call to berustup target add --toolchain <pinned> <triple>. The pin is the source of truth; soldr enforces it.2.2 Eager preparation eliminates mid-build ambush failures
Today, the discovery loop for a missing cross target is:
cargo build --target x86_64-unknown-linux-musl.can't find crate for 'std'.rustup target add ..., retries.rust-srcis required by a plugin that wasn't installed.Every one of these failures costs minutes on a slow machine and a re-queued job in CI. They're all preventable: the project already knows which targets, components, and plugins it needs. A
soldr toolchain preparestep run before any compilation moves these costs from "discovered painfully mid-build" to "paid once during a known setup phase." Same shiftcargo fetchmade for dependencies: not magic, just doing the inevitable work in the right place.2.3 Single source of truth for a project's toolchain footprint
A non-trivial Rust project's toolchain footprint is more than "rustc." It's: a specific toolchain pin,
clippy+rustfmtfor CI,rust-srcforcargo-fuzz/cargo-careful, one or more cross targets, possibly a nightly formiri, and a handful of cargo plugins (cargo-zigbuild,cargo-deny,cargo-nextest). Today, that footprint is scattered acrossrust-toolchain.toml,.cargo/config.toml, CI workflow YAML files, README setup blocks, and tribal knowledge. New contributors hit a different missing piece every time they try a different command. A soldr-recognized manifest —rust-toolchain.toml(which already supportstargetsandcomponentsnatively in its[toolchain]table) plus an optional[soldr.plugins]section for cargo plugins — collapses that into one auditable spec, andsoldr toolchain prepareenforces it.2.4 Better error surface
soldr: tool not found: rustup: no repository on crates.iois technically accurate and entirely useless. A user typingsoldr rustup target add ...expects either success or a clear "rustup doesn't ship from crates.io, install it from rustup.rs" — not a message that suggests soldr looked forrustupas if it wereserde. Makingrustupa known special case lets soldr produce errors at the right semantic level: "rustup binary not found on PATH," "pinned toolchain 1.94.1 isn't installed; runsoldr toolchain install," "rustup >= 1.26 required, found 1.20."2.5 Reproducibility across machines
"Does this build work on your machine?" today depends on off-band state: which rustup toolchains are installed, which targets and components those toolchains have, which cargo plugins are on PATH, which zig is installed. A soldr-mediated bootstrap that owns rustup means the answer to "what state does this project need from the toolchain layer?" is a single command's output, identical on every machine that runs it. setup-soldr already provides this property for CI; bringing it home to local dev closes a real reproducibility gap.
3. Examples
3.1 The dev-docker loop that motivated this
The
./devscript in the project that motivated this issue today reads:Three setup checks and one bare-rustup invocation because soldr doesn't own toolchain prep yet. With drop-in
soldr rustupplus a small project manifest, the intermediate form is every command consistently prefixed:And once a manifest exists, the bootstrap collapses to:
3.2 CI via setup-soldr
Multi-target CI today, in full:
The drop-in form preserves the shape but routes every tool through soldr:
With manifest +
prepare, the provisioning lines collapse:3.3 New-contributor onboarding
Today: clone,
cargo buildworks, try./dev, fails because pin is wrong, install rustup, re-run, target missing, install target, re-run, plugin missing, install, re-run, ziglang missing, install, finally works. Five distinct discovery failures.With
soldr toolchain prepare: clone, one bootstrap command (installs rustup-via-soldr if missing, pins toolchain, adds declared targets and components, installs declared cargo plugins, fetches zig),./devworks.3.4 Multi-target release workflow
A release producing musl-Linux, Windows-GNU, and macOS binaries today has to remember three
rustup target addcalls, the cargo-zigbuild install, and the right env vars per target. With a manifest declaring the three triples, the release issoldr toolchain preparefollowed by threesoldr cargo zigbuild --target <triple>calls. "Which targets are part of this release?" lives in one place rather than three CI scripts that have to be kept in sync.4. How this fits the existing feature set
4.1 The "well-known managed tools" registry pattern
soldr already treats
cargo/rustc/clippy-driver/rustfmtas well-known names that aren't fetched from crates.io. Addingrustupto that registry is a small, principled extension of an existing pattern. The same registry could absorb other commonly-needed-but-not-on-crates.io tools (zig,sccache,mold, thewasm-packinstaller) in future expansions, each carrying the same "soldr knows how to find or fetch this; you don't have to know the install command" property — and each obeying the drop-in rule.4.2 Composes with
soldr cargo installsoldr already routes
cargo installthrough itself, which means cargo plugins installed via soldr can land in a soldr-managed location instead of~/.cargo/binand be pinned per project.soldr toolchain preparereads the manifest's plugin list and calls the existingsoldr cargo installprimitive in a loop. No new install path, no second source of truth — one orchestrator over an existing primitive.4.3 zccache parallel: cache the toolchain layer the way we cache compilation
zccache already caches compile output across
cargo build,cargo test, andcargo clippyso switching between them isn't wasteful. Toolchain artifacts — downloaded targets, downloaded components, downloaded cargo-plugin binaries — are the same shape of problem: expensive to fetch, rarely changing, shared across invocations. soldr is already in the cache-management business; extending zccache (or a sibling cache) to hold these artifacts is a natural step.4.4 setup-soldr exposes a declarative subset
The companion issue at zackees/setup-soldr#104 already proposes auto-bootstrap on CI. With
soldr toolchain prepareas the underlying primitive, setup-soldr becomes the declarative front end (YAML inputs → spec) and soldr becomes the engine (spec → installed state). The action stays the relaxed/CI-friendly side of the pair; the CLI stays the strict/explicit side. Same division of labor; sharper boundary between front end and engine.5. Subcommand surface (minimal)
That's it. No
soldr target add, nosoldr component add— those aresoldr rustup target addandsoldr rustup component addand behave identically to bare rustup except for the pin scoping. The manifest is the existingrust-toolchain.toml(already supportstargetsandcomponentsin[toolchain]) plus an optional[soldr.plugins]section. No new file needed for the common case.6. Target storage: global, not project-scoped
When
soldr rustup target add x86_64-unknown-linux-muslinstalls a cross-compile target, where on disk should the rustlib live? Three plausible answers:~/.rustup/toolchains/<channel>-<host>/lib/rustlib/<target>/.Answer: (B). Global, rustup-native, no symlinks.
Why not project-level (A)
A rustlib is keyed by
(toolchain_version, target_triple)— that tuple is already globally unique, with no project-specific variant possible. Project A using1.94.1 + musland project B using1.94.1 + muslwould store the exact same bytes twice. Five projects × three targets × two toolchains is roughly 1.5 GB of duplicated std rustlibs for a class of artifact (50–150 MB each) where dedup is free if you don't fight rustup. Cold install per project, no sharing.Why not symlinks-into-project (C)
The symlink approach buys nothing meaningful and breaks real invariants:
rustup component addmutating another's expected state.lsvisibility — butrustup target list --installed --toolchain <pin>already answers "what's installed for this pin" and the manifest answers "what should be." Two clear sources of truth beats a symlink farm.Why global (B) is right
Rustup natively dedupes by toolchain. A target rustlib at
~/.rustup/toolchains/1.94.1-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-musl/is shared by every project on that machine using1.94.1+ musl. That's the property you want — fighting it costs complexity for no win on a class of artifact too small to matter (50–150 MB vs. multi-GB registry-src / workspace target trees).What soldr earns at this layer
Not storage. Authority and reaping.
soldr toolchain preparereads each project's manifest (rust-toolchain.toml+[soldr.plugins]) and shells outrustup target add --toolchain <pin> <triple>for missing entries. Global install, project-scoped enforcement.~/.soldr/state.redb, already tracking workspacetarget/dirs for GC) gets extended to record which(toolchain, target)pairs each project's manifest references. That gives GC a signal it doesn't have today.rustup_target_rustlib, safety class derived (re-fetchable from dist server). Eligibility: rustlib for a(toolchain, target)pair where no registered project manifest references that pair AND last-used > some threshold. Belongs insoldr gc sweep's aggressive tier — the reclaim volume is small relative to other kinds, so the value is correctness (cleaning up after deprecated cross-compile targets) rather than reclaim bytes.Disk-cost framing
target/(per workspace)~/.cargo/registry/src/~/.cargo/git/checkouts/rustup_target_rustlib)Adding
rustup_target_rustlibto GC is mostly about hygiene (manifest-driven cleanup), not pressure relief.7. Non-goals
soldr cargo build --target <triple>should still fail loudly if the target isn't installed. Bootstrap is a separate, explicit step — that's the whole point of the eager-prep model. Implicit installs would re-introduce the ambush failure mode in a new disguise.rustup/zig/sccacheextensions are pragmatic exceptions for tools that are functionally part of a Rust cross-compile pipeline. soldr isn't trying to become asdf.Related