libc-flatten.sh (3574B)
1 #!/bin/sh 2 ## libc-flatten.sh — flatten the slimmed mes-libc closure (vendor/mes-libc/ 3 ## libc.c, a single TU folding boot2-syscall.c plus every mes .c file 4 ## tcc.flat.c actually references) into libc.flat.c using the host 5 ## preprocessor. Mirrors stage1-flatten.sh; runs on the host, no 6 ## container — hence the non-`boot-` name (boot-*.sh runs inside the 7 ## minimal container). 8 ## 9 ## Steps: 10 ## 1. stage vendor/mes-libc → build/<arch>/vendor/mes-libc/libc-stage/ 11 ## (still a copy: we tweak the per-arch include layout there) 12 ## 2. HOST_CC -E -nostdinc -I staging/include … staging/libc.c 13 ## → build/<arch>/vendor/mes-libc/libc.flat.c 14 ## 15 ## The .c-file patches that used to live in step (2) are now baked into 16 ## vendor/mes-libc/libc.c directly; libc-flatten.sh no longer rewrites 17 ## sources before flattening. 18 ## 19 ## Stage 4 (cc.scm libc.flat.c → libc.P1pp) is a separate Makefile rule 20 ## that reuses scripts/boot-build-cc.sh inside the per-arch container. 21 ## 22 ## ARCH selects the boot2 target (aarch64/amd64/riscv64). MES_ARCH is 23 ## the mes header tree we hand the host preprocessor; mes ships 24 ## x86_64/riscv64 only, so aarch64 builds borrow riscv64's headers (the 25 ## resulting libc.flat.c references no SYS_* / kernel-stat fields, so 26 ## the choice only affects type widths, all 64-bit Linux-identical). 27 ## 28 ## Usage: bootprep/libc-flatten.sh [--arch <aarch64|amd64|riscv64>] 29 30 set -eu 31 32 ARCH=aarch64 33 while [ $# -gt 0 ]; do 34 case "$1" in 35 --arch) ARCH=$2; shift 2 ;; 36 -h|--help) awk '/^##/ { sub(/^## ?/, ""); print }' "$0"; exit 0 ;; 37 *) echo "unknown arg: $1" >&2; exit 2 ;; 38 esac 39 done 40 41 case "$ARCH" in 42 aarch64) MES_ARCH=riscv64 ;; 43 amd64) MES_ARCH=x86_64 ;; 44 riscv64) MES_ARCH=riscv64 ;; 45 *) echo "unknown ARCH: $ARCH" >&2; exit 2 ;; 46 esac 47 48 ROOT=$(cd "$(dirname "$0")/.." && pwd) 49 VENDOR=$ROOT/vendor/mes-libc 50 WORK=$ROOT/build/$ARCH/vendor/mes-libc 51 STAGE=$WORK/libc-stage 52 FLAT=$WORK/libc.flat.c 53 SYS_INCLUDE=$ROOT/bootprep/headers 54 55 [ -d "$VENDOR" ] || { echo "missing $VENDOR" >&2; exit 1; } 56 [ -d "$SYS_INCLUDE" ] || { echo "missing $SYS_INCLUDE" >&2; exit 1; } 57 58 # --- (1) stage -------------------------------------------------------- 59 mkdir -p "$WORK" 60 rm -rf "$STAGE" 61 mkdir -p "$STAGE" 62 cp -R "$VENDOR/." "$STAGE/" 63 64 # --- (2) flatten via host preprocessor -------------------------------- 65 HOST_CC=${HOST_CC:-cc} 66 67 # Bridge file: post-patch tcc <stdarg.h>. Written by stage1-flatten.sh, 68 # which boot3.sh / Makefile run first. Required so we can prepend the 69 # per-arch va_list typedef + __builtin_va_* → tcc __va_* mapping into 70 # libc.flat.c, eliminating the need for `-I /work/in/tcc-include 71 # -include /work/in/tcc-include/stdarg.h` on every in-container compile. 72 BRIDGE=$ROOT/build/$ARCH/vendor/tcc/stdarg-bridge.h 73 [ -e "$BRIDGE" ] || { echo "missing $BRIDGE — run bootprep/stage1-flatten.sh first" >&2; exit 1; } 74 75 "$HOST_CC" -E -P \ 76 -nostdinc \ 77 -I "$SYS_INCLUDE" \ 78 -D HAVE_CONFIG_H=0 \ 79 -D __linux__=1 \ 80 -D __${MES_ARCH}__=1 \ 81 -D __riscv_xlen=64 \ 82 -D inline= \ 83 "$STAGE/libc.c" > "$FLAT.body" 84 85 # Prepend the bridge, guarded by !CCSCM (cc.scm predefines CCSCM and 86 # handles __builtin_va_* natively, so it must skip this block). Under 87 # tcc, the per-arch #ifdefs inside the bridge resolve and provide the 88 # va_list typedef + __builtin_va_* → tcc native __va_* macros. 89 { 90 echo '#ifndef CCSCM' 91 cat "$BRIDGE" 92 echo '#endif' 93 cat "$FLAT.body" 94 } > "$FLAT" 95 rm -f "$FLAT.body" 96 97 BYTES=$(wc -c < "$FLAT") 98 echo "produced $FLAT ($BYTES bytes)"