boot-build-tcc-tcc.sh (3818B)
1 #!/bin/sh 2 ## boot-build-tcc-tcc.sh — next-stage tcc, parametrized by the 3 ## compiler that does the building. 4 ## 5 ## Drives one stage of the README's tcc compilation chain: 6 ## tcc0 = cc.scm compiles tcc.flat.c -> tcc-boot2 (compile 1) 7 ## tcc1 = tcc-boot2 compiles tcc.flat.c -> tcc-tcc (compile 2) 8 ## tcc2 = tcc-tcc compiles tcc.flat.c -> tcc-tcc-tcc (compile 3) 9 ## 10 ## The compiler binary is supplied as the optional second positional 11 ## arg (default: build/$ARCH/tcc-boot2/tcc-boot2 — i.e. compile 2). 12 ## Output is linked against the same libc.o / mem.o / sys_stubs.o / 13 ## start.o the tcc-libc suite uses, plus per-target libtcc1 helpers: 14 ## - aarch64 / riscv64: lib-arm64.c (soft-float TFmode helpers — 15 ## __addtf3 / __extenddftf2 / …; libgcc-equivalent — same source 16 ## on both arches, gated internally by __riscv to skip the 17 ## __arm64_clear_cache wrapper; upstream tcc names the .o 18 ## lib-arm64.o for both via RISCV64_O = lib-arm64.o in 19 ## lib/Makefile). 20 ## - amd64: va_list.c (defines __va_start / __va_arg, the 21 ## intrinsics tcc's x86_64 codegen calls for variadic functions 22 ## — see tcc/include/stdarg.h on x86_64 and OBJ-x86_64 in 23 ## lib/Makefile). Long double on amd64 is x87 80-bit and tcc 24 ## emits native FPU instructions, so no soft-float helper is 25 ## needed. 26 ## Helpers are rebuilt by $CC into the same dirname as $OUT so each 27 ## stage owns its own lib-arm64.o / va_list.o. 28 ## 29 ## Env: ARCH in {aarch64, amd64, riscv64} 30 ## Usage: boot-build-tcc-tcc.sh <out> [<cc>] 31 32 set -eu 33 : "${ARCH:?ARCH must be set}" 34 [ "$#" -ge 1 ] && [ "$#" -le 2 ] \ 35 || { echo "usage: ARCH=<arch> $0 <out> [<cc>]" >&2; exit 2; } 36 37 OUT=$1 38 CC=${2:-build/$ARCH/tcc-boot2/tcc-boot2} 39 40 case "$ARCH" in 41 aarch64) LIB_TARGET_DEFINES="-D TCC_TARGET_ARM64=1 -D TCC_TARGET_ARM=1" ;; 42 amd64) LIB_TARGET_DEFINES= ;; 43 riscv64) LIB_TARGET_DEFINES="-D TCC_TARGET_RISCV64=1" ;; 44 *) echo "boot-build-tcc-tcc.sh: unsupported ARCH '$ARCH'" >&2; exit 2 ;; 45 esac 46 47 TCC_VENDOR=build/$ARCH/vendor/tcc 48 TCC_INC=$TCC_VENDOR/tcc-0.9.26-1147-gee75a10c/include 49 TCC_FLAT=$TCC_VENDOR/tcc.flat.c 50 LIBC_O=build/$ARCH/tcc-libc/libc.o 51 MEM_O=build/$ARCH/tcc-libc/mem.o 52 SYS_O=build/$ARCH/tcc-libc/sys_stubs.o 53 START_O=build/$ARCH/tcc-libc/start.o 54 WORK=$(dirname "$OUT") 55 56 mkdir -p "$WORK" 57 58 TCC_LIB_DIR=$TCC_VENDOR/tcc-0.9.26-1147-gee75a10c/lib 59 60 LIB_OBJS= 61 if [ "$ARCH" = "aarch64" ] || [ "$ARCH" = "riscv64" ]; then 62 # lib-arm64.o: TFmode soft-float helpers (__addtf3 / __extenddftf2 / 63 # …). tcc.flat.c references these for long double arithmetic; 64 # without them the final link fails with undefined symbols. Upstream 65 # tcc reuses lib-arm64.c for riscv64 too (RISCV64_O = lib-arm64.o 66 # in lib/Makefile); the file gates the arm64-specific cache-flush 67 # wrapper on !__riscv. 68 # shellcheck disable=SC2086 # LIB_TARGET_DEFINES is intentionally word-split. 69 "$CC" -nostdlib -I "$TCC_INC" \ 70 -D HAVE_CONFIG_H=1 $LIB_TARGET_DEFINES \ 71 -c -o "$WORK/lib-arm64.o" "$TCC_LIB_DIR/lib-arm64.c" 72 LIB_OBJS=$WORK/lib-arm64.o 73 elif [ "$ARCH" = "amd64" ]; then 74 # va_list.o: defines __va_start / __va_arg. tcc's x86_64 codegen 75 # lowers va_start / va_arg to direct calls into these intrinsics 76 # (see tcc/include/stdarg.h, lib/va_list.c). Without them the 77 # tcc-tcc link fails with undefined symbols. 78 "$CC" -nostdlib -I "$TCC_INC" \ 79 -D TCC_TARGET_X86_64=1 \ 80 -c -o "$WORK/va_list.o" "$TCC_LIB_DIR/va_list.c" 81 LIB_OBJS=$WORK/va_list.o 82 fi 83 84 # Compile + link the next-stage tcc in one $CC invocation. 85 # shellcheck disable=SC2086 # $LIB_OBJS is intentionally word-split (may be empty). 86 "$CC" -nostdlib -I "$TCC_INC" -include "$TCC_INC/stdarg.h" \ 87 "$START_O" "$SYS_O" "$MEM_O" "$LIBC_O" $LIB_OBJS \ 88 "$TCC_FLAT" -o "$OUT"