boot7.sh (5147B)
1 #!/bin/sh 2 ## boot7.sh — assemble the final static C toolchain sysroot. 3 ## 4 ## This stage installs the verified boot4/boot5 products and canonical 5 ## headers into one relocatable directory, then compiles and runs a temporary 6 ## acceptance program through the installed driver: 7 ## 8 ## build/$ARCH/$DRIVER/boot7/toolchain/ 9 ## bin/tcc boot4's fixed-point compiler (tcc2) 10 ## lib/libc.a boot5 musl 11 ## lib/crt{1,i,n}.o boot5 startup objects 12 ## lib/tcc/libtcc1.a boot4 compiler runtime 13 ## lib/tcc/include/stdarg.h TCC compiler-owned varargs ABI 14 ## include/ installed public musl headers 15 ## MANIFEST.sha256 hash of every installed file except itself 16 ## 17 ## boot7 is deliberately host-side for both DRIVER values: it only copies 18 ## already-verified artifacts. Slash-containing paths work in both execution 19 ## transports, but assembling an installed tree does not gain anything from 20 ## hundreds of guest-side copy operations. 21 ## 22 ## Usage: boot/boot7.sh <arch> 23 ## <arch> ∈ {aarch64, amd64, riscv64} for either DRIVER (default podman). 24 25 set -eu 26 27 . boot/lib-arch.sh 28 bootlib_init boot7 "${1:-}" 29 require_tcc_target 30 require_src 31 32 OUT=build/$ARCH/$DRIVER/boot7 33 STAGE=build/$ARCH/$DRIVER/.boot7-stage 34 export OUT STAGE 35 36 BOOT4=build/$ARCH/$DRIVER/boot4 37 BOOT5=build/$ARCH/$DRIVER/boot5 38 MUSL=build/$ARCH/src/src/musl 39 TCC_PKG=tcc-0.9.26-1147-gee75a10c 40 TCC_INCLUDE=build/$ARCH/src/src/tcc/$TCC_PKG/include 41 SMOKE_SOURCE=build/$ARCH/src/src/test-fixtures/toolchain-hello.c 42 43 for f in \ 44 "$BOOT4/tcc2" "$BOOT4/libtcc1.a" "$SMOKE_SOURCE" \ 45 "$BOOT5/libc.a" "$BOOT5/crt1.o" "$BOOT5/crti.o" "$BOOT5/crtn.o" \ 46 "$MUSL/obj/include/bits/alltypes.h" \ 47 "$MUSL/obj/include/bits/syscall.h" \ 48 "$TCC_INCLUDE/stdarg.h" 49 do 50 require_file "$f" 51 done 52 53 rm -rf "$STAGE" 54 mkdir -p "$STAGE/toolchain/bin" "$STAGE/toolchain/lib/tcc/include" \ 55 "$STAGE/toolchain/include" 56 TOOLCHAIN=$STAGE/toolchain 57 58 # Final built binaries and libraries. boot4's mes-libc/crt1 are bootstrap 59 # internals; the installed libc/crt objects are boot5's musl products. 60 cp "$BOOT4/tcc2" "$TOOLCHAIN/bin/tcc" 61 cp "$BOOT4/libtcc1.a" "$TOOLCHAIN/lib/tcc/libtcc1.a" 62 cp "$BOOT5/libc.a" "$TOOLCHAIN/lib/libc.a" 63 cp "$BOOT5/crt1.o" "$TOOLCHAIN/lib/crt1.o" 64 cp "$BOOT5/crti.o" "$TOOLCHAIN/lib/crti.o" 65 cp "$BOOT5/crtn.o" "$TOOLCHAIN/lib/crtn.o" 66 67 # Install public musl headers with the same precedence as musl's 68 # install-headers target: generic bits, arch bits, then generated bits. 69 # The general include/ tree is disjoint from the installed bits/ overlay. 70 copy_headers() { 71 _src=$1; _dest=$2 72 ( cd "$_src" && find . -type f -name '*.h' | LC_ALL=C sort ) | 73 while IFS= read -r _rel; do 74 _rel=${_rel#./} 75 _dst=$_dest/$_rel 76 mkdir -p "$(dirname "$_dst")" 77 cp "$_src/$_rel" "$_dst" 78 done 79 } 80 81 copy_headers "$MUSL/include" "$TOOLCHAIN/include" 82 copy_headers "$MUSL/arch/generic/bits" "$TOOLCHAIN/include/bits" 83 copy_headers "$MUSL/arch/$MUSL_ARCH/bits" "$TOOLCHAIN/include/bits" 84 copy_headers "$MUSL/obj/include/bits" "$TOOLCHAIN/include/bits" 85 cp "$TCC_INCLUDE/stdarg.h" "$TOOLCHAIN/lib/tcc/include/stdarg.h" 86 87 chmod 0755 "$TOOLCHAIN/bin/tcc" 88 find "$TOOLCHAIN/lib" "$TOOLCHAIN/include" -type f -exec chmod 0644 {} + 89 90 # Acceptance is the downstream interface itself: no wrapper, include flags, 91 # CRT paths, or library flags. Run it in the target-architecture BusyBox 92 # container; boot7 stays host-side for assembly, and seed artifacts have 93 # already been proven byte-identical to the podman artifacts separately. 94 if [ "$DRIVER" = podman ]; then 95 IMAGE=boot2-busybox:$ARCH 96 if ! podman image exists "$IMAGE"; then 97 podman build --platform "$PLATFORM" -t "$IMAGE" \ 98 -f boot/containers/Containerfile.busybox boot/containers/ 99 fi 100 mkdir -p "$STAGE/smoke" 101 cp "$SMOKE_SOURCE" "$STAGE/smoke/hello.c" 102 TOOLCHAIN_ABS=$(cd "$TOOLCHAIN" && pwd) 103 SMOKE_ABS=$(cd "$STAGE/smoke" && pwd) 104 podman run --rm --pull=never --platform "$PLATFORM" \ 105 --network=none --read-only --tmpfs /tmp:size=16M \ 106 --env PATH=/toolchain/bin:/bin \ 107 -v "$TOOLCHAIN_ABS:/toolchain:ro" -v "$SMOKE_ABS:/work:rw" \ 108 -w /work "$IMAGE" tcc hello.c -o hello 109 podman run --rm --pull=never --platform "$PLATFORM" \ 110 --network=none --read-only --tmpfs /tmp:size=16M \ 111 -v "$SMOKE_ABS:/work:ro" -w /work "$IMAGE" /work/hello 112 rm -rf "$STAGE/smoke" 113 fi 114 115 if command -v sha256sum >/dev/null 2>&1; then 116 sha256() { sha256sum "$1" | awk '{print $1}'; } 117 else 118 sha256() { shasum -a 256 "$1" | awk '{print $1}'; } 119 fi 120 121 : > "$TOOLCHAIN/MANIFEST.sha256" 122 ( cd "$TOOLCHAIN" && find . -type f ! -name MANIFEST.sha256 | LC_ALL=C sort ) | 123 while IFS= read -r rel; do 124 rel=${rel#./} 125 printf '%s %s\n' "$(sha256 "$TOOLCHAIN/$rel")" "$rel" \ 126 >> "$TOOLCHAIN/MANIFEST.sha256" 127 done 128 chmod 0644 "$TOOLCHAIN/MANIFEST.sha256" 129 130 rm -rf "$OUT" 131 mkdir -p "$OUT" 132 mv "$TOOLCHAIN" "$OUT/toolchain" 133 134 count=$(wc -l < "$OUT/toolchain/MANIFEST.sha256" | tr -d ' ') 135 echo "[$BOOT_TAG] OK -> $OUT/toolchain ($count files)"