boot5-calibrate.sh (5990B)
1 #!/bin/sh 2 ## boot5-calibrate.sh — produce vendor/musl/skip-$ARCH.txt 3 ## 4 ## NOT on the boot.sh path. Generates the per-arch calibration list 5 ## boot5.sh uses to drop skip-on-fail logic from the container. Run 6 ## this once per architecture when the patch set, calibration arch, or 7 ## tcc version changes; commit the resulting file alongside the rest of 8 ## the vendored musl artifacts. 9 ## 10 ## What it does: 11 ## 1. Stage the same prerequisites boot5.sh stages (boot4/tcc3, 12 ## libtcc1.a, vendored overrides + deletes, pre-generated headers, 13 ## stdarg bridge). 14 ## 2. Run a skip-on-fail compile loop in the container over every 15 ## musl source. Whatever tcc 0.9.26 cannot compile gets recorded. 16 ## 3. Copy the resulting skip list out to 17 ## vendor/musl/skip-$ARCH.txt. 18 ## 19 ## boot5.sh then enumerates sources on the host and subtracts this 20 ## list, emitting a flat sequential build script with no in-container 21 ## branch on $TCC's exit code. 22 ## 23 ## Usage: bootprep/boot5-calibrate.sh <amd64|aarch64|riscv64> 24 25 set -eu 26 27 usage() { echo "usage: $0 <amd64|aarch64|riscv64>" >&2; exit 2; } 28 [ "$#" -eq 1 ] || usage 29 ARCH=$1 30 31 case "$ARCH" in 32 amd64) PLATFORM=linux/amd64; MUSL_ARCH=x86_64 ;; 33 aarch64) PLATFORM=linux/arm64; MUSL_ARCH=aarch64 ;; 34 riscv64) PLATFORM=linux/riscv64; MUSL_ARCH=riscv64 ;; 35 *) usage ;; 36 esac 37 38 ROOT=$(cd "$(dirname "$0")/.." && pwd) 39 cd "$ROOT" 40 41 IMAGE=boot2-busybox:$ARCH 42 BOOT4=build/$ARCH/boot4 43 STAGE=build/$ARCH/.boot5-calibrate 44 MUSL_TARBALL=vendor/musl/1.2.5.tar.gz 45 MUSL_OVERRIDES=vendor/musl/overrides 46 MUSL_DELETES=vendor/musl/deletes.txt 47 MUSL_GENERATED=vendor/musl/generated/$MUSL_ARCH 48 BRIDGE_FILE=build/$ARCH/vendor/tcc/stdarg-bridge.h 49 SKIP_OUT=vendor/musl/skip-$ARCH.txt 50 51 [ -x "$BOOT4/tcc3" ] || { echo "missing $BOOT4/tcc3 (run boot/boot4.sh $ARCH)" >&2; exit 1; } 52 [ -e "$BOOT4/libtcc1.a" ] || { echo "missing $BOOT4/libtcc1.a" >&2; exit 1; } 53 [ -e "$MUSL_TARBALL" ] || { echo "missing $MUSL_TARBALL" >&2; exit 1; } 54 [ -d "$MUSL_OVERRIDES" ] || { echo "missing $MUSL_OVERRIDES" >&2; exit 1; } 55 [ -e "$MUSL_DELETES" ] || { echo "missing $MUSL_DELETES" >&2; exit 1; } 56 [ -d "$MUSL_GENERATED" ] || { echo "missing $MUSL_GENERATED (run bootprep/musl-vendor.sh)" >&2; exit 1; } 57 [ -e "$BRIDGE_FILE" ] || { echo "missing $BRIDGE_FILE (run bootprep/stage1-flatten.sh)" >&2; exit 1; } 58 59 if ! podman image exists "$IMAGE"; then 60 podman build --platform "$PLATFORM" -t "$IMAGE" \ 61 -f boot/containers/Containerfile.busybox boot/containers/ 62 fi 63 64 rm -rf "$STAGE" 65 mkdir -p "$STAGE/in" "$STAGE/out" 66 67 cp "$BOOT4/tcc3" "$STAGE/in/tcc" 68 cp "$BOOT4/libtcc1.a" "$STAGE/in/libtcc1.a" 69 tar xzf "$MUSL_TARBALL" -C "$STAGE/in/" 70 MUSL_DIR=$STAGE/in/musl-1.2.5 71 cp -R "$MUSL_OVERRIDES/." "$MUSL_DIR/" 72 while read -r p; do 73 [ -n "$p" ] && rm -rf "$MUSL_DIR/$p" 74 done < "$MUSL_DELETES" 75 cp "$BRIDGE_FILE" "$STAGE/in/tcc-stdarg-bridge.h" 76 cp "$MUSL_GENERATED/alltypes.h" "$STAGE/in/musl-alltypes.h" 77 cp "$MUSL_GENERATED/syscall.h" "$STAGE/in/musl-syscall.h" 78 79 echo "[calibrate $ARCH] running skip-on-fail compile loop in container" 80 podman run --rm -i --pull=never --platform "$PLATFORM" \ 81 --tmpfs /tmp:size=1024M \ 82 -e MUSL_ARCH="$MUSL_ARCH" \ 83 -v "$ROOT/$STAGE:/work" -w /work "$IMAGE" \ 84 sh -eu -s <<'CONTAINER' 85 IN=/work/in 86 OUT=/work/out 87 TCC=$IN/tcc 88 89 cd /tmp 90 cp -R "$IN/musl-1.2.5" . 91 cd musl-1.2.5 92 93 mkdir -p obj/include/bits obj/src/internal 94 cp $IN/musl-alltypes.h obj/include/bits/alltypes.h 95 cp $IN/musl-syscall.h obj/include/bits/syscall.h 96 echo '#define VERSION "1.2.5-tcc-boot5"' > obj/src/internal/version.h 97 98 CFLAGS_BASE="-std=c99 -nostdinc -ffreestanding -fno-strict-aliasing 99 -D_XOPEN_SOURCE=700 100 -I./arch/$MUSL_ARCH -I./arch/generic -Iobj/src/internal 101 -I./src/include -I./src/internal -Iobj/include -I./include 102 -O2 -fomit-frame-pointer 103 -Werror=implicit-function-declaration -Werror=implicit-int 104 -Werror=pointer-sign -Werror=pointer-arith" 105 CFLAGS_C="$CFLAGS_BASE -include $IN/tcc-stdarg-bridge.h" 106 CFLAGS_ASM="$CFLAGS_BASE" 107 108 SRC_TOP="src/aio src/conf src/crypt src/ctype src/dirent 109 src/env src/errno src/exit src/fcntl src/fenv src/internal 110 src/ipc src/legacy src/linux src/locale src/malloc 111 src/malloc/mallocng src/math src/misc src/mman src/mq 112 src/multibyte src/network src/passwd src/prng src/process 113 src/regex src/sched src/search src/select src/setjmp src/signal 114 src/stat src/stdio src/stdlib src/string src/temp src/termios 115 src/thread src/time src/unistd" 116 117 BASE_SRCS=""; ARCH_SRCS="" 118 for d in $SRC_TOP; do 119 [ -d "$d" ] || continue 120 for f in $d/*.c; do [ -f "$f" ] && BASE_SRCS="$BASE_SRCS $f"; done 121 for f in $d/$MUSL_ARCH/*.c $d/$MUSL_ARCH/*.s $d/$MUSL_ARCH/*.S; do 122 [ -f "$f" ] && ARCH_SRCS="$ARCH_SRCS $f" 123 done 124 done 125 REPLACED="" 126 for a in $ARCH_SRCS; do 127 p=${a%.*} 128 head=${p%%/${MUSL_ARCH}/*} 129 tail=${p#*/${MUSL_ARCH}/} 130 REPLACED="$REPLACED $head/$tail" 131 done 132 KEEP="" 133 for b in $BASE_SRCS; do 134 stem=${b%.c}; skip=0 135 for r in $REPLACED; do [ "$stem" = "$r" ] && { skip=1; break; }; done 136 [ $skip -eq 0 ] && KEEP="$KEEP $b" 137 done 138 KEEP="$KEEP $ARCH_SRCS" 139 140 mkdir -p obj/lib 141 n=0; n_ok=0; n_skip=0 142 : >$OUT/skipped.txt 143 for src in $KEEP; do 144 obj="obj/${src%.*}.o" 145 mkdir -p "$(dirname $obj)" 146 case "$src" in 147 *.c) flags="$CFLAGS_C" ;; 148 *.s | *.S) flags="$CFLAGS_ASM" ;; 149 *) flags="$CFLAGS_C" ;; 150 esac 151 if $TCC $flags -c "$src" -o "$obj" >/tmp/compile.log 2>&1; then 152 n_ok=$((n_ok+1)) 153 else 154 n_skip=$((n_skip+1)) 155 echo "$src" >>$OUT/skipped.txt 156 fi 157 n=$((n+1)) 158 [ $((n % 200)) -eq 0 ] && echo " $n done (ok=$n_ok skip=$n_skip)" 159 done 160 echo " compiled=$n_ok skipped=$n_skip total=$n" 161 CONTAINER 162 163 sort -u "$STAGE/out/skipped.txt" > "$SKIP_OUT" 164 echo "[calibrate $ARCH] wrote $SKIP_OUT ($(wc -l <"$SKIP_OUT") entries)"