kit

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

linux_bootstrap.sh (3488B)


      1 #!/usr/bin/env bash
      2 # Run the three-stage self-build (mk/bootstrap.mk) for aarch64-linux inside a
      3 # Linux container, from a non-Linux dev host (e.g. an Apple-silicon Mac).
      4 #
      5 # The bootstrap is a NATIVE build: `make bootstrap` keys off the container's
      6 # own uname (HOST_OS=linux + aarch64), so it selects the aarch64-linux ELF
      7 # toolchain and reaches its fixed point entirely inside the container. No
      8 # cross-compilation is involved -- the host only supplies podman + the repo.
      9 #
     10 # We run on the same arm64 Linux container family used by the hosted test
     11 # suite: alpine (musl) or debian (glibc). The container needs a seed C
     12 # compiler (clang) to build stage1; stages 2 and 3 are built by kit itself.
     13 #
     14 # usage: scripts/linux_bootstrap.sh [libc] [chain]
     15 #   libc   musl  (default, alpine)  |  glibc (debian)
     16 #   chain  both  (default)          |  debug (-O0)  |  release (-O1)
     17 #
     18 # Env overrides:
     19 #   KIT_LINUX_BOOT_IMAGE   container image (defaults per libc, below)
     20 #   KIT_LINUX_BOOT_PLATFORM  podman --platform (default linux/arm64)
     21 #   KIT_LINUX_BOOT_TOY=1   also run the Toy corpus through the stage3 compiler
     22 #
     23 # The stage tree lands under build/linux-boot/<libc>/ on the host (gitignored),
     24 # so artifacts survive the run for inspection / per-object diffing.
     25 
     26 set -eu
     27 
     28 ROOT="$(cd "$(dirname "$0")/.." && pwd)"
     29 LIBC="${1:-musl}"
     30 CHAIN="${2:-both}"
     31 PLATFORM="${KIT_LINUX_BOOT_PLATFORM:-linux/arm64}"
     32 
     33 case "$LIBC" in
     34   musl)  DEF_IMAGE="docker.io/library/alpine:3.23" ;;
     35   glibc) DEF_IMAGE="docker.io/arm64v8/debian:bookworm-slim" ;;
     36   *) echo "linux_bootstrap: unknown libc '$LIBC' (want musl|glibc)" >&2; exit 2 ;;
     37 esac
     38 IMAGE="${KIT_LINUX_BOOT_IMAGE:-$DEF_IMAGE}"
     39 
     40 case "$CHAIN" in
     41   both)    TARGET="bootstrap" ;;
     42   debug)   TARGET="bootstrap-debug" ;;
     43   release) TARGET="bootstrap-release" ;;
     44   *) echo "linux_bootstrap: unknown chain '$CHAIN' (want both|debug|release)" >&2; exit 2 ;;
     45 esac
     46 
     47 TOY="${KIT_LINUX_BOOT_TOY:-0}"
     48 BUILD_DIR="build/linux-boot/$LIBC"
     49 
     50 # In-container provisioning + build. The package sets give: a seed clang/lld,
     51 # make, the libc dev headers, binutils (ar/ranlib used by the host stage1
     52 # link), the ASan/UBSan runtime + unwinder for the -O0 stage1, and perl (the
     53 # `shasum` the bootstrap recipe prints with). detect_leaks=0 because kit is
     54 # arena-allocated and never frees -- LeakSanitizer (absent on the macOS
     55 # reference host, which is why this only bites on Linux) would otherwise abort
     56 # every stage1 cc invocation.
     57 case "$LIBC" in
     58   musl)
     59     PROVISION='apk add --no-cache clang lld make musl-dev binutils compiler-rt libgcc perl-utils bash >/dev/null'
     60     ;;
     61   glibc)
     62     PROVISION='export DEBIAN_FRONTEND=noninteractive; apt-get update -qq >/dev/null && apt-get install -y -qq clang lld make libc6-dev binutils perl >/dev/null'
     63     ;;
     64 esac
     65 
     66 read -r -d '' REMOTE <<EOF || true
     67 set -eu
     68 $PROVISION
     69 cd /work
     70 echo "=== linux_bootstrap: \$(uname -m) / $LIBC / $TARGET ==="
     71 clang --version | head -1
     72 make $TARGET BUILD_DIR='$BUILD_DIR' CC=clang AR=ar
     73 if [ "$TOY" = "1" ]; then
     74   for m in debug release; do
     75     s3="$BUILD_DIR/\$m/bootstrap/stage3/kit"
     76     [ -x "\$s3" ] || continue
     77     echo "=== Toy corpus through \$m stage3 ==="
     78     KIT="\$(pwd)/\$s3" test/toy/run.sh || true
     79   done
     80 fi
     81 echo "=== linux_bootstrap: DONE $TARGET ==="
     82 EOF
     83 
     84 exec podman run --rm --platform "$PLATFORM" \
     85   -e ASAN_OPTIONS=halt_on_error=1:abort_on_error=1:detect_leaks=0 \
     86   -e UBSAN_OPTIONS=halt_on_error=1:print_stacktrace=1 \
     87   -v "$ROOT":/work:Z \
     88   "$IMAGE" sh -c "$REMOTE"