libc-flatten.sh (3528B)
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 # Compiler header: post-patch tcc <stdarg.h>. Written by 68 # stage1-flatten.sh, which boot3.sh / Makefile run first. Required so we 69 # can prepend the 70 # per-arch va_list typedef + __builtin_va_* → tcc __va_* mapping into 71 # libc.flat.c. 72 TCC_PKG=tcc-0.9.26-1147-gee75a10c 73 TCC_STDARG=$ROOT/build/$ARCH/vendor/tcc/$TCC_PKG/include/stdarg.h 74 [ -e "$TCC_STDARG" ] || { echo "missing $TCC_STDARG — run bootprep/stage1-flatten.sh first" >&2; exit 1; } 75 76 "$HOST_CC" -E -P \ 77 -nostdinc \ 78 -I "$SYS_INCLUDE" \ 79 -D HAVE_CONFIG_H=0 \ 80 -D __linux__=1 \ 81 -D __${MES_ARCH}__=1 \ 82 -D __riscv_xlen=64 \ 83 -D inline= \ 84 "$STAGE/libc.c" > "$FLAT.body" 85 86 # Prepend TCC's compiler header, guarded by !CCSCM (cc.scm predefines CCSCM and 87 # handles __builtin_va_* natively, so it must skip this block). Under 88 # tcc, the per-arch #ifdefs inside the header resolve and provide the 89 # va_list typedef + __builtin_va_* → tcc native __va_* macros. 90 { 91 echo '#ifndef CCSCM' 92 cat "$TCC_STDARG" 93 echo '#endif' 94 cat "$FLAT.body" 95 } > "$FLAT" 96 rm -f "$FLAT.body" 97 98 BYTES=$(wc -c < "$FLAT") 99 echo "produced $FLAT ($BYTES bytes)"