Skip to content

feat(examples): docker-cross-all — one linux image cross-builds all 8 targets#924

Open
zackees wants to merge 8 commits into
mainfrom
loop/docker-cross-all
Open

feat(examples): docker-cross-all — one linux image cross-builds all 8 targets#924
zackees wants to merge 8 commits into
mainfrom
loop/docker-cross-all

Conversation

@zackees

@zackees zackees commented Jun 22, 2026

Copy link
Copy Markdown
Owner

Summary

Iteration 1 of /loop — replaces the per-OS GH Actions matrix with a single local-docker recipe that bakes soldr prepare --target <comma-list> into the image so a fresh docker run does zero network fetches before going into cargo build.

Blocked on #925 — uses the comma-separated --target form that ships in that PR.

What's in the image

  1. soldr (PyPI wheel — pip install soldr==<version>)
  2. rustup + 1.94.1 (soldr bootstrap + soldr toolchain install)
  3. All cross-compile assets (soldr prepare --target <comma-list> — zig, LLVM, Apple SDK, xwin MSVC CRT cache, rustup target add for all 8 triples). The explicit comma-separated list is used because at image-build time no source volume is mounted, so --target all can't read [workspace.metadata.soldr].targets.

What build.sh does

  • Builds the image (cached after first run).
  • Loops the requested targets through soldr cargo build --release --target <triple>.
  • Copies each artifact back to out/<triple>/.
  • Prints per-target wall-clock, binary size, file(1) type, and du -sh of target/<triple>/ and target/<triple>/release/incremental/.
  • Ends with a final target/ partition report so the cargo per-platform layout is visible — input to the cache-design iteration that follows.

Draft because

End-to-end docker build + docker run validation is iteration 2 of this loop. It also needs #925 to land in a PyPI release first.

Follow-ups tracked by the loop

  • Run the docker build, fix any breakage in soldr prepare --target <list> along the way.
  • Wire soldr save <stable-path> / soldr load <same-path> for one cache artifact per repo at a stable name (no per-target fan-out).
  • Optimization pass: lld, codegen-units, parallel target builds, eliminate redundant prepare-time downloads.

Depends on #925.
Refs #914.

🤖 Generated with Claude Code

… targets

Replaces the per-OS GH Actions matrix with a single local-docker step.
The image bakes:

  1. soldr (PyPI wheel)
  2. rustup + 1.94.1 channel (`soldr bootstrap` + `soldr toolchain
     install`)
  3. `soldr prepare --target all` — zig, LLVM, Apple SDK, xwin MSVC
     CRT cache, every `rustup target add` for the 8 triples declared
     in `[workspace.metadata.soldr].targets`.

`build.sh` loops the targets through `soldr cargo build --release
--target <triple>`, copies each artifact back to `out/<triple>/`, and
prints per-target wall-clock plus `du -sh` of `target/<triple>/` and
its `incremental/` subdir. The final report dumps the cargo per-
platform layout so the cache shape is auditable at a glance.

Iteration 1 of the loop: ships the skeleton; cache save/load wiring,
optimization passes, and end-to-end docker build validation are
follow-ups tracked outside this PR.

Refs #914.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The seed/Cargo.toml workaround existed only so `soldr prepare --target
all` had a `[workspace.metadata.soldr].targets` table to read from at
image-build time. Switching to the explicit comma-separated form
(soldr PR #925) lets the bake step pass the 8 triples directly and
removes the seed manifest entirely.

Now requires a soldr release containing #925. Bump SOLDR_VERSION when
that lands.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace the `pipx install soldr==<ver>` step with a two-stage build:

  Stage 1 — debian + rust 1.94.1 + git clone soldr at `SOLDR_GIT_REF`
            (default main) + `cargo build --release`
  Stage 2 — runtime image with the built binary copied in + the
            existing soldr bootstrap / toolchain install / prepare
            sequence

Avoids the PyPI release cadence — the example always builds against
latest main (which now includes #925's comma-separated --target
form). Override with `--build-arg SOLDR_GIT_REF=<sha|branch>` to
pin a specific revision.

Image grows by the rust-toolchain layer in stage 1 but stage 2
remains lean; the final image carries only the soldr binary.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
zackees and others added 2 commits June 22, 2026 06:37
…orks

soldr prepare calls bare `rustup target add` via PATH (root-caused in
issue #927). When soldr-managed rustup lives at `/root/.soldr/bin`
(not on PATH by default), every target's rustup-target-add silently
fails — the image looks prepared but only the host triple is
actually installed.

Workaround: prepend /root/.soldr/bin to PATH in stage 2 before
`soldr bootstrap` runs. This makes the rustup discovery succeed and
all 8 targets get added.

Also drop the misleading CARGO_HOME/RUSTUP_HOME env settings — soldr
manages those internally and the env-var override wasn't actually
honored (the cargo proxy at /opt/cargo/bin/ remained empty).

Drop this workaround once #927 lands.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
build.sh now dispatches by target family:
  *-pc-windows-msvc       → soldr cargo xwin build
  *-apple-darwin          → soldr cargo zigbuild
  *-unknown-linux-{gnu,musl} → soldr cargo zigbuild

Without the dispatch, plain `soldr cargo build` for windows-msvc dies
with "linker `link.exe` not found"; for darwin, the system linker
can't produce Mach-O. cargo-xwin and cargo-zigbuild auto-fetch on
first use (soldr's cargo front door), so no extra prepare step is
needed — the underlying assets (xwin CRT cache, zig, Apple SDK,
LLVM) were already baked into the image.

Also adds `MSYS_NO_PATHCONV=1` so the docker run survives Git-for-
Windows shell path translation, matching what `examples/docker-cross-
win/build.sh` already does.

Verified end-to-end on linux/amd64 docker: all 8 targets in
[workspace.metadata.soldr].targets build green. Per-target binary
sizes 128KB-432KB; aggregate target/ tree 4.6MB partitioned cleanly
by triple.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@zackees zackees marked this pull request as ready for review June 22, 2026 14:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant