Problem
A release build links the next compiler against the static SDK at
.deps/llvm-<ver>-<host>/lib/libclang.a (+ libLLVM*.a, liblld*.a).
build/compiler.w:7 pins COMPILER_LLVM_VERSION = "22.1.6"; comp_llvm_prefix()
(build/compiler.w:116-129) defaults to .deps/llvm-<ver>-<host>; the link
fails loudly if the static archive is absent (build/compiler.w:368).
The only way to populate .deps/llvm-<ver>-<host> is
tools/build-static-llvm.sh — a from-source LLVM build (≈ an hour). There is
no fetch for a prebuilt SDK, and nothing publishes one. Compare the seed,
which does have a download path (make seed / build :seed /
run_seed_download_action in build/seed.w).
Consequence: our own rule "a release reuses the already-built static SDK, never
rebuilds it, never trusts a system LLVM" (see docs/with-release-runbook.md →
Toolchain, docs/with-bootstrap-runbook.md → Failure Policy, AGENTS.md →
Self-Contained Toolchain) only holds on a host that already ran bootstrap
from source. On a clean host the only options left are "rebuild LLVM from
source" (bootstrap-only) or "point at a system LLVM" (forbidden — we didn't
build it and it won't have the static .a anyway). The toolchain is therefore
not actually self-contained at build time.
Decision
Publish the heavy static LLVM/Clang/lld SDK as a per-platform release asset, and
add a pinned fetch so with build obtains it the same way it obtains the seed.
Proposed mechanism
- Package script (e.g.
scripts/package-llvm-sdk.sh, run per platform):
tar+zstd the essentials of .deps/llvm-<ver>-<host> into
with-llvm-sdk-<ver>-<platform>.tar.zst:
- Publish it on each release, per platform (asset names beside the existing
with-<platform> binaries).
- Fetch target
make deps / with build :deps, mirroring
run_seed_download_action: if .deps/llvm-<ver>-<host> is absent, download
with-llvm-sdk-<COMPILER_LLVM_VERSION>-<host>.tar.zst from the matching
release and extract it. The compiler/link targets depend on it; the existing
"missing static libclang archive" failure should point at make deps.
The SDK only changes when COMPILER_LLVM_VERSION bumps, so the bytes are
identical across patch releases of the same LLVM version. Publishing it on every
release keeps each release self-describing (the maintainer's stated preference);
keying the fetch by COMPILER_LLVM_VERSION lets a release reuse a prior
release's SDK asset if we ever choose to dedupe. Either way the fetch is by
pinned version, never "latest" and never the system.
Relationship to #312
Sibling self-containment gaps, different layers:
Together they make the toolchain self-contained end to end. (The packaged
lib/clang/<v>/include/ here is the same tree #312 embeds.)
Acceptance
A clean checkout on a supported platform, with no system LLVM and no
pre-existing .deps, can run make deps && make build && make fixpoint using
only the pinned, published SDK — no from-source LLVM build, no system LLVM.
Problem
A release build links the next compiler against the static SDK at
.deps/llvm-<ver>-<host>/lib/libclang.a(+libLLVM*.a,liblld*.a).build/compiler.w:7pinsCOMPILER_LLVM_VERSION = "22.1.6";comp_llvm_prefix()(
build/compiler.w:116-129) defaults to.deps/llvm-<ver>-<host>; the linkfails loudly if the static archive is absent (
build/compiler.w:368).The only way to populate
.deps/llvm-<ver>-<host>istools/build-static-llvm.sh— a from-source LLVM build (≈ an hour). There isno fetch for a prebuilt SDK, and nothing publishes one. Compare the seed,
which does have a download path (
make seed/build :seed/run_seed_download_actioninbuild/seed.w).Consequence: our own rule "a release reuses the already-built static SDK, never
rebuilds it, never trusts a system LLVM" (see
docs/with-release-runbook.md→Toolchain,
docs/with-bootstrap-runbook.md→ Failure Policy, AGENTS.md →Self-Contained Toolchain) only holds on a host that already ran bootstrap
from source. On a clean host the only options left are "rebuild LLVM from
source" (bootstrap-only) or "point at a system LLVM" (forbidden — we didn't
build it and it won't have the static
.aanyway). The toolchain is thereforenot actually self-contained at build time.
Decision
Publish the heavy static LLVM/Clang/lld SDK as a per-platform release asset, and
add a pinned fetch so
with buildobtains it the same way it obtains the seed.Proposed mechanism
scripts/package-llvm-sdk.sh, run per platform):tar+zstd the essentials of
.deps/llvm-<ver>-<host>intowith-llvm-sdk-<ver>-<platform>.tar.zst:lib/libclang.a,lib/libLLVM*.a,lib/liblld*.alib/clang/<v>/include/(clang builtin headers — also the embed source for c_import is not self-contained: resolves clang resource dir (and other toolchain bits) from an external LLVM at runtime #312)bin/ld.lld/bin/ld64.lld,bin/llvm-nmwith-<platform>binaries).make deps/with build :deps, mirroringrun_seed_download_action: if.deps/llvm-<ver>-<host>is absent, downloadwith-llvm-sdk-<COMPILER_LLVM_VERSION>-<host>.tar.zstfrom the matchingrelease and extract it. The compiler/link targets depend on it; the existing
"missing static libclang archive" failure should point at
make deps.The SDK only changes when
COMPILER_LLVM_VERSIONbumps, so the bytes areidentical across patch releases of the same LLVM version. Publishing it on every
release keeps each release self-describing (the maintainer's stated preference);
keying the fetch by
COMPILER_LLVM_VERSIONlets a release reuse a priorrelease's SDK asset if we ever choose to dedupe. Either way the fetch is by
pinned version, never "latest" and never the system.
Relationship to #312
Sibling self-containment gaps, different layers:
compiler must be fetchable/pinned, not rebuilt and not system.
from inside itself (embedded), not from an external resource dir.
Together they make the toolchain self-contained end to end. (The packaged
lib/clang/<v>/include/here is the same tree #312 embeds.)Acceptance
A clean checkout on a supported platform, with no system LLVM and no
pre-existing
.deps, can runmake deps && make build && make fixpointusingonly the pinned, published SDK — no from-source LLVM build, no system LLVM.