boot5-calibrate.sh (6065B)
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/tcc2, 12 ## libtcc1.a, vendored overrides + deletes, pre-generated headers, 13 ## TCC compiler headers). 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 TCC_PKG=tcc-0.9.26-1147-gee75a10c 49 TCC_INCLUDE=build/$ARCH/vendor/tcc/$TCC_PKG/include 50 SKIP_OUT=vendor/musl/skip-$ARCH.txt 51 52 [ -x "$BOOT4/tcc2" ] || { echo "missing $BOOT4/tcc2 (run boot/boot4.sh $ARCH)" >&2; exit 1; } 53 [ -e "$BOOT4/libtcc1.a" ] || { echo "missing $BOOT4/libtcc1.a" >&2; exit 1; } 54 [ -e "$MUSL_TARBALL" ] || { echo "missing $MUSL_TARBALL" >&2; exit 1; } 55 [ -d "$MUSL_OVERRIDES" ] || { echo "missing $MUSL_OVERRIDES" >&2; exit 1; } 56 [ -e "$MUSL_DELETES" ] || { echo "missing $MUSL_DELETES" >&2; exit 1; } 57 [ -d "$MUSL_GENERATED" ] || { echo "missing $MUSL_GENERATED (run bootprep/musl-vendor.sh)" >&2; exit 1; } 58 [ -e "$TCC_INCLUDE/stdarg.h" ] || { echo "missing $TCC_INCLUDE/stdarg.h (run bootprep/stage1-flatten.sh)" >&2; exit 1; } 59 60 if ! podman image exists "$IMAGE"; then 61 podman build --platform "$PLATFORM" -t "$IMAGE" \ 62 -f boot/containers/Containerfile.busybox boot/containers/ 63 fi 64 65 rm -rf "$STAGE" 66 mkdir -p "$STAGE/in" "$STAGE/out" 67 68 cp "$BOOT4/tcc2" "$STAGE/in/tcc" 69 cp "$BOOT4/libtcc1.a" "$STAGE/in/libtcc1.a" 70 tar xzf "$MUSL_TARBALL" -C "$STAGE/in/" 71 MUSL_DIR=$STAGE/in/musl-1.2.5 72 cp -R "$MUSL_OVERRIDES/." "$MUSL_DIR/" 73 while read -r p; do 74 [ -n "$p" ] && rm -rf "$MUSL_DIR/$p" 75 done < "$MUSL_DELETES" 76 mkdir -p "$STAGE/in/tcc-include" 77 cp "$TCC_INCLUDE/stdarg.h" "$STAGE/in/tcc-include/stdarg.h" 78 cp "$MUSL_GENERATED/alltypes.h" "$STAGE/in/musl-alltypes.h" 79 cp "$MUSL_GENERATED/syscall.h" "$STAGE/in/musl-syscall.h" 80 81 echo "[calibrate $ARCH] running skip-on-fail compile loop in container" 82 podman run --rm -i --pull=never --platform "$PLATFORM" \ 83 --tmpfs /tmp:size=1024M \ 84 -e MUSL_ARCH="$MUSL_ARCH" \ 85 -v "$ROOT/$STAGE:/work" -w /work "$IMAGE" \ 86 sh -eu -s <<'CONTAINER' 87 IN=/work/in 88 OUT=/work/out 89 TCC=$IN/tcc 90 91 cd /tmp 92 cp -R "$IN/musl-1.2.5" . 93 cd musl-1.2.5 94 95 mkdir -p obj/include/bits obj/src/internal 96 cp $IN/musl-alltypes.h obj/include/bits/alltypes.h 97 cp $IN/musl-syscall.h obj/include/bits/syscall.h 98 echo '#define VERSION "1.2.5-tcc-boot5"' > obj/src/internal/version.h 99 100 CFLAGS_BASE="-std=c99 -nostdinc -ffreestanding -fno-strict-aliasing 101 -D_XOPEN_SOURCE=700 102 -I./arch/$MUSL_ARCH -I./arch/generic -Iobj/src/internal 103 -I./src/include -I./src/internal -Iobj/include -I./include 104 -O2 -fomit-frame-pointer 105 -Werror=implicit-function-declaration -Werror=implicit-int 106 -Werror=pointer-sign -Werror=pointer-arith" 107 CFLAGS_C="-I$IN/tcc-include $CFLAGS_BASE" 108 CFLAGS_ASM="$CFLAGS_BASE" 109 110 SRC_TOP="src/aio src/conf src/crypt src/ctype src/dirent 111 src/env src/errno src/exit src/fcntl src/fenv src/internal 112 src/ipc src/legacy src/linux src/locale src/malloc 113 src/malloc/mallocng src/math src/misc src/mman src/mq 114 src/multibyte src/network src/passwd src/prng src/process 115 src/regex src/sched src/search src/select src/setjmp src/signal 116 src/stat src/stdio src/stdlib src/string src/temp src/termios 117 src/thread src/time src/unistd" 118 119 BASE_SRCS=""; ARCH_SRCS="" 120 for d in $SRC_TOP; do 121 [ -d "$d" ] || continue 122 for f in $d/*.c; do [ -f "$f" ] && BASE_SRCS="$BASE_SRCS $f"; done 123 for f in $d/$MUSL_ARCH/*.c $d/$MUSL_ARCH/*.s $d/$MUSL_ARCH/*.S; do 124 [ -f "$f" ] && ARCH_SRCS="$ARCH_SRCS $f" 125 done 126 done 127 REPLACED="" 128 for a in $ARCH_SRCS; do 129 p=${a%.*} 130 head=${p%%/${MUSL_ARCH}/*} 131 tail=${p#*/${MUSL_ARCH}/} 132 REPLACED="$REPLACED $head/$tail" 133 done 134 KEEP="" 135 for b in $BASE_SRCS; do 136 stem=${b%.c}; skip=0 137 for r in $REPLACED; do [ "$stem" = "$r" ] && { skip=1; break; }; done 138 [ $skip -eq 0 ] && KEEP="$KEEP $b" 139 done 140 KEEP="$KEEP $ARCH_SRCS" 141 142 mkdir -p obj/lib 143 n=0; n_ok=0; n_skip=0 144 : >$OUT/skipped.txt 145 for src in $KEEP; do 146 obj="obj/${src%.*}.o" 147 mkdir -p "$(dirname $obj)" 148 case "$src" in 149 *.c) flags="$CFLAGS_C" ;; 150 *.s | *.S) flags="$CFLAGS_ASM" ;; 151 *) flags="$CFLAGS_C" ;; 152 esac 153 if $TCC $flags -c "$src" -o "$obj" >/tmp/compile.log 2>&1; then 154 n_ok=$((n_ok+1)) 155 else 156 n_skip=$((n_skip+1)) 157 echo "$src" >>$OUT/skipped.txt 158 fi 159 n=$((n+1)) 160 [ $((n % 200)) -eq 0 ] && echo " $n done (ok=$n_ok skip=$n_skip)" 161 done 162 echo " compiled=$n_ok skipped=$n_skip total=$n" 163 CONTAINER 164 165 sort -u "$STAGE/out/skipped.txt" > "$SKIP_OUT" 166 echo "[calibrate $ARCH] wrote $SKIP_OUT ($(wc -l <"$SKIP_OUT") entries)"