Invariant being violated
After bootstrap the seed must depend on nothing external from LLVM. We build the entire static LLVM/Clang/lld SDK ourselves (tools/build-static-llvm.sh), and the release binary embeds those static resources — libclang is statically linked, the stdlib and runtime objects are embedded. A clean release host has no LLVM at all (not in /usr, not in .deps), and a system LLVM is never trusted (we didn't build it; it won't have the static .a/resources we need). See AGENTS.md → Self-Contained Toolchain and docs/with-bootstrap-runbook.md → Failure Policy.
c_import violates this: several runtime paths reach for an external toolchain. They happen to succeed on a dev box that has LLVM installed, which is exactly why this stayed hidden until a clean Linux release host failed with 'stddef.h' file not found.
Bug 1 (core) — get_clang_resource_dir() should not exist in this form
rt/clang_bridge.w:709 resolves clang's builtin-header resource dir (stddef.h, stdarg.h, stdint.h, …) entirely from external locations at runtime:
WITH_CLANG_RESOURCE_DIR env (:712)
LLVM_PREFIX env → <prefix>/lib/clang (:716)
find_clang_resource_dir_from_llvm_config() → shells out to llvm-config --libdir (:697) — a system tool we didn't build
/usr/local/llvm/lib/clang (:726) — a system path
find_clang_resource_dir_under() (:666) scans an external dir for the <v> subdir
These builtin headers are produced by our own SDK build at $LLVM_PREFIX/lib/clang/<v>/include, but the build never embeds them, so the runtime has no choice but to hunt externally. The function's existence is the bug.
Consumed at 4 sites that pass -resource-dir <external> to clang_parseTranslationUnit: rt/clang_bridge.w:1221, :2226, :2504, :2592.
Fix: embed lib/clang/<v>/include/ into the binary the same way the stdlib is embedded (build/runtime.w → EmbeddedStdlibData.w) — generate a raw-string data module + lookup, or incbin a tarball via .EmbedObjectFiles. At first c_import, materialize to a versioned cache dir (e.g. ~/.cache/with/clang-resource/<llvm-ver>/) and point -resource-dir there. Delete the env/llvm-config//usr/local/llvm probes, or demote them to an explicit override-only last resort (never the default). The build should fail loudly if the resource headers aren't present to embed.
Symptom / regression context: the v0.14.6 Linux FFI test (spec_ss16_1_ffi_direct_call) only passed because I set WITH_CLANG_RESOURCE_DIR to the host's .deps LLVM — i.e. the test validated against an external resource, masking that c_import is not self-contained on a bare host.
Related runtime-external-toolchain gaps (same theme, different resource — triage separately)
These are not the LLVM static resources we build, so they may have different resolutions, but they're the same class of "reaches outside the binary at runtime":
- Bug 2 —
get_sdk_path() shells out to xcrun --show-sdk-path (rt/clang_bridge.w:650) for the macOS platform sysroot. This is the platform's libc headers (e.g. stdio.h itself), inherently the user's system when importing them — but the runtime shell-out to Xcode tooling is fragile and fails on a host without Xcode. Decide: pin/cache vs accept as a platform requirement.
- Bug 3 — macro extraction shells out to
cc (rt/clang_bridge.w:2282, :2435: cc -E -dM …) to evaluate object-like macros during c_import, instead of going through the embedded libclang. External C-compiler dependency at runtime; fails on a clean host with no cc.
Acceptance
- A release binary on a host with no LLVM/Clang/
cc/llvm-config/Xcode-resource-dir installed can use c_import("stdio.h") and build, using only resources embedded at build time.
- No runtime filesystem probe for an LLVM/Clang resource dir, archive, or
llvm-config.
spec_ss16_1_ffi_direct_call passes on the Linux release host without WITH_CLANG_RESOURCE_DIR set.
Invariant being violated
After bootstrap the seed must depend on nothing external from LLVM. We build the entire static LLVM/Clang/lld SDK ourselves (
tools/build-static-llvm.sh), and the release binary embeds those static resources — libclang is statically linked, the stdlib and runtime objects are embedded. A clean release host has no LLVM at all (not in/usr, not in.deps), and a system LLVM is never trusted (we didn't build it; it won't have the static.a/resources we need). See AGENTS.md → Self-Contained Toolchain anddocs/with-bootstrap-runbook.md→ Failure Policy.c_importviolates this: several runtime paths reach for an external toolchain. They happen to succeed on a dev box that has LLVM installed, which is exactly why this stayed hidden until a clean Linux release host failed with'stddef.h' file not found.Bug 1 (core) —
get_clang_resource_dir()should not exist in this formrt/clang_bridge.w:709resolves clang's builtin-header resource dir (stddef.h,stdarg.h,stdint.h, …) entirely from external locations at runtime:WITH_CLANG_RESOURCE_DIRenv (:712)LLVM_PREFIXenv →<prefix>/lib/clang(:716)find_clang_resource_dir_from_llvm_config()→ shells out tollvm-config --libdir(:697) — a system tool we didn't build/usr/local/llvm/lib/clang(:726) — a system pathfind_clang_resource_dir_under()(:666) scans an external dir for the<v>subdirThese builtin headers are produced by our own SDK build at
$LLVM_PREFIX/lib/clang/<v>/include, but the build never embeds them, so the runtime has no choice but to hunt externally. The function's existence is the bug.Consumed at 4 sites that pass
-resource-dir <external>toclang_parseTranslationUnit:rt/clang_bridge.w:1221,:2226,:2504,:2592.Fix: embed
lib/clang/<v>/include/into the binary the same way the stdlib is embedded (build/runtime.w→EmbeddedStdlibData.w) — generate a raw-string data module + lookup, or incbin a tarball via.EmbedObjectFiles. At firstc_import, materialize to a versioned cache dir (e.g.~/.cache/with/clang-resource/<llvm-ver>/) and point-resource-dirthere. Delete the env/llvm-config//usr/local/llvmprobes, or demote them to an explicit override-only last resort (never the default). The build should fail loudly if the resource headers aren't present to embed.Symptom / regression context: the v0.14.6 Linux FFI test (
spec_ss16_1_ffi_direct_call) only passed because I setWITH_CLANG_RESOURCE_DIRto the host's.depsLLVM — i.e. the test validated against an external resource, masking thatc_importis not self-contained on a bare host.Related runtime-external-toolchain gaps (same theme, different resource — triage separately)
These are not the LLVM static resources we build, so they may have different resolutions, but they're the same class of "reaches outside the binary at runtime":
get_sdk_path()shells out toxcrun --show-sdk-path(rt/clang_bridge.w:650) for the macOS platform sysroot. This is the platform's libc headers (e.g.stdio.hitself), inherently the user's system when importing them — but the runtime shell-out to Xcode tooling is fragile and fails on a host without Xcode. Decide: pin/cache vs accept as a platform requirement.cc(rt/clang_bridge.w:2282,:2435:cc -E -dM …) to evaluate object-like macros duringc_import, instead of going through the embedded libclang. External C-compiler dependency at runtime; fails on a clean host with nocc.Acceptance
cc/llvm-config/Xcode-resource-dir installed canuse c_import("stdio.h")and build, using only resources embedded at build time.llvm-config.spec_ss16_1_ffi_direct_callpasses on the Linux release host withoutWITH_CLANG_RESOURCE_DIRset.