boot5.sh (5045B)
1 #!/bin/sh 2 ## boot5.sh — build musl-1.2.5 with boot4 artifacts and link hello. 3 ## 4 ## Builds on top of boot4's verified-fixed-point tcc (tcc1 == tcc2) and 5 ## demonstrates that the same compiler can produce a working static libc 6 ## from upstream musl source — patched only as far as needed to work 7 ## around tcc's missing GCC extensions (register-asm-variable syscalls, 8 ## attribute(alias) weak refs, _Complex, x86_64 SSE/x87 inline asm). 9 ## 10 ## ─── Inputs ────────────────────────────────────────────────────────── 11 ## build/$ARCH/$DRIVER/boot4/tcc2 — boot4's verified self-host tcc 12 ## build/$ARCH/$DRIVER/boot4/libtcc1.a — boot4's tcc runtime archive 13 ## build/$ARCH/$DRIVER/boot2/{catm, scheme1} 14 ## build/$ARCH/src/src/musl/ — canonical musl tree (overrides 15 ## merged, deletes applied, 16 ## alltypes.h/syscall.h generated, 17 ## per-arch skip filter applied) 18 ## build/$ARCH/src/src/tcc/<package>/include/ — TCC compiler headers 19 ## build/$ARCH/src/src/test-fixtures/boot-hello.c 20 ## 21 ## ─── Tools ──────────────────────────────────────────────────────────── 22 ## scheme1 evaluates the prep-time run.scm at 23 ## build/$ARCH/src/run/boot5.scm (generated by 24 ## bootprep/boot5-gen-runscm.sh during prep-src) against the flat 25 ## staging root. 26 ## 27 ## ─── Outputs ───────────────────────────────────────────────────────── 28 ## build/$ARCH/$DRIVER/boot5/libc.a 29 ## build/$ARCH/$DRIVER/boot5/{crt1.o, crti.o, crtn.o} 30 ## build/$ARCH/$DRIVER/boot5/hello — static, runs in the container 31 ## 32 ## Usage: boot/boot5.sh <arch> 33 ## <arch> ∈ {aarch64, amd64, riscv64} for either DRIVER (default podman). 34 35 set -eu 36 37 . boot/lib-arch.sh 38 bootlib_init boot5 "${1:-}" 39 require_tcc_target 40 driver_init empty 41 require_src 42 43 BOOT2=build/$ARCH/$DRIVER/boot2 44 BOOT4=build/$ARCH/$DRIVER/boot4 45 SRC=build/$ARCH/src 46 MUSL_DIR=$SRC/src/musl 47 TCC_PKG=tcc-0.9.26-1147-gee75a10c 48 TCC_INCLUDE=$SRC/src/tcc/$TCC_PKG/include 49 50 # ── prerequisites ───────────────────────────────────────────────────── 51 require_prev "$BOOT4" tcc2 52 require_prev "$BOOT2" catm scheme1 53 require_file "$BOOT4/libtcc1.a" "run boot/boot4.sh $ARCH" 54 require_file "$MUSL_DIR" "run bootprep/prep-src.sh $ARCH" 55 require_file "$MUSL_DIR/skip.txt" "run bootprep/prep-src.sh $ARCH" 56 require_file "$TCC_INCLUDE/stdarg.h" "run bootprep/prep-src.sh $ARCH" 57 58 # ── prepare staging dirs ────────────────────────────────────────────── 59 # $STAGE/in/ — read-only inputs (becomes /work/in or in/ in tmpfs) 60 # $STAGE/out/ — writable outputs (becomes /work/out or out/ in tmpfs) 61 . boot/lib-runscm.sh 62 runscm_init "$STAGE" "$OUT" 63 runscm_runscm "$SRC/run/boot5.scm" 64 65 # Pre-create per-source obj/ dirs under $STAGE/out/obj/musl/ so 66 # scheme1's (run "in/tcc" -c …) doesn't need to mkdir at runtime (tcc 67 # errors out if the parent dir is missing, and scheme1 has no mkdir 68 # primitive). Per-source list is the build-srcs.txt produced by 69 # bootprep/boot5-enumerate.sh at prep time. 70 SRCS=$SRC/run/boot5/build-srcs.txt 71 require_file "$SRCS" "run bootprep/prep-src.sh $ARCH" 72 COBJ=$STAGE/out/obj/musl 73 mkdir -p "$COBJ/crt" 74 awk ' 75 { 76 sub(/\.[^.]*$/, "") 77 if (match($0, /\/[^\/]*$/)) print substr($0, 1, RSTART - 1) 78 } 79 ' "$SRCS" | sort -u | while read -r d; do mkdir -p "$COBJ/$d"; done 80 81 runscm_scheme1 "$BOOT2/scheme1" 82 runscm_prelude "$SRC/src/scheme1/prelude.scm" 83 84 # Chain binaries staged at flat in/ root (cwd-relative names in run.scm). 85 runscm_input tcc "$BOOT4/tcc2" 86 runscm_input libtcc1.a "$BOOT4/libtcc1.a" 87 runscm_input catm "$BOOT2/catm" 88 runscm_input tcc-include/stdarg.h "$TCC_INCLUDE/stdarg.h" 89 runscm_input_from_src test-fixtures/boot-hello.c hello.c 90 91 # Stage the canonical musl tree under in/musl/. Both drivers pick it 92 # up automatically (podman bind-mounts $STAGE/in; seed packs 93 # `find in -type f` into the cpio). 94 runscm_input_tree_from_src musl musl 95 96 runscm_export libc.a crt1.o crti.o crtn.o hello 97 98 # boot5 has ~1300 spawns + heavy tcc work; bump qemu memory + timeout for 99 # the seed driver. Podman ignores QEMU_MEM and uses host memory directly. 100 QEMU_MEM=${QEMU_MEM:-3072M} runscm_run "${BOOT5_TIMEOUT:-7200}" 101 102 echo "[$BOOT_TAG] sizes: libc.a=$(wc -c <"$OUT/libc.a") hello=$(wc -c <"$OUT/hello")" 103 echo "[$BOOT_TAG] OK -> $OUT/{libc.a, crt1.o, crti.o, crtn.o, hello}"