kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

commit 3938a2976de2f2ce3dd46fbf64a4b59ee355805c
parent 10d51e050c4a32261df88a66fdf4b45df33c3740
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Wed, 10 Jun 2026 15:02:07 -0700

feat(port): all selfhost paths bootstrap from a cross-compiled seed

There is no point building stage1 with clang inside the target environment
(and for an emulated arch that clang runs emulated, slowly). Every linux and
freebsd selfhost target now cross-compiles its stage1 seed on the host (clang,
independent of kit) and runs only kit's stages 2/3 in the container/VM:

- selfhost.sh: linux and freebsd branches build the seed via kit_cross.sh
  <target> --cc=clang and pass it through (generalizes the rv64-only seed to
  all arches).
- freebsd_bootstrap.sh: KIT_FREEBSD_BOOT_SEED ships the seed into the VM and
  feeds it to mk/bootstrap.mk's BOOTSTRAP_SEED, so clang is never run in the VM.

windows already cross-builds kit.exe on the host; macos bootstraps natively on
the host (no foreign environment). Validated: freebsd-aa64 seeded debug
bootstrap is byte-identical (stage2 == stage3, sha 214d14a4…).

Doc: PORT.md self-host shapes already describe the seed model.

Diffstat:
Mscripts/freebsd_bootstrap.sh | 33+++++++++++++++++++++++++++++++--
Mscripts/selfhost.sh | 18+++++++++++-------
2 files changed, 42 insertions(+), 9 deletions(-)

diff --git a/scripts/freebsd_bootstrap.sh b/scripts/freebsd_bootstrap.sh @@ -18,6 +18,12 @@ # Env overrides: # KIT_FREEBSD_VM_KEEP_UP=1 leave the VM running after the build # KIT_FREEBSD_BOOT_TOY=1 also run the Toy corpus through the stage3 compiler +# KIT_FREEBSD_BOOT_SEED repo-relative path to a pre-built stage1 kit. When +# set, stage1 is this host-cross-compiled seed +# instead of an in-VM clang build (so clang is never +# exercised in the VM); only kit's stages 2/3 run +# there. Build one with: +# scripts/kit_cross.sh freebsd-<arch> --cc=clang set -eu @@ -40,8 +46,23 @@ esac KEEP_UP="${KIT_FREEBSD_VM_KEEP_UP:-0}" TOY="${KIT_FREEBSD_BOOT_TOY:-0}" +SEED="${KIT_FREEBSD_BOOT_SEED:-}" BUILD_DIR="build/freebsd-boot/$ARCH" +if [ -n "$SEED" ]; then + [ -x "$ROOT/$SEED" ] || { echo "freebsd_bootstrap: seed not found/executable: $ROOT/$SEED (build with scripts/kit_cross.sh freebsd-$ARCH --cc=clang)" >&2; exit 2; } +fi + +# Hybrid (seeded) vs in-VM clang stage1. A seed feeds mk/bootstrap.mk a +# host-cross-compiled stage1, so clang is never run in the VM. +if [ -n "$SEED" ]; then + BUILD_LINE="\$MAKE $TARGET BUILD_DIR='$BUILD_DIR' BOOTSTRAP_SEED='/home/kit/work/$SEED' MAKE=\"\$MAKE\"" + CC_BANNER="echo \"stage1 seed: $SEED\"; /home/kit/work/$SEED --help >/dev/null 2>&1 && echo 'seed runs' || echo 'seed FAILED to run'" +else + BUILD_LINE="\$MAKE $TARGET BUILD_DIR='$BUILD_DIR' CC=clang AR=ar MAKE=\"\$MAKE\"" + CC_BANNER="clang --version | head -1" +fi + ssh_vm() { scripts/freebsd_vm.sh ssh "$ARCH" "$@" } @@ -71,20 +92,28 @@ ssh_vm 'rm -rf /home/kit/work && mkdir -p /home/kit/work' git -C "$ROOT" ls-files -z | (cd "$ROOT" && COPYFILE_DISABLE=1 tar --null -T - -cf -) \ | ssh_vm 'tar -C /home/kit/work -xf -' +# The seed lives under build/ (gitignored), so it is not in the source tar — +# stream it into the VM separately. +if [ -n "$SEED" ]; then + printf 'freebsd_bootstrap: sending stage1 seed to %s VM\n' "$ARCH" + ssh_vm "mkdir -p /home/kit/work/$(dirname "$SEED")" + ssh_vm "cat > /home/kit/work/$SEED && chmod +x /home/kit/work/$SEED" < "$ROOT/$SEED" +fi + printf 'freebsd_bootstrap: running %s bootstrap on %s\n' "$TARGET" "$ARCH" ssh_vm sh <<EOF set -eu cd /home/kit/work echo "=== freebsd_bootstrap: \$(uname -m) FreeBSD / $TARGET ===" -clang --version | head -1 +$CC_BANNER # FreeBSD ships BSD make as 'make'; the kit Makefile requires GNU make (gmake). MAKE=\$(which gmake 2>/dev/null || which make) # Capture the bootstrap result without aborting the script: a chain that fails # (e.g. the -O1 release link) should still let the Toy corpus run through the # stage3 of any chain that did reach its fixed point. boot_rc=0 -\$MAKE $TARGET BUILD_DIR='$BUILD_DIR' CC=clang AR=ar MAKE="\$MAKE" || boot_rc=\$? +$BUILD_LINE || boot_rc=\$? if [ "$TOY" = "1" ]; then # test/toy/run.sh needs bash (it uses arrays); the FreeBSD base system ships # only the POSIX /bin/sh, so a bash package must be installed (pkg install diff --git a/scripts/selfhost.sh b/scripts/selfhost.sh @@ -116,17 +116,21 @@ selfhost_token() { run_step "$t:run" macos_stage3_hello fi ;; linux) - # rv64 has no native host here, and an in-container clang stage1 would - # itself run emulated. Build the stage1 seed via clang cross on the host - # (native speed), then bootstrap stages 2/3 in the emulated container. - if [ "$arch" = rv64 ]; then - run_step "$t:seed" bash "$ROOT/scripts/kit_cross.sh" "linux-$libc-rv64" --cc=clang || return 1 - seed_env="KIT_LINUX_BOOT_SEED=build/kit-cross/clang/linux-$libc-rv64/kit" - fi + # Always bootstrap from a cross-compiled seed built on the host (clang, + # independent of kit), never an in-container clang stage1: there is no + # point exercising clang inside the target environment, and for a non-host + # arch that clang would run emulated. kit_cross builds the stage1 seed + # here; linux_bootstrap then runs only kit's stages 2/3 in the container. + run_step "$t:seed" bash "$ROOT/scripts/kit_cross.sh" "linux-$libc-$arch" --cc=clang || return 1 + seed_env="KIT_LINUX_BOOT_SEED=build/kit-cross/clang/linux-$libc-$arch/kit" run_step "$t:bootstrap" env KIT_LINUX_BOOT_ARCH="$arch" KIT_LINUX_BOOT_TOY="$toy" $seed_env \ bash "$ROOT/scripts/linux_bootstrap.sh" "$libc" both ;; freebsd) + # Cross-build the stage1 seed on the host (clang), then bootstrap stages + # 2/3 in the VM from it — clang is never run in the VM. + run_step "$t:seed" bash "$ROOT/scripts/kit_cross.sh" "freebsd-$arch" --cc=clang || return 1 run_step "$t:bootstrap" env KIT_FREEBSD_BOOT_TOY="$toy" \ + KIT_FREEBSD_BOOT_SEED="build/kit-cross/clang/freebsd-$arch/kit" \ bash "$ROOT/scripts/freebsd_bootstrap.sh" "$arch" both ;; windows) run_step "$t:cross-build" bash "$ROOT/scripts/windows_cross.sh" "$arch"