|
| 1 | +#!/bin/bash |
| 2 | +# Build gcc-2.8.1-psx natively on macOS (x86_64 and aarch64). |
| 3 | +# Produces Mach-O cc1 and companion binaries targeting mips-sony-psx. |
| 4 | +set -e |
| 5 | + |
| 6 | +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" |
| 7 | +PATCHES="$SCRIPT_DIR/patches" |
| 8 | +OUTDIR="$SCRIPT_DIR/build-gcc-2.8.1-psx" |
| 9 | +WORKDIR="$(mktemp -d)" |
| 10 | +trap 'rm -rf "$WORKDIR"' EXIT |
| 11 | + |
| 12 | +echo "Building gcc-2.8.1-psx for macOS in $WORKDIR" |
| 13 | + |
| 14 | +# Ensure we use the system compiler, not any cross-compiler wrappers that |
| 15 | +# may be in PATH (e.g. from a nix shell). |
| 16 | +export PATH="/usr/bin:/bin:/usr/sbin:/sbin:$PATH" |
| 17 | +unset CC CXX |
| 18 | + |
| 19 | +cd "$WORKDIR" |
| 20 | +curl -fL "https://mirrors.kernel.org/gnu/gcc/gcc-2.8.1.tar.gz" | tar xz |
| 21 | +cd gcc-2.8.1 |
| 22 | + |
| 23 | +# Apply the same patches as the Linux Dockerfile |
| 24 | +# Replace varargs.h with stdarg.h; some files are read-only from the tarball. |
| 25 | +grep -rl 'include <varargs\.h>' *.c | xargs chmod u+w |
| 26 | +sed -i '' 's/include <varargs\.h>/include <stdarg\.h>/g' *.c |
| 27 | +# macOS SDKs declare sys_nerr as 'const int'; fix the conflicting declarations. |
| 28 | +for f in gcc.c cp/g++.c; do |
| 29 | + [ -f "$f" ] && sed -i '' 's/^extern int sys_nerr;/extern const int sys_nerr;/' "$f" |
| 30 | +done |
| 31 | + |
| 32 | +patch -u -p1 obstack.h -i "$PATCHES/obstack-2.8.1.h.patch" |
| 33 | +patch -u -p1 config/mips/mips.h -i "$PATCHES/mips.patch" |
| 34 | +patch -su -p1 < "$PATCHES/psx.patch" |
| 35 | + |
| 36 | +# macOS: replace config.guess/config.sub with modern versions that know |
| 37 | +# about aarch64-apple-darwin, then add psx* to the OS list. |
| 38 | +# Pinned to specific commits for reproducibility. |
| 39 | +chmod +w config.guess config.sub |
| 40 | +curl -fsL "https://raw.githubusercontent.com/gcc-mirror/gcc/74af13c174714dd3b9f1ded4b39955f003c16361/config.guess" -o config.guess |
| 41 | +curl -fsL "https://raw.githubusercontent.com/gcc-mirror/gcc/6fad101f3063d722e3348d07dc93cf737f8709e4/config.sub" -o config.sub |
| 42 | +chmod +x config.guess config.sub |
| 43 | +sed -i '' 's/| hiux\* | abug | nacl\*/| psx* \\\ |
| 44 | +'"$(printf '\t')"' | hiux* | abug | nacl*/' config.sub |
| 45 | + |
| 46 | +# Add xm-darwin.h and teach configure about *-apple-darwin* hosts. |
| 47 | +cp "$PATCHES/xm-darwin.h" config/ |
| 48 | +chmod +w configure |
| 49 | +awk '/^\t\*\)$/ { buf=$0; next } |
| 50 | + buf != "" { if (!done && /echo.*Configuration.*not supported/) { |
| 51 | + print "\t*-apple-darwin*)"; print "\t\txm_file=xm-darwin.h" |
| 52 | + print "\t\tfixincludes=Makefile.in"; print "\t\t;;"; done=1 } |
| 53 | + print buf; buf="" } { print }' configure > configure.tmp |
| 54 | +mv configure.tmp configure |
| 55 | +chmod +x configure |
| 56 | + |
| 57 | +# Explicitly pass --host/--build so configure uses a single-arg config.sub |
| 58 | +# call (which modern config.sub accepts), rather than its multi-arg form. |
| 59 | +# Export CFLAGS so configure's compiler test (main(){return(0);}) passes under |
| 60 | +# modern clang, which rejects implicit int without -std=gnu89. |
| 61 | +DARWIN_HOST="$(uname -m)-apple-darwin" |
| 62 | +export CFLAGS="-std=gnu89 -w -Wno-int-conversion -Wno-implicit-function-declaration -Wno-return-mismatch" |
| 63 | +./configure \ |
| 64 | + --target=mips-sony-psx \ |
| 65 | + --host="$DARWIN_HOST" \ |
| 66 | + --build="$DARWIN_HOST" \ |
| 67 | + --prefix=/opt/cross \ |
| 68 | + --with-endian-little \ |
| 69 | + --with-gnu-as \ |
| 70 | + --disable-gprof \ |
| 71 | + --disable-gdb \ |
| 72 | + --disable-werror |
| 73 | + |
| 74 | +# insn-config.h is generated during the build but referenced early; touch |
| 75 | +# it to prevent spurious missing-file errors on some make versions. |
| 76 | +touch insn-config.h |
| 77 | + |
| 78 | +make --jobs "$(sysctl -n hw.ncpu)" cpp cc1 xgcc cc1plus g++ \ |
| 79 | + CFLAGS="-std=gnu89 -w -Wno-int-conversion -Wno-implicit-function-declaration -Wno-return-mismatch" |
| 80 | + |
| 81 | +# Run the same tests as the Dockerfile |
| 82 | +./cc1 -quiet -O2 "$SCRIPT_DIR/tests/little_endian.c" -o little_endian.s |
| 83 | +grep -E 'lbu\s\$2,0\(\$4\)' little_endian.s |
| 84 | +./cc1 -quiet -O2 "$SCRIPT_DIR/tests/section_attribute.c" -o /dev/null |
| 85 | +./cc1 -version </dev/null 2>&1 | grep -- -msoft-float |
| 86 | +./cc1 -version </dev/null 2>&1 | grep -- -msplit-addresses |
| 87 | +./cc1 -version </dev/null 2>&1 | grep -- -mgpopt |
| 88 | + |
| 89 | +mkdir -p "$OUTDIR" |
| 90 | +cp cpp cc1 xgcc cc1plus g++ "$OUTDIR/" |
| 91 | +mv "$OUTDIR/xgcc" "$OUTDIR/gcc" |
| 92 | +echo "Done — $OUTDIR/ ($(file "$OUTDIR/cc1" | cut -d: -f2 | xargs))" |
0 commit comments