From: Tulio A M Mendes Date: Fri, 3 Apr 2026 15:11:39 +0000 (-0300) Subject: fix: toolchain build reproducibility — header ordering, libcody, specs, GNU-stack X-Git-Url: https://projects.tadryanom.me/?a=commitdiff_plain;h=ac54401cc5abd8e50a738626c653c834c4eb7ffa;p=AdrOS.git fix: toolchain build reproducibility — header ordering, libcody, specs, GNU-stack - Move AdrOS sysroot headers installation to AFTER Newlib install so Newlib's make install doesn't overwrite our custom sys/dirent.h (fixes DIR unknown type error on first build) - Move Newlib header patching (sys/stat.h, sys/signal.h, sys/wait.h, glob.h) to after Newlib install (fixes sed on non-existent files) - Keep libcody in GCC host_libs — required by cc1plus (C++ frontend) - Add all-libcody to step 4 make targets - Move specs file creation to after step 4 (GCC full install overwrites it) - Add .note.GNU-stack to crti-adros.S (fixes executable stack warning) - Fix *.h glob in libgloss/adros cp (no .h files exist) - Add toolchain/build/ and toolchain/logs/ to .gitignore - Update README.md: clarify patches/ are reference diffs, add native-toolchain.patch --- diff --git a/.gitignore b/.gitignore index b58cd1fa..b40c275e 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,8 @@ isodir/ supplementary-material toolchain/src/ +toolchain/build/ +toolchain/logs/ # Editor/OS clutter .DS_Store diff --git a/toolchain/README.md b/toolchain/README.md index 1ba29547..7a3c6ca8 100644 --- a/toolchain/README.md +++ b/toolchain/README.md @@ -75,12 +75,14 @@ i686-adros-gcc -static -o myapp myapp.c ## AdrOS Target Patches -The `patches/` directory contains diffs that add `i686-adros` as a recognized -target in each component's build system: +The `patches/` directory contains **reference diffs** documenting the changes +that `build.sh` applies inline via `sed`. They are not applied with `patch`; +they exist for review and auditing: - **`binutils-adros.patch`**: `config.sub`, `bfd/config.bfd`, `gas/configure.tgt`, `ld/configure.tgt` - **`gcc-adros.patch`**: `config.sub`, `gcc/config.gcc`, `gcc/config/i386/adros.h`, `libgcc/config.host`, `crti.S`/`crtn.S` - **`newlib-adros.patch`**: `config.sub`, `newlib/configure.host`, `newlib/libc/include/sys/config.h`, `libgloss/configure.in`, autoconf files +- **`native-toolchain.patch`**: GMP/MPFR/MPC/ISL `config.sub` patches for native (Canadian cross) builds ### Key GCC Target Header (`adros.h`) diff --git a/toolchain/build.sh b/toolchain/build.sh index d2cc0c36..62f44e72 100755 --- a/toolchain/build.sh +++ b/toolchain/build.sh @@ -275,11 +275,9 @@ i[34567]86-*-adros*)\ done done - # Remove libcody from host_libs (requires C++ host compiler, breaks Canadian cross) - if grep -q 'libcody' "$d/configure" 2>/dev/null; then - sed -i 's/ libcody / /' "$d/configure" - step "Removed libcody from GCC host_libs" - fi + # NOTE: libcody is kept in host_libs — it is required by cc1plus (C++ + # frontend) which is built in step 4. Only a Canadian cross (host!=build) + # would have trouble, but our normal cross build has host==build. # crti.S and crtn.S for AdrOS if [[ ! -f "$d/libgcc/config/i386/crti-adros.S" ]]; then @@ -298,6 +296,8 @@ _init: _fini: push %ebp mov %esp, %ebp + + .section .note.GNU-stack,"",@progbits EOF cat > "$d/libgcc/config/i386/crtn-adros.S" <<'EOF' /* crtn.S for AdrOS — .init/.fini epilogue */ @@ -374,7 +374,7 @@ EOF # Copy/sync our libgloss/adros stubs into the Newlib source tree mkdir -p "$d/libgloss/adros" - cp -u "$ADROS_ROOT/newlib/libgloss/adros/"*.{c,S,h} "$d/libgloss/adros/" 2>/dev/null || true + cp -u "$ADROS_ROOT/newlib/libgloss/adros/"*.c "$ADROS_ROOT/newlib/libgloss/adros/"*.S "$d/libgloss/adros/" 2>/dev/null || true step "Synced libgloss/adros/ stubs" # Create libgloss/adros autoconf files if not present @@ -472,67 +472,6 @@ patch_gcc patch_newlib patch_bash -# ---- Install AdrOS-specific sysroot headers ---- -# NOTE: We do NOT copy the full ulibc headers here because they conflict -# with Newlib's POSIX-compliant headers (signal.h, errno.h, stdio.h, etc.). -# ulibc headers are for AdrOS userland built with -nostdlib; the cross- -# toolchain uses Newlib headers instead. Only truly AdrOS-specific headers -# (syscall numbers, ioctl defs) are installed. -msg "Installing AdrOS-specific sysroot headers" -mkdir -p "${SYSROOT}/include/sys" -for h in syscall.h; do - if [[ -f "$ADROS_ROOT/user/ulibc/include/$h" ]]; then - cp "$ADROS_ROOT/user/ulibc/include/$h" "${SYSROOT}/include/$h" - step "Installed $h" - fi -done - -# Install Linux/POSIX compatibility headers from newlib/sysroot_headers/. -# These provide stubs for headers that newlib doesn't supply but that -# ported software (Bash, Busybox) expects: asm/*, linux/*, net/*, -# netinet/*, sys/socket.h, poll.h, mntent.h, etc. -COMPAT_HEADERS="$ADROS_ROOT/newlib/sysroot_headers" -if [[ -d "$COMPAT_HEADERS" ]]; then - cp -r "$COMPAT_HEADERS"/* "${SYSROOT}/include/" - step "Installed $(find "$COMPAT_HEADERS" -type f | wc -l) sysroot compat headers" -fi - -# Patch newlib headers that need small AdrOS-specific additions. -# sys/stat.h — expose lstat()/mknod() for __adros__ (newlib guards them) -if ! grep -q '__adros__' "${SYSROOT}/include/sys/stat.h" 2>/dev/null; then - sed -i 's/defined(__SPU__) || defined(__rtems__) || defined(__CYGWIN__)/defined(__SPU__) || defined(__rtems__) || defined(__CYGWIN__) || defined(__adros__)/' \ - "${SYSROOT}/include/sys/stat.h" - step "Patched sys/stat.h (lstat/mknod for __adros__)" -fi - -# sys/signal.h — add SA_RESTART and friends to the non-rtems block -if ! grep -q 'SA_RESTART' "${SYSROOT}/include/sys/signal.h" 2>/dev/null; then - sed -i '/^#define SA_NOCLDSTOP 1/a\ -#define SA_RESTART 0x10000000\ -#define SA_NODEFER 0x40000000\ -#define SA_RESETHAND 0x80000000\ -#define SA_NOCLDWAIT 0x20000000\ -#define SA_SIGINFO 0x2' \ - "${SYSROOT}/include/sys/signal.h" - step "Patched sys/signal.h (SA_RESTART etc.)" -fi - -# sys/wait.h — add WCOREDUMP macro -if ! grep -q 'WCOREDUMP' "${SYSROOT}/include/sys/wait.h" 2>/dev/null; then - sed -i '/#define WTERMSIG/a\ -#define WCOREDUMP(w) ((w) \& 0x80)' \ - "${SYSROOT}/include/sys/wait.h" - step "Patched sys/wait.h (WCOREDUMP)" -fi - -# glob.h — add GLOB_NOMATCH -if ! grep -q 'GLOB_NOMATCH' "${SYSROOT}/include/glob.h" 2>/dev/null; then - sed -i '/#define.*GLOB_ABEND/a\ -#define GLOB_NOMATCH (-3) /* No match found. */' \ - "${SYSROOT}/include/glob.h" - step "Patched glob.h (GLOB_NOMATCH)" -fi - # ================================================================== # STEP 1: Build Binutils # ================================================================== @@ -614,6 +553,75 @@ else step "Newlib already installed" fi +# ---- Install AdrOS-specific sysroot headers ---- +# NOTE: These MUST be installed AFTER Newlib's make install, because Newlib +# overwrites headers (e.g. sys/dirent.h) that we need to replace with +# AdrOS-specific versions. On the first build the overwrite matters; +# on subsequent builds Newlib install is skipped but we re-install anyway. +# +# We do NOT copy the full ulibc headers here because they conflict with +# Newlib's POSIX-compliant headers (signal.h, errno.h, stdio.h, etc.). +# ulibc headers are for AdrOS userland built with -nostdlib; the cross- +# toolchain uses Newlib headers instead. Only truly AdrOS-specific headers +# (syscall numbers, ioctl defs) are installed. +msg "Installing AdrOS-specific sysroot headers" +mkdir -p "${SYSROOT}/include/sys" +for h in syscall.h; do + if [[ -f "$ADROS_ROOT/user/ulibc/include/$h" ]]; then + cp "$ADROS_ROOT/user/ulibc/include/$h" "${SYSROOT}/include/$h" + step "Installed $h" + fi +done + +# Install Linux/POSIX compatibility headers from newlib/sysroot_headers/. +# These provide stubs for headers that newlib doesn't supply but that +# ported software (Bash, Busybox) expects: asm/*, linux/*, net/*, +# netinet/*, sys/socket.h, poll.h, mntent.h, etc. +COMPAT_HEADERS="$ADROS_ROOT/newlib/sysroot_headers" +if [[ -d "$COMPAT_HEADERS" ]]; then + cp -r "$COMPAT_HEADERS"/* "${SYSROOT}/include/" + step "Installed $(find "$COMPAT_HEADERS" -type f | wc -l) sysroot compat headers" +fi + +# ---- Patch Newlib headers that need small AdrOS-specific additions ---- +# These must run AFTER Newlib install populates ${SYSROOT}/include/. +msg "Patching Newlib sysroot headers for AdrOS" + +# sys/stat.h — expose lstat()/mknod() for __adros__ (newlib guards them) +if ! grep -q '__adros__' "${SYSROOT}/include/sys/stat.h" 2>/dev/null; then + sed -i 's/defined(__SPU__) || defined(__rtems__) || defined(__CYGWIN__)/defined(__SPU__) || defined(__rtems__) || defined(__CYGWIN__) || defined(__adros__)/' \ + "${SYSROOT}/include/sys/stat.h" + step "Patched sys/stat.h (lstat/mknod for __adros__)" +fi + +# sys/signal.h — add SA_RESTART and friends to the non-rtems block +if ! grep -q 'SA_RESTART' "${SYSROOT}/include/sys/signal.h" 2>/dev/null; then + sed -i '/^#define SA_NOCLDSTOP 1/a\ +#define SA_RESTART 0x10000000\ +#define SA_NODEFER 0x40000000\ +#define SA_RESETHAND 0x80000000\ +#define SA_NOCLDWAIT 0x20000000\ +#define SA_SIGINFO 0x2' \ + "${SYSROOT}/include/sys/signal.h" + step "Patched sys/signal.h (SA_RESTART etc.)" +fi + +# sys/wait.h — add WCOREDUMP macro +if ! grep -q 'WCOREDUMP' "${SYSROOT}/include/sys/wait.h" 2>/dev/null; then + sed -i '/#define WTERMSIG/a\ +#define WCOREDUMP(w) ((w) \& 0x80)' \ + "${SYSROOT}/include/sys/wait.h" + step "Patched sys/wait.h (WCOREDUMP)" +fi + +# glob.h — add GLOB_NOMATCH +if ! grep -q 'GLOB_NOMATCH' "${SYSROOT}/include/glob.h" 2>/dev/null; then + sed -i '/#define.*GLOB_ABEND/a\ +#define GLOB_NOMATCH (-3) /* No match found. */' \ + "${SYSROOT}/include/glob.h" + step "Patched glob.h (GLOB_NOMATCH)" +fi + # ================================================================== # STEP 3b: Build libgloss/adros (crt0.o + libadros.a) # ================================================================== @@ -633,18 +641,6 @@ else step "libadros.a already installed" fi -# ================================================================== -# STEP 3c: Create GCC specs file (fix LIB_SPEC link order) -# ================================================================== -SPECS_FILE="$PREFIX/lib/gcc/${TARGET}/${GCC_VER}/specs" -if [[ ! -f "$SPECS_FILE" ]]; then - ${TARGET}-gcc -dumpspecs > "$SPECS_FILE" - sed -i 's/-lc -ladros -lgcc/--start-group -lc -ladros --end-group -lgcc/' "$SPECS_FILE" - step "Created specs file with corrected LIB_SPEC" -else - step "Specs file already exists" -fi - # ================================================================== # STEP 4: Rebuild GCC (full, with Newlib) # ================================================================== @@ -666,7 +662,7 @@ if [[ ! -f "$BUILD_DIR/gcc-full/.built" ]]; then --disable-libquadmath \ 2>&1 | tee "$LOG_DIR/gcc-full-configure.log" - make -j"$JOBS" all-gcc all-target-libgcc \ + make -j"$JOBS" all-libcody all-gcc all-target-libgcc \ 2>&1 | tee "$LOG_DIR/gcc-full-build.log" make install-gcc install-target-libgcc \ 2>&1 | tee "$LOG_DIR/gcc-full-install.log" @@ -676,6 +672,19 @@ else step "Full GCC already installed" fi +# ================================================================== +# STEP 4b: Create GCC specs file (fix LIB_SPEC link order) +# ================================================================== +# Must run AFTER step 4 — make install-gcc overwrites the GCC lib directory. +SPECS_FILE="$PREFIX/lib/gcc/${TARGET}/${GCC_VER}/specs" +if [[ ! -f "$SPECS_FILE" ]]; then + ${TARGET}-gcc -dumpspecs > "$SPECS_FILE" + sed -i 's/-lc -ladros -lgcc/--start-group -lc -ladros --end-group -lgcc/' "$SPECS_FILE" + step "Created specs file with corrected LIB_SPEC" +else + step "Specs file already exists" +fi + # ================================================================== # STEP 5: Cross-compile Bash (optional) # ==================================================================