boot2

Playing with the boostrap
git clone https://git.ryansepassi.com/git/boot2.git
Log | Files | Refs | README

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}"