Repository navigation
rust + go: bootstrap both language toolchains from the hex0-rooted, CS-attested chains - #667
Conversation
|
Important Review skippedToo many files! This PR contains 244 files, which is 94 over the limit of 150. To get a review, reduce the PR to 150 files or fewer by splitting it into smaller PRs or changing its base branch. Upgrade to Team to raise the limit. Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
Reviews can continue after your included limit without a manual trigger. An admin must approve usage-based billing. ⚙️ Run configurationConfiguration used: Repository: gominimal/pkgs/.coderabbit.yaml Review profile: CHILL Plan: Essentials Run ID: 📒 Files selected for processing (244)
You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
…ader lists, s1 comment corrected
Consumer-verified (PR comment 5500513628): no rung reads R4a's or R4b's merged /usr copies any
more — s3 (-nostdinc/-nostdlib vs the §E sysroot), s4/R5 (-nostdinc -I $MB/include), gcc-4.0.4
(CPATH/LIBRARY_PATH/LIBGCC2_INCLUDES already at /usr/lib/musl-bedrock; its comment said
-I/usr/include and was stale). Dropping usr/include/** + usr/lib/{libc.a,*.o,*.a} from both
removes two contenders from the first-writer-wins header draw in every downstream sandbox.
binutils-2.30/2.41: headers = explicit bfd.h-class brace list (absent names match nothing).
s1: the mes-first -I comment overclaimed — mes ships its libc headers at the TOP level and only
9 names under /usr/include/mes/, so s1 is still draw-dependent; mesl_roll is the real mitigation.
Each narrowed pkg gets a build.sh RE-CAPTURE BUMP (outputs are not in the spec hash).
Spec-hash diff via minimal dump: arm64 0 changed; amd64 158 changed = everything above R4a
(expected: one cold amd64 round).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
hex0 (sha-pinned seed) -> hex1 -> kaem -> mes -> mescc -> tcc 0.9.26/0.9.27 -> musl 1.1.24 -> binutils 2.30 -> gcc 4.0.4 -> 4.7.4 -> 10.4.0 -> 15.2.0, with gmp/mpfr/mpc, linux-headers, binutils 2.41, musl 1.2.5 and the tcc/musl relink steps as intermediate rungs. Each package builds only with what the previous rung installed. amd64-only; the packages export empty collections on arm64.
…15.2.0-glibc Built by the top of the stage0 ladder and installed under versioned prefixes so they never collide with the distro toolchain. Binaries they produce are linked with an explicit dynamic linker and rpath into that prefix. gcc ships C and C++; each package carries a compile-and-run gate.
mrustc at a pinned upstream commit plus a patch series (aarch64 and shared-library fixes, each documented in its header) builds rustc 1.90.0 with cargo and std from the rustc-1.90.0 source tarball, fully offline, into /usr/lib/mrustc-rust-1.90.0. Functional gates compile and run programs covering generics, trait objects, unwinding, TLS, proc-macros and cargo.
Standard ./x.py build with bootstrap.toml [build] rustc/cargo pinned at the previous rung's install prefix, so the stage0 snapshot download never happens; network tools are stubbed to fail closed and vendored *-sys crates get empty .git markers. Each rung installs to /usr/lib/rustc-<version> and ships the same functional gate set. The directories differ only in versions and stage0 pointers.
…14 -> 1.22.6 -> 1.24.9 rungs go-1.4 (C-only root) is built with the glibc-hosted gcc; each later rung uses the previous one as GOROOT_BOOTSTRAP. packages/go bootstraps from go-1.24.9 on amd64 and from the sealed arm ladder artifact on arm64; the go.dev bindist Source is removed and a missing bootstrap is fatal. Version 1.26.6 -> 1.27.0, with source bridges in otel-collector and trivy for go 1.27 API removals.
bootstrap.toml [build] rustc/cargo point at the rustc-1.96.0 package's prefix; the seed tarball Sources and the download fallback are removed, the stage0 is asserted by --version before the build, and cargo runs with CARGO_NET_OFFLINE=true. On arm64 the stage0 is the sealed arm ladder artifact. Runtime deps and outputs are unchanged.
2f2f8bc to
336bba3
Compare
0chroma
left a comment
There was a problem hiding this comment.
Review: rust + go hex0-rooted bootstrap chains
Reviewed the full branch. CI is green (minimal-check and a full minimal build pass); note CodeRabbit skipped this PR entirely — 236 files exceed its 150-file limit — so this needs human eyes.
Verified correct
- Ladder consistency. Every
GOROOT_BOOTSTRAP/ stage0 prefix resolves to a package present in that file'sbuild_deps; no dependency cycles. Min-bootstrap versions line up: go1.27 needs ≥1.24.6, the 1.24.9 rung's ownminBootstrapis exactly its predecessor 1.22.6, earlier rungs still accept thego1.4default. - Hashes. Source shas recomputed against upstream for go 1.17.13/1.20.14/1.22.6/1.24.9/1.27.0, glibc-2.42, binutils 2.30/2.41/2.46, gcc 4.0.4/4.7.4/10.4.0/15.2.0, musl, gmp/mpfr/mpc, mes, tcc, linux-6.12.43 — all match. Arch prebuilt shas are pinned and match their URL path segments.
- Stage0 pinning.
--version/--print sysroot/src/version+src/stage0assertions abort on mismatch; stub PATH dirs are genuinely prepended with the curl/git shadowing asserted;CARGO_NET_OFFLINE=true; thevendor.rssed patch fails closed (grep before and after,exit 1). - Gates. Pass values are computed from guarded sums, never literals; each gated command is
rc-captured soset -ecan't short-circuit. - go-1.27 bridges. trivy 0.74.0 has exactly the two
json.SkipFuncsites the rewrite targets anderrors.ErrUnsupportedis the documented replacement; otel 0.159.0's manifest has areplaces:block and no swiss mention, and the pinned swiss pseudo-version carries the right build guard.
Findings
- Dead arm64 prebuilt branches —
glibc-bedrock-2.42/build.ncl,binutils-2.46-glibc/build.ncl,gcc-15.2.0-glibc/build.ncl: the innermatchsupplies an'Arm64prebuiltSource, but the outermatchcollapses arm64 to an emptyBuildSpec. Those Sources are never fetched and thebuild.shaarch64 blocks are unreachable. Harmless functionally (arm64 doesn't consume these), but the comments claiming "on aarch64 the prebuilt is extracted instead" are false. stage0-tcc-0.9.27-musl-s1/build.sh:38— on extract/cdfailure it copies/usr/bin/tcc-0.9.26to$OUTPUT_DIR/usr/bin/tcc-musland exits 0, so a failure mode installs a mislabeled binary that would be cached. Every other path in this PR fails shut; this one should too.- s1/s3 are retry-driven, not gated — they run under
set +ewith an env-layout perturbation loop (4–6 tries) and ship nostage0.answers. A first-try success is deterministic, but nothing pins that it happened. - Reproducibility seals are inert — most later rungs'
sha256sum -cgates are commented out /SEAL_FATAL=0,*.answersare# UNPINNED, and the six rustc rungs don't declare.answersas aLocaldep at all, so the seal check atrustc-1.95.0/build.sh:604is dead code. The PR body discloses pinning as a follow-up — this is just a request to track it somewhere concrete. packages/rustdiverges from the chain's own claims — unlike every rung it has no curl/wget/git stubs and no network tripwire, andbuild.nclstill declaresneeds = { dns, internet }, while the headline is "no recipe in the chain touches the network at build time." Either add the tripwire or state in the PR why the top-level package is deliberately exempt.- Comment drift —
rustc-1.94.1/build.ncl:3says its stage0 is "the rustc-1.94.1 package" (should be 1.93.1);binutils-2.46-glibc/build.ncl:3says "same sha as packages/binutils" but that package is now 2.47;glibc-bedrock-2.42/build.nclsimilarly vs glibc 2.44. - Nits — the "OutputBin's checker rejects the interpreter" rationale is inaccurate (
OutputBinonly special-cases shebang scripts, never ELF interpreters); thefind ./*/ -deleteclean-state blocks are safe only because everySourceisextract=false; a few import identifiers don't match package names (stage0-tcc-r2,stage0-cc,stage0-binutils-r10, …).
The ladder machinery is solid and the central claims hold. Findings 1–2 are quick fixes and 3–5 are worth addressing or explicitly waiving before this lands. Not blocking on my side, but I didn't want it to merge on a green CI + bot-skip alone.
|
Thanks for the careful read. Fixes for 1, 2, 4, 5, 6 and 7 are in b638f0a; 3 and part of 4 are waived below with the reasoning.
Note for the merge: the s1 and |
…t offline tripwire, seal answers declared, comment drift, package-name imports - stage0-tcc-0.9.27-musl-s1: an extract failure exits 1 instead of shipping tcc-0.9.26 as tcc-musl - glibc-bedrock-2.42 / binutils-2.46-glibc / gcc-15.2.0-glibc: the arm64 Source arm and the aarch64 build.sh block were unreachable (the outer match makes arm64 an empty spec); removed - rust: the rungs' curl/wget/git stub harness and NETWORK-TRIPWIRE check; `needs` dropped - rustc-1.91.1..1.96.0: the .answers file is a declared Local input, so the seal check can read it - comments: rustc-1.94.1's stage0 is 1.93.1; the -glibc trio no longer claims parity with the production binutils/glibc versions; OutputData rationale for the binutils programs - stage0 imports named after their packages instead of ladder-rung labels Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… so build.rs never calls git submodule The tripwire added in the previous commit fired on `git submodule update --init curl` from the vendored curl-sys build.rs: the rungs pre-empt that call with an empty .git marker in the bundled submodule dir. Same block, same rationale. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Follow-up 318d00c: the new |
The build failed on both arches in seconds:
error: rustc 1.97.1 is not supported by the following packages:
atuin@18.22.0 requires rustc 1.98.0
packages/rust is on 1.97.1; latest stable is 1.98.1. Bumping the Rust
toolchain rotates spec hashes for the 121 packages that import rust or go, and
packages/rust/build.ncl is also rewritten by the in-flight hex0 bootstrap work
(#667), so that bump wants to be a deliberate, scheduled change rather than a
side effect of a routine version sweep.
Dropping this one package lets the other six updates in this stack land. atuin
comes back with the Rust bump.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ess from it The builder ORs `needs` over a package's dependencies; the Rust programs that depend on rust fetch their crates during their own builds and were getting network through this flag. rust's own build stays offline: build.sh stubs curl/wget/git and fails on any attempt (NETWORK-TRIPWIRE). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
32d7df3 restores |
…0; rust stays 1.97.1, the attested chain's top)
…l still the 1.96.0 bundle)
…nfig_library (as packages/rust already does)
…ude-code bump)
- packages/go/build.ncl: keep main's hex0-bootstrapped, source-built shape (#667); bump it to 1.27.1 with the 1.27.1 source sha256 (verified against go.dev's published checksum and by hashing the tarball). The branch's prebuilt amd64 url/sha is obsolete under #667. - packages/otel-collector/build.sh: take main's Go-1.27 swiss pin; drop the branch's duplicate (main's guard exits if swiss is already pinned). - packages/trivy/build.sh (semantic conflict git didn't flag): keep this branch's upstream json/v2 patch (trivy dc3c56eed5, also handles json:",inline") and drop #667's sed SkipFunc bridge, which deliberately exits 1 when no json.SkipFunc is left, i.e. after the patch has run. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
croc >= 11.5.2 declares go 1.27.0; this branch last built against go 1.26 and failed. Main is now on go 1.27.0 (hex0-bootstrapped, #667), so the bump no longer waits on #758. No conflicts; vs main the branch still changes only packages/croc/build.ncl. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ak each other (gominimal#671) * fix(pnpm): depend on node, not node-lts — two npms in one sandbox breaks both pnpm only needs *a* node for its `#!/usr/bin/env node` shebang, but whichever one it names enters the closure of every package built with pnpm. `next` and `agent-browser` both declare `node` themselves, so each sandbox held TWO npm installs at the same paths. The sandbox hardlinks closure members first-writer-wins PER FILE, so /usr/lib/node_modules/npm came out a blend: minipass-flush/index.js from npm 11.17.0 (named `{ Minipass }` import) beside a nested minipass@3.3.6 from npm 11.11.1 (default export only). That tree never existed upstream and cannot load — `class Flush extends undefined` throws and every `npm install` dies. It broke `next` for two days and blocked gominimal#665, gominimal#667, gominimal#669 and gominimal#659. Verified: closure of next 75->74 and agent-browser 114->113 with node-lts gone, capy (the only other node-lts consumer) untouched; next, pnpm and agent-browser each build --rebuild clean and pass min check 15/15. Supersedes gominimal#670, whose fix was a no-op against node-lts's own output. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * refine: take only the node BINARY, not the whole package Review point from Bryan: pnpm should not be dictating a node version to its consumers at all. The spec language cannot express that today — RuntimeDep is BuildSpec | Subset | UpstreamPkg, all concrete, with no "consumer provides it" form — but `subsetOf` gets most of the way there. pnpm needs a node to interpret `#!/usr/bin/env node` and nothing else. Taking `subsetOf node ["node"]` instead of the whole package means pnpm can never contribute an npm tree to any closure, so the two-npms-merged-per-file failure is structurally impossible rather than merely absent from today's fleet. Residual, and worth stating: pnpm still names a version, so a future node-lts consumer adding pnpm would collide on the `node` binary. That is a much smaller failure than an unloadable module graph, and the real fix is a virtual/provided dependency in the spec language. Verified with the subset: next, pnpm and agent-browser all build --rebuild clean and pass min check, including pnpm's `missing runtime_deps` — which independently confirms the bare binary satisfies the shebang. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
* Update age to 1.3.2
* Update ast-grep to 0.45.3
* Update atuin to 18.22.0
* Update bash-completions to 2.18.0
* Update bash-language-server to 5.8.0
* Update bzip3 to 1.5.4
* Update chezmoi to 2.72.2
* Hold atuin at 18.19.0: 18.22.0 needs rustc 1.98.0, we ship 1.97.1
The build failed on both arches in seconds:
error: rustc 1.97.1 is not supported by the following packages:
atuin@18.22.0 requires rustc 1.98.0
packages/rust is on 1.97.1; latest stable is 1.98.1. Bumping the Rust
toolchain rotates spec hashes for the 121 packages that import rust or go, and
packages/rust/build.ncl is also rewritten by the in-flight hex0 bootstrap work
(gominimal#667), so that bump wants to be a deliberate, scheduled change rather than a
side effect of a routine version sweep.
Dropping this one package lets the other six updates in this stack land. atuin
comes back with the Rust bump.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: gominimal-pkgmgr-mgr[bot] <285843623+gominimal-pkgmgr-mgr[bot]@users.noreply.github.com>
Co-authored-by: bryan <bryan@minimal.dev>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Mirrors gominimal#727's go 1.26.6 -> 1.26.8. Both bumps exist for the same reason: the routine package sweeps have started landing upstream releases whose toolchain floor is above what we ship. pkgs#725 failed on error: rustc 1.97.1 is not supported by the following packages: atuin@18.22.0 requires rustc 1.98.0 atuin is held at 18.19.0 on that branch until this lands. 1.98.1 is current stable and one patch above atuin's floor. Source tarball mirrored to gs://minimal-staging-archives/rustc-1.98.1-src.tar.xz: downloaded from static.rust-lang.org, sha256 verified against the upstream .sha256 file (be1816e7...), uploaded, then re-read back out of the bucket and re-hashed to confirm the round trip. That matches the existing convention — the mirrored 1.97.1 object hashes to exactly the sha256 upstream publishes. Only the version and source hash change. pins with no version, and carries no version references, so nothing else in the recipe moves. Note for scheduling: this rotates spec hashes for the packages that import rust, and packages/rust/build.ncl is also rewritten by the hex0 bootstrap work in gominimal#667 — expect a conflict there whichever lands second. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…al#734) Every cold bun build on res-server-arm64 (c4a-standard-72) stalls at the same line — 'zig obj -> bun-zig.{0..71}.o' — and sits there with zero cache writes until the 6h watchdog kills the run. Three sandboxes, 2026-09-19/20/21, two of them on gominimal#667 (which rotates bun's spec hash via rust). amd64 with 144 shards completes in ~4 min. The fast arm64 'successes' in the run history are cache hydrations, not compiles. bun's local profile sets -Dllvm_codegen_threads=availableParallelism() (scripts/build/zig.ts codegenThreads); upstream CI never exceeds 8 shards and shipped releases use 1. Pin arm64 to 8 with the same sed+verify-grep pattern as the lol-html patch (gominimal#228). This PR's own build is the experiment: a cold arm64 bun build either completes, or hangs again and we capture the process tree live. Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…ea, openjdk-9..25) (gominimal#775) * jvm: bootstrap OpenJDK from source (jikes/jamvm/classpath root, icedtea, openjdk-9..25) Clean re-cut of bryan/jvm-ladder onto main d0b0026: only the ladder package directories, none of the stale pre-gominimal#667 chain that branch carried. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * jvm: the base packages the ladder imports (zip, fastjar, which, ant-bootstrap, giflib, libICE/libSM/libXt) The clean re-cut carried only the rung directories; these eight are imported by classpath, ecj4-bootstrap, icedtea and the openjdk rungs and were left on the test branch. Sources are all mirrored in the staging bucket. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * which: keep main's 2.25 (the ladder only needs the package, not its 2.21 copy) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * jvm: nickel format Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * jvm: import aliases named after their folders minimal's imports checker requires a bare-word import alias to equal the folder it imports; dashed aliases follow the ghc-9-6-7 convention (dots become dashes). Variable references only; record keys and strings are unchanged. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * jvm rungs: pkgmgr freeze marker Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * giflib, fastjar: build in the sandbox giflib: build the library targets only; `all` also builds the utilities and runs doc/ through ImageMagick's convert, which the sandbox does not have. fastjar: the bundled 2008 config.guess/config.sub predate aarch64, so the modern GNU pair comes in as Sources (as libtecla does); zlib was an undeclared dependency. Both verified with a bare PATH on amd64 and arm64 lab VMs. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * jvm ladder: re-run the buildbot Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * jvm ladder: re-run the buildbot with the upload retry deployed Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * zip: bzip2 is a build and runtime dependency unix/configure finds bzlib.h (bzip2 rides in through base at build time) and links -lbz2, so the binary needs libbz2.so.1.0 wherever it runs; classpath-0.93's sandbox had no bzip2 and `zip -r glibj.zip` failed to load. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * jvm rungs: declare runtime_deps None of the rungs declared any. The lab VM is one filesystem, the sandbox is not: icedtea-7's configure ran classpath-devel's javah wrapper, which execs /usr/lib/jamvm-1.5.1/bin/jamvm, in a closure without jamvm-1.5.1. Each rung now names what its installed files exec or load: the VMs their class library and libz (libffi for jamvm-2.0.0), the Classpath tool wrappers and ecj javac wrappers their VM and class library, the JDKs libz. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * jvm rungs: sysroot link flags before the caller's arguments OpenJDK's freetype_versioncheck link line carries its own -Wl,-rpath,/usr/lib; with the wrapper's flags appended after it, /usr/lib came first in RPATH and the sysroot's ld.so loaded the system libc.so.6 (symbol lookup error: __pointer_chk_guard, GLIBC_PRIVATE). The lab VM has no /usr/lib/libc.so.6, so it never showed. The wrapper now puts its -L/-B/--dynamic-linker/-rpath flags ahead of the arguments. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * mrustc: restore main's build.sh (touched by the wrapper reorder glob by mistake) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * icedtea, openjdk rungs: compile C as gnu17 gcc 15 defaults to C23, where hotspot's serviceability agent (`typedef int bool;` in agent/src/os/linux/libproc.h) no longer compiles; the lab's gcc 14 defaulted to gnu17. The Classpath and jamvm-2.0.0 rungs already pinned it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * icedtea-8, openjdk rungs: rename hotspot's uabs glibc 2.42's <stdlib.h> declares `unsigned int uabs(int)`; hotspot's inline overloads of the same name (utilities/globalDefinitions.hpp) then fail to compile against the bedrock sysroot. Rename hotspot's to hs_uabs after unpacking; the openjdk rungs apply the same rename conditionally, as a no-op where their hotspot has none. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * openjdk-23..25: the uabs rename too (these rungs apply no patches, so the anchor differs) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * openjdk rungs: gnu17 and a warning demotion in the JDK's own CFLAGS The wrapper's -std=gnu17 does not survive the JDK's flag handling for libnet's gio shims (K&R `()` prototypes, "too many arguments" under gcc 15's C23), so it goes into --with-extra-cflags, which the JDK appends last. jtreg's libTestJNI.c trips gcc 14's incompatible-pointer-types error; it is a warning again. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * openjdk rungs: --with-build-user=minimal The sandbox runs as a uid with no passwd entry, so `whoami` fails; JDK 21+'s configure refuses an empty build user ("Value cannot be empty"). Naming it also keeps the recorded build user identical between the lab and the sandbox. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * openjdk-24, 25: make images, not all JDK 24 added a static-launcher target to `all`; it links the launcher statically and fails against the versioned sysroot. The rung ships the jdk image only. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * jdk rungs: runtime_deps from an audit of the installed trees bin/runtime-deps-audit.py (minimermetic) walks every ELF's DT_NEEDED/PT_INTERP and every script's exec targets and resolves them against the declared runtime closure. On the lab rehearsal trees the JDK images load the X libraries, alsa, fontconfig, lcms2, freetype, libpng, giflib and libjpeg from AWT, sound, font and image code; jikes' interpreter is the sysroot's ld.so. All were build deps only. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * openjdk-15..22: libawt_xawt loads libXcursor too (audit) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * jdk rungs: address CR review (BUILDINFO newline, dead flags/deps, orphan patches) - openjdk-9..25: BUILDINFO heredoc wrote a literal "\n" between the source and boot fields; split it onto its own line. - jamvm-1.5.1: drop --enable-runtime-reloc. 1.5.1's configure.ac only defines runtime-reloc-checks and its autoconf-2.61 configure ignores unknown options silently, so the flag never did anything (JVMFLAGS passes -Xnoinlining, so reloc mode is moot anyway). - openjdk-23..25: drop the libxcursor build dep; these rungs do not apply the xcursor-no-dynamic patch, so nothing links it. - openjdk-15/16: remove three classlist patches build.ncl never applies. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * jvm ladder: drop duplicate gawk/diffutils deps; trim jikes narration - all 17 openjdk rungs listed gawk and diffutils twice in build_deps. - jikes-1.22: replace the lab-notebook banner and private-infra references with the classpath-0.93-style header. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * openjdk rungs: stop re-setting SOURCE_DATE_EPOCH 9-14: the export was a no-op (nothing under make/ in 12/13/14 reads it), so drop it. 15-25: pass configure's own --with-source-date=315532802 (jmod rejects the sandbox's pre-1980 0) instead of overriding the sandbox variable, the nspr pattern pkgs' CLAUDE.md asks for. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * jikes-1.22: report why the bedrock gcc does not run Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * jikes-1.22: run the bedrock toolchain against the sysroot's libc The B5 gcc and B4 binutils have no RUNPATH; their loader is the sysroot's ld.so, which searches /usr/lib and found production glibc 2.44 there (symbol lookup error: __pointer_chk_guard, GLIBC_PRIVATE). Wrap every executable that loads through that ld.so with LD_LIBRARY_PATH=$SR/lib and put the wrappers first on PATH. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * jikes-1.22: no trace for the wrapper scan; list the wrapped tools Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * jikes-1.22: print config.log's tail when configure fails Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * jikes-1.22: print the failing compiler test from config.log Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * jikes-1.22: assemble and link with production binutils The sealed binutils-2.46-glibc and production binutils 2.47 both put libsframe.so.3 in /usr/lib; whichever wins, as from one loads the other's library and aborts (stack smashing). Production binutils is consistent with the production glibc it runs on; the bedrock gcc keeps its sysroot-libc wrapper and still links against the 2.42 sysroot. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * jikes-1.22: production as and ld run without the sysroot library path The bedrock gcc wrapper exports LD_LIBRARY_PATH for gcc and its cc1; the production as it spawned inherited it, loaded the 2.42 libc and aborted. Give as/ld wrappers that unset it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * jikes-1.22: point the bedrock gcc drivers at the wrapped as/ld with -B gcc looks for as in its own tool dirs before PATH and found an unwrapped copy, which inherited the sysroot library path and aborted. -B is searched first, for the driver and for collect2. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * jikes-1.22: on configure failure, report which as gcc runs and how each loads Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * jikes-1.22: bind the sysroot libc per process, not through the environment LD_LIBRARY_PATH leaked from the bedrock gcc into the production /bin/sh and as it ran, which then aborted on the 2.42 libc. Start each bedrock program (drivers, cc1, cc1plus, collect2, lto1) through the sysroot's ld.so with --library-path; the drivers find the wrapped internals via -B. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * jvm ladder: run the bedrock gcc against its sysroot libc, link with production binutils On main the amd64 bedrock roots are sealed tarballs and /usr/lib holds production glibc 2.44. The B5 gcc has no RUNPATH, so its 2.42 loader picked up the 2.44 libc and nothing ran. Every rung now starts each bedrock program through the sysroot's ld.so with --library-path (per process, so the production as, ld and /bin/sh it runs keep their own libc), and assembles and links with production binutils 2.47 instead of the sealed 2.46, whose libsframe.so.3 collides with 2.47's in /usr/lib. Proven on jikes-1.22 in the sandbox. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
rust + go: bootstrap both toolchains from source, starting at hex0
packages/rustandpackages/gocurrently start from a downloaded binary compiler (rust's stage0 snapshot from static.rust-lang.org, go's bootstrap toolchain from go.dev). This PR replaces both with chains of in-tree packages that begin at the 229-bytehex0seed and end at the compilersrustandgobuild with today. No recipe in the chain touches the network at build time.What is in the PR
38 new packages, 4 modified. They form four ladders plus two flips.
stage0-*, amd64):hex0 → hex1 → kaem → mes → mescc → tcc 0.9.26 → tcc 0.9.27 → musl 1.1.24 → binutils 2.30 → gcc 4.0.4 → gcc 4.7.4 → gcc 10.4.0 → gcc 15.2.0, withgmp-mpfr-mpc,linux-headers,binutils-2.41,musl-1.2.5and three tcc/musl relink steps (-s1/-s3/-s4) as the intermediate rungs. Each package builds only with what the previous rung installed. The early rungs arekaemscripts (*.kaem), the rest arebuild.sh.glibc-bedrock-2.42,binutils-2.46-glibc,gcc-15.2.0-glibc(C and C++). Built by the top of the stage0 ladder, installed under versioned prefixes (/usr/lib/glibc-bedrock-2.42, …) so they never collide with the distro toolchain. Every binary they produce is linked with an explicit dynamic linker and rpath into that prefix.mrustc(pinned upstream commit plus a patch series for aarch64 and shared-library builds, each patch documented in its header) buildsmrustc-rustc-1.90.0(rustc 1.90.0 + cargo + std). From thererustc-1.91.1 → 1.92.0 → 1.93.1 → 1.94.1 → 1.95.0 → 1.96.0, each rung a standard./x.py buildwhose stage0 is the previous rung's install prefix. Each rung installs to/usr/lib/rustc-<version>and ships a functional gate (compile and run a program that exercises generics, trait objects, unwinding, TLS, proc-macros and cargo; the pass value is computed, never a literal).go-1.4(C-only root, built with the glibc-hosted gcc)→ go-1.17.13 → go-1.20.14 → go-1.22.6 → go-1.24.9, each using the previous rung asGOROOT_BOOTSTRAP.packages/rust: stage0 is now therustc-1.96.0rung (bootstrap.toml [build] rustc/cargopoint at its prefix, so x.py skips the snapshot download); the seed tarball Sources and the download fallback are gone, the stage0 is asserted by--versionbefore the build starts, and cargo runs withCARGO_NET_OFFLINE=true. Runtime deps and outputs are unchanged.packages/go: bootstraps fromgo-1.24.9on amd64 and from the sealed arm ladder artifact on arm64; the go.dev bindist Source is gone and a missing bootstrap is fatal. Version moves 1.26.6 → 1.27.0, which needed two small source bridges inotel-collectorandtrivyfor go 1.27 API removals.hex0is the single binary trust root: a sha-pinned Source (amd64 seed and the sealed aarch64 seed).How to review it efficiently
rustc-1.93.1,go-1.20.14,stage0-musl-1.1.24) anddiff -rit against its siblings; the diffs are a few lines each.packages/rustc-*/build.sh(and, for stage0 pinning,packages/rust/build.sh): (a) stage0 pinning viabootstrap.toml, asserted at start by--versionand--print sysrootagainst the expected prefix; (b) the rungs' offline harness: network tools on PATH replaced by stubs that exit non-zero,CARGO_NET_OFFLINE=true, and empty.gitmarkers inside vendored*-syscrates so theirbuild.rsnever runsgit submodule update.OutputDataglob). Ladder packages that legitimately ship ELF files as data (loaders, crt objects, musl's emptycrti.o) useallow_executable/allow_dataexplicitly.rustandgoon arm64 consume the sealed arm-ladder artifacts as pinned Sources; the arm64 rust rungs above 1.90 are not built from source yet and are the next tranche.Build cost
Ladder rungs take minutes each;
mrustc-rustc-1.90.0about an hour; each rustc rung 30 to 60 minutes;rustandgoabout an hour each. Cold, the whole chain is roughly a day of sequential build time; with a warm artifact cache only changed links rebuild. Byte-seal.answersfiles are present but unpinned; pinning is a data-only follow-up once each rung has two identical cold builds.Follow-ups (not in this PR)
attrsmetadata (license_spdx,upstream_version) for the stage0 and rung packages.-s1/-s3/-s4inputs as pristine source plus patch files instead of prepared tarballs.