stage3-rebuild.sh (10369B)
1 #!/bin/sh 2 ## scripts/stage3-rebuild.sh — drive the tcc-boot1 / tcc-boot2 chain 3 ## inside a busybox container, consuming stage 2's tcc-boot0-mes. 4 ## 5 ## Mirrors live-bootstrap's pass1.kaem (steps/tcc-0.9.26) chain: 6 ## tcc-boot0-mes (= tcc-boot0 slot) 7 ## → rebuild libc → tcc-boot1 8 ## → rebuild libc → tcc-boot2 (= "final 0.9.26") 9 ## 10 ## Each rebuild compiles the **real**, unflattened tcc-0.9.26 sources 11 ## (the patched tree at $WORK/tcc-0.9.26-1147-gee75a10c) using the 12 ## previous-stage tcc, with the full live-bootstrap define set 13 ## (HAVE_FLOAT, HAVE_BITFIELD, HAVE_SETJMP added on top of the stage 1 14 ## flatten set). 15 ## 16 ## Pre-condition: 17 ## build/amd64/vendor/tcc/tcc-boot0-mes 18 ## build/amd64/vendor/tcc/stage3-input/ (staged by stage 2) 19 ## build/amd64/vendor/tcc/tcc-0.9.26-1147-gee75a10c/ (patched, from stage 1) 20 ## build/amd64/vendor/tcc/mes-0.27.1/ (from stage 2) 21 ## 22 ## Container: docker.io/library/busybox:musl on linux/amd64. 23 ## Tools used inside: busybox sh + tcc-boot0-mes (which provides its own 24 ## preprocessor, assembler, linker, and `-ar`). 25 ## 26 ## Status: stage 3 cannot complete on macOS arm64 hosts today — Issue §3 27 ## (tcc-boot0-mes segfaults at startup under QEMU x86_64) blocks the 28 ## very first step. The script is correct; it will run end-to-end on 29 ## native x86_64 hardware or once a tcc 0.9.28rc backport patches the 30 ## prologue/_DYNAMIC issues. The failure is reported clearly so the 31 ## blocker is visible. 32 ## 33 ## Usage: 34 ## scripts/stage3-rebuild.sh [--arch X86_64] 35 36 set -eu 37 38 ARCH=X86_64 39 while [ $# -gt 0 ]; do 40 case "$1" in 41 --arch) ARCH=$2; shift 2 ;; 42 -h|--help) sed -n 's/^## \{0,1\}//p' "$0"; exit 0 ;; 43 *) echo "unknown arg: $1" >&2; exit 2 ;; 44 esac 45 done 46 47 if [ "$ARCH" != "X86_64" ]; then 48 echo "stage3 currently only supports X86_64" >&2 49 exit 2 50 fi 51 MES_ARCH=x86_64 52 BOOT_ARCH=amd64 53 54 ROOT=$(cd "$(dirname "$0")/.." && pwd) 55 WORK=$ROOT/build/$BOOT_ARCH/vendor/tcc 56 TCC_PKG=tcc-0.9.26-1147-gee75a10c 57 MES_PKG=mes-0.27.1 58 59 [ -x "$WORK/tcc-boot0-mes" ] || { echo "missing $WORK/tcc-boot0-mes — run stage2-alpine.sh" >&2; exit 1; } 60 [ -d "$WORK/stage3-input" ] || { echo "missing $WORK/stage3-input — run stage2-alpine.sh" >&2; exit 1; } 61 [ -d "$WORK/$TCC_PKG" ] || { echo "missing $WORK/$TCC_PKG — run stage1-flatten.sh" >&2; exit 1; } 62 [ -d "$WORK/$MES_PKG" ] || { echo "missing $WORK/$MES_PKG — run stage2-alpine.sh" >&2; exit 1; } 63 command -v podman >/dev/null 2>&1 || { echo "podman required" >&2; exit 2; } 64 65 echo "=== stage 3: tcc-boot1 / tcc-boot2 via busybox:musl ===" 66 echo "(Issue §3 may block on macOS arm64 / QEMU; native x86_64 expected to succeed)" 67 68 podman run --rm -i --platform linux/amd64 \ 69 -v "$ROOT":/work -w /work \ 70 docker.io/library/busybox:musl sh -s "$ARCH" "$MES_ARCH" "$TCC_PKG" "$MES_PKG" "$BOOT_ARCH" <<'CONTAINER_SCRIPT' 71 set -eu 72 ARCH=$1 73 MES_ARCH=$2 74 TCC_PKG=$3 75 MES_PKG=$4 76 BOOT_ARCH=$5 77 WORK=/work/build/$BOOT_ARCH/vendor/tcc 78 79 # --- install tcc-boot0-mes + mes libc bits at baked-in paths -------- 80 mkdir -p /lib/tcc /include/mes /bin 81 cp "$WORK/stage3-input/lib/libc.a" /lib/libc.a 82 cp "$WORK/stage3-input/lib/crt1.o" /lib/crt1.o 83 cp "$WORK/stage3-input/lib/crtn.o" /lib/crtn.o 84 cp "$WORK/stage3-input/lib/crti.o" /lib/crti.o 85 cp "$WORK/stage3-input/lib/tcc/libtcc1.a" /lib/tcc/libtcc1.a 86 cp -r "$WORK/stage3-input/include/mes/." /include/mes/ 87 88 TCC=$WORK/tcc-boot0-mes 89 90 echo "--- tcc-boot0-mes -version (smoke; Issue §3 may SEGV here) ---" 91 "$TCC" -version 92 93 INC_MES=/include/mes 94 TCC_DEFS_BUILD="-D BOOTSTRAP=1 \ 95 -D HAVE_FLOAT=1 \ 96 -D HAVE_BITFIELD=1 \ 97 -D HAVE_LONG_LONG=1 \ 98 -D HAVE_SETJMP=1 \ 99 -D TCC_TARGET_${ARCH}=1 \ 100 -D CONFIG_TCCDIR=\"/lib/tcc\" \ 101 -D CONFIG_TCC_CRTPREFIX=\"/lib\" \ 102 -D CONFIG_TCC_ELFINTERP=\"/mes/loader\" \ 103 -D CONFIG_TCC_LIBPATHS=\"/lib:/lib/tcc\" \ 104 -D CONFIG_TCC_SYSINCLUDEPATHS=\"/include/mes\" \ 105 -D TCC_LIBGCC=\"/lib/libc.a\" \ 106 -D TCC_LIBTCC1=\"libtcc1.a\" \ 107 -D CONFIG_TCCBOOT=1 \ 108 -D CONFIG_TCC_STATIC=1 \ 109 -D CONFIG_USE_LIBGCC=1 \ 110 -D TCC_VERSION=\"0.9.26\" \ 111 -D ONE_SOURCE=1" 112 113 # Helper: rebuild mes libc with the given tcc binary, install to /lib + /lib/tcc. 114 # Mirrors pass1.kaem's "Recompile libc" block after each tcc-bootN. 115 rebuild_libc() { 116 cc=$1 117 label=$2 118 echo "--- $label: rebuilding mes libc ---" 119 cd "$WORK/$MES_PKG" 120 "$cc" -c -D HAVE_CONFIG_H=1 -I include -I include/linux/$MES_ARCH \ 121 -o /lib/crt1.o lib/linux/$MES_ARCH-mes-gcc/crt1.c 122 123 "$cc" -c -D HAVE_CONFIG_H=1 -D HAVE_LONG_LONG=1 -D HAVE_FLOAT=1 \ 124 -I include -I include/linux/$MES_ARCH \ 125 -o /tmp/libtcc1.o lib/libtcc1.c 126 "$cc" -ar cr /lib/tcc/libtcc1.a /tmp/libtcc1.o 127 128 # libc.a: same per-file approach as stage 2 (Issue §2 workaround). 129 rm -rf /tmp/objs && mkdir -p /tmp/objs 130 cd lib 131 OBJS= 132 for f in $ALL_LIBC_FILES; do 133 name=$(echo "$f" | tr / _) 134 o=/tmp/objs/${name%.c}.o 135 "$cc" -c -D HAVE_CONFIG_H=1 -I ../include -I ../include/linux/$MES_ARCH \ 136 -o "$o" "$f" 137 OBJS="$OBJS $o" 138 done 139 "$cc" -ar cr /lib/libc.a $OBJS 140 cd "$WORK/$MES_PKG/.." 141 } 142 143 # Helper: compile tcc.c (real, unflattened) into a new tcc binary. 144 # Mirrors pass1.kaem's tcc-boot0/1/2 invocations. 145 build_tcc() { 146 cc=$1 147 out=$2 148 echo "--- $out: $cc compiling real tcc.c ---" 149 cd "$WORK/$TCC_PKG" 150 eval "\"$cc\" -g -static -o \"$WORK/$out\" \ 151 $TCC_DEFS_BUILD \ 152 -I . -I $INC_MES \ 153 -L . -L /lib \ 154 tcc.c" 155 "$WORK/$out" -version 156 } 157 158 # Same canonical mes libc list as stage 2 + pass1.kaem. 159 ALL_LIBC_FILES="ctype/isalnum.c ctype/isalpha.c ctype/isascii.c ctype/iscntrl.c \ 160 ctype/isdigit.c ctype/isgraph.c ctype/islower.c ctype/isnumber.c \ 161 ctype/isprint.c ctype/ispunct.c ctype/isspace.c ctype/isupper.c \ 162 ctype/isxdigit.c ctype/tolower.c ctype/toupper.c \ 163 dirent/closedir.c dirent/__getdirentries.c dirent/opendir.c \ 164 linux/readdir.c linux/access.c linux/brk.c linux/chdir.c linux/chmod.c \ 165 linux/clock_gettime.c linux/close.c linux/dup2.c linux/dup.c linux/execve.c \ 166 linux/fcntl.c linux/fork.c linux/fsync.c linux/fstat.c linux/_getcwd.c \ 167 linux/getdents.c linux/getegid.c linux/geteuid.c linux/getgid.c linux/getpid.c \ 168 linux/getppid.c linux/getrusage.c linux/gettimeofday.c linux/getuid.c \ 169 linux/ioctl.c linux/ioctl3.c linux/kill.c linux/link.c linux/lseek.c \ 170 linux/lstat.c linux/malloc.c linux/mkdir.c linux/mknod.c linux/nanosleep.c \ 171 linux/_open3.c linux/pipe.c linux/_read.c linux/readlink.c linux/rename.c \ 172 linux/rmdir.c linux/setgid.c linux/settimer.c linux/setuid.c linux/signal.c \ 173 linux/sigprogmask.c linux/symlink.c linux/stat.c linux/time.c linux/unlink.c \ 174 linux/waitpid.c linux/wait4.c \ 175 linux/${MES_ARCH}-mes-gcc/_exit.c linux/${MES_ARCH}-mes-gcc/syscall.c \ 176 linux/${MES_ARCH}-mes-gcc/_write.c \ 177 math/ceil.c math/fabs.c math/floor.c \ 178 mes/abtod.c mes/abtol.c mes/__assert_fail.c mes/assert_msg.c \ 179 mes/__buffered_read.c mes/__init_io.c mes/cast.c mes/dtoab.c \ 180 mes/eputc.c mes/eputs.c mes/fdgetc.c mes/fdgets.c mes/fdputc.c mes/fdputs.c \ 181 mes/fdungetc.c mes/globals.c mes/itoa.c mes/ltoab.c mes/ltoa.c \ 182 mes/__mes_debug.c mes/mes_open.c mes/ntoab.c mes/oputc.c mes/oputs.c \ 183 mes/search-path.c mes/ultoa.c mes/utoa.c \ 184 posix/alarm.c posix/buffered-read.c posix/execl.c posix/execlp.c \ 185 posix/execv.c posix/execvp.c posix/getcwd.c posix/getenv.c posix/isatty.c \ 186 posix/mktemp.c posix/open.c posix/pathconf.c posix/raise.c posix/sbrk.c \ 187 posix/setenv.c posix/sleep.c posix/unsetenv.c posix/wait.c posix/write.c \ 188 stdio/clearerr.c stdio/fclose.c stdio/fdopen.c stdio/feof.c stdio/ferror.c \ 189 stdio/fflush.c stdio/fgetc.c stdio/fgets.c stdio/fileno.c stdio/fopen.c \ 190 stdio/fprintf.c stdio/fputc.c stdio/fputs.c stdio/fread.c stdio/freopen.c \ 191 stdio/fscanf.c stdio/fseek.c stdio/ftell.c stdio/fwrite.c stdio/getc.c \ 192 stdio/getchar.c stdio/perror.c stdio/printf.c stdio/putc.c stdio/putchar.c \ 193 stdio/remove.c stdio/snprintf.c stdio/sprintf.c stdio/sscanf.c stdio/ungetc.c \ 194 stdio/vfprintf.c stdio/vfscanf.c stdio/vprintf.c stdio/vsnprintf.c \ 195 stdio/vsprintf.c stdio/vsscanf.c \ 196 stdlib/abort.c stdlib/abs.c stdlib/alloca.c stdlib/atexit.c stdlib/atof.c \ 197 stdlib/atoi.c stdlib/atol.c stdlib/calloc.c stdlib/__exit.c stdlib/exit.c \ 198 stdlib/free.c stdlib/mbstowcs.c stdlib/puts.c stdlib/qsort.c stdlib/realloc.c \ 199 stdlib/strtod.c stdlib/strtof.c stdlib/strtol.c stdlib/strtold.c \ 200 stdlib/strtoll.c stdlib/strtoul.c stdlib/strtoull.c \ 201 string/bcmp.c string/bcopy.c string/bzero.c string/index.c string/memchr.c \ 202 string/memcmp.c string/memcpy.c string/memmem.c string/memmove.c string/memset.c \ 203 string/rindex.c string/strcat.c string/strchr.c string/strcmp.c string/strcpy.c \ 204 string/strcspn.c string/strdup.c string/strerror.c string/strlen.c \ 205 string/strlwr.c string/strncat.c string/strncmp.c string/strncpy.c \ 206 string/strpbrk.c string/strrchr.c string/strspn.c string/strstr.c string/strupr.c \ 207 stub/atan2.c stub/bsearch.c stub/chown.c stub/__cleanup.c stub/cos.c \ 208 stub/ctime.c stub/exp.c stub/fpurge.c stub/freadahead.c stub/frexp.c \ 209 stub/getgrgid.c stub/getgrnam.c stub/getlogin.c stub/getpgid.c stub/getpgrp.c \ 210 stub/getpwnam.c stub/getpwuid.c stub/gmtime.c stub/ldexp.c stub/localtime.c \ 211 stub/log.c stub/mktime.c stub/modf.c stub/mprotect.c stub/pclose.c \ 212 stub/popen.c stub/pow.c stub/putenv.c stub/rand.c stub/realpath.c stub/rewind.c \ 213 stub/setbuf.c stub/setgrent.c stub/setlocale.c stub/setvbuf.c stub/sigaction.c \ 214 stub/sigaddset.c stub/sigblock.c stub/sigdelset.c stub/sigemptyset.c \ 215 stub/sigsetmask.c stub/sin.c stub/sys_siglist.c stub/system.c stub/sqrt.c \ 216 stub/strftime.c stub/times.c stub/ttyname.c stub/umask.c stub/utime.c \ 217 ${MES_ARCH}-mes-gcc/setjmp.c" 218 219 # --- Pass 1: tcc-boot0-mes -> tcc-boot1 ----------------------------- 220 rebuild_libc "$TCC" "tcc-boot0-mes" 221 build_tcc "$TCC" "tcc-boot1" 222 223 # --- Pass 2: tcc-boot1 -> tcc-boot2 (final 0.9.26) ------------------ 224 TCC=$WORK/tcc-boot1 225 rebuild_libc "$TCC" "tcc-boot1" 226 build_tcc "$TCC" "tcc-boot2" 227 228 echo 229 echo "=== stage 3: tcc-boot2 is the final 0.9.26 build ===" 230 ls -la "$WORK/tcc-boot1" "$WORK/tcc-boot2" 231 CONTAINER_SCRIPT 232 233 echo 234 echo "=== stage 3 artifacts ===" 235 ls -la "$WORK/tcc-boot1" "$WORK/tcc-boot2" 2>/dev/null || \ 236 echo "(stage 3 did not complete — see container output above; likely Issue §3)"