Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions .github/workflows/build-macos.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Compile GCC (macOS)
on:
push:
tags: '*'
branches: [master]
paths-ignore:
- README.md
pull_request:
branches: [master]
jobs:
build:
runs-on: macos-latest
strategy:
fail-fast: false
matrix:
version:
- 2.7.2-psx
- 2.7.2-cdk
- 2.8.1-psx
name: Build GCC ${{ matrix.version }} (macOS)
steps:
- name: Clone repository
uses: actions/checkout@v4
- name: Install dependencies
run: |
# byacc is required for gcc-2.7.2-cdk
brew install byacc
- name: Build GCC
run: VERSION=${{ matrix.version }} PLATFORM=macos make
- name: Create release archive
shell: bash
run: |
cd build-gcc-${{ matrix.version }}
tar -czvf ../gcc-${{ matrix.version }}-macos.tar.gz *
- name: Create artifact
uses: actions/upload-artifact@v4
with:
name: gcc-${{ matrix.version }}-macos
path: gcc-${{ matrix.version }}-macos.tar.gz
- name: Publish release
uses: softprops/action-gh-release@v2
if: startsWith(github.ref, 'refs/tags/')
with:
files: |
gcc-${{ matrix.version }}-macos.tar.gz
12 changes: 12 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
PLATFORM ?= linux

all: check-version
ifeq ($(PLATFORM),macos)
bash gcc-$(VERSION)-macos.sh
else
docker build -f gcc-$(VERSION).Dockerfile --target export --output build-gcc-$(VERSION) .
endif

clean:
rm -rf build-gcc-*/
Expand All @@ -8,8 +14,14 @@ check-version:
ifndef VERSION
$(error You must specify a VERSION e.g. `make VERSION=2.8.1`)
endif
ifeq ($(PLATFORM),macos)
ifeq ($(wildcard gcc-$(VERSION)-macos.sh),)
$(error Building GCC $(VERSION) for macOS is not currently supported)
endif
else
ifeq ($(wildcard gcc-$(VERSION).Dockerfile),)
$(error Building GCC $(VERSION) is not currently supported)
endif
endif

.PHONY: all check-version
89 changes: 89 additions & 0 deletions gcc-2.7.2-cdk-macos.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#!/bin/bash
# Build gcc-2.7.2-cdk natively on macOS (x86_64 and aarch64).
# Produces Mach-O cc1 and companion binaries targeting mips-sony-psx.
#
# Requires: byacc (install via Homebrew: brew install byacc)
set -e

if ! command -v byacc >/dev/null 2>&1; then
echo "Error: byacc is required. Install it with: brew install byacc" >&2
exit 1
fi

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PATCHES="$SCRIPT_DIR/patches"
OUTDIR="$SCRIPT_DIR/build-gcc-2.7.2-cdk"
WORKDIR="$(mktemp -d)"
trap 'rm -rf "$WORKDIR"' EXIT

echo "Building gcc-2.7.2-cdk for macOS in $WORKDIR"

# Ensure we use the system compiler and tools, not any cross-compiler wrappers
# that may be in PATH (e.g. from a nix shell).
export PATH="/usr/bin:/bin:/usr/sbin:/sbin:$PATH"
unset CC CXX

cd "$WORKDIR"
curl -fL "https://github.com/decompals/old-gcc/releases/download/0.14/b18.tar.gz" | tar xz
cd cdk-gcc-b18

# Apply the same patches as the Linux Dockerfile
# macOS SDKs declare sys_nerr as 'const int'; fix the conflicting declarations.
for f in gcc.c cp/g++.c; do
[ -f "$f" ] && sed -i '' 's/^extern int sys_nerr;/extern const int sys_nerr;/' "$f"
done
patch -u -p1 Makefile.in -i "$PATCHES/Makefile-2.7.2-cdk.in.patch"
patch -u -p1 obstack.h -i "$PATCHES/obstack-2.7.2-cdk.h.patch"
patch -u -p1 config/mips/mips.h -i "$PATCHES/mipsel-2.7-cdk.patch"
patch -su -p1 < "$PATCHES/psx-2.7.2-cdk.patch"

# macOS: replace config.guess/config.sub with modern versions that know
# about aarch64-apple-darwin, then add psx* to the OS list.
# Pinned to specific commits for reproducibility.
chmod +w config.guess config.sub
curl -fsL "https://raw.githubusercontent.com/gcc-mirror/gcc/74af13c174714dd3b9f1ded4b39955f003c16361/config.guess" -o config.guess
curl -fsL "https://raw.githubusercontent.com/gcc-mirror/gcc/6fad101f3063d722e3348d07dc93cf737f8709e4/config.sub" -o config.sub
chmod +x config.guess config.sub
sed -i '' 's/| hiux\* | abug | nacl\*/| psx* \\\
'"$(printf '\t')"' | hiux* | abug | nacl*/' config.sub

# Add xm-darwin.h and teach configure about *-apple-darwin* hosts.
cp "$PATCHES/xm-darwin.h" config/
chmod +w configure
awk '/^\t\*\)$/ { buf=$0; next }
buf != "" { if (!done && /echo.*Configuration.*not supported/) {
print "\t*-apple-darwin*)"; print "\t\txm_file=xm-darwin.h"
print "\t\tfixincludes=Makefile.in"; print "\t\t;;"; done=1 }
print buf; buf="" } { print }' configure > configure.tmp
mv configure.tmp configure
chmod +x configure

./configure \
--target=mips-sony-psx \
--prefix=/opt/cross \
--with-endian-little \
--with-gnu-as \
--disable-gprof \
--disable-gdb \
--disable-werror

# Compile the __eprintf stub — this symbol was removed from macOS SDKs
# after 10.14 but is referenced by the exception-handling code.
EPRINTF_OBJ="$PWD/eprintf-darwin.o"
cc -std=gnu89 -c "$PATCHES/eprintf-darwin.c" -o "$EPRINTF_OBJ"

# Build single-threaded: parallel yacc invocations race on y.tab.h,
# causing bi-parser.h to be generated with the wrong grammar.
make cpp cc1 xgcc cc1plus g++ \
CFLAGS="-std=gnu89 -w -Wno-int-conversion -Wno-implicit-function-declaration -Wno-return-mismatch" \
LDFLAGS="$EPRINTF_OBJ"

# Run the same tests as the Dockerfile
./cc1 -quiet -O2 "$SCRIPT_DIR/tests/little_endian.c" -o little_endian.s
grep -E 'lbu\s\$2,0\(\$4\)' little_endian.s
./cc1 -quiet -O2 "$SCRIPT_DIR/tests/section_attribute.c" -o /dev/null

mkdir -p "$OUTDIR"
cp cpp cc1 xgcc cc1plus g++ "$OUTDIR/"
mv "$OUTDIR/xgcc" "$OUTDIR/gcc"
echo "Done — $OUTDIR/ ($(file "$OUTDIR/cc1" | cut -d: -f2 | xargs))"
79 changes: 79 additions & 0 deletions gcc-2.7.2-psx-macos.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#!/bin/bash
# Build gcc-2.7.2-psx natively on macOS (x86_64 and aarch64).
# Produces Mach-O cc1 and companion binaries targeting mips-sony-psx.
set -e

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PATCHES="$SCRIPT_DIR/patches"
OUTDIR="$SCRIPT_DIR/build-gcc-2.7.2-psx"
WORKDIR="$(mktemp -d)"
trap 'rm -rf "$WORKDIR"' EXIT

echo "Building gcc-2.7.2-psx for macOS in $WORKDIR"

# Ensure we use the system compiler and tools, not any cross-compiler wrappers
# that may be in PATH (e.g. from a nix shell).
export PATH="/usr/bin:/bin:/usr/sbin:/sbin:$PATH"
unset CC CXX

cd "$WORKDIR"
curl -fL "https://ftp.gnu.org/old-gnu/gcc/gcc-2.7.2.tar.gz" | tar xz
cd gcc-2.7.2

# Apply the same patches as the Linux Dockerfile
# Replace varargs.h with stdarg.h; some files are read-only from the tarball.
grep -rl 'include <varargs\.h>' *.c | xargs chmod u+w
sed -i '' 's/include <varargs\.h>/include <stdarg\.h>/g' *.c
# macOS SDKs declare sys_nerr as 'const int'; fix the conflicting declarations.
for f in gcc.c cp/g++.c; do
[ -f "$f" ] && sed -i '' 's/^extern int sys_nerr;/extern const int sys_nerr;/' "$f"
done

patch -u -p1 obstack.h -i "$PATCHES/obstack-2.7.2.h.patch"
patch -u -p1 configure -i "$PATCHES/configure.patch"
patch -u -p1 config/mips/mips.h -i "$PATCHES/mipsel-2.7.patch"
patch -su -p1 < "$PATCHES/psx-2.5.7.patch"

# macOS: replace config.guess/config.sub with modern versions that know
# about aarch64-apple-darwin, then add psx* to the OS list.
# Pinned to specific commits for reproducibility.
chmod +w config.guess config.sub
curl -fsL "https://raw.githubusercontent.com/gcc-mirror/gcc/74af13c174714dd3b9f1ded4b39955f003c16361/config.guess" -o config.guess
curl -fsL "https://raw.githubusercontent.com/gcc-mirror/gcc/6fad101f3063d722e3348d07dc93cf737f8709e4/config.sub" -o config.sub
chmod +x config.guess config.sub
sed -i '' 's/| hiux\* | abug | nacl\*/| psx* \\\
'"$(printf '\t')"' | hiux* | abug | nacl*/' config.sub

# Add xm-darwin.h and teach configure about *-apple-darwin* hosts.
cp "$PATCHES/xm-darwin.h" config/
chmod +w configure
awk '/^\t\*\)$/ { buf=$0; next }
buf != "" { if (!done && /echo.*Configuration.*not supported/) {
print "\t*-apple-darwin*)"; print "\t\txm_file=xm-darwin.h"
print "\t\tfixincludes=Makefile.in"; print "\t\t;;"; done=1 }
print buf; buf="" } { print }' configure > configure.tmp
mv configure.tmp configure
chmod +x configure

./configure \
--target=mips-sony-psx \
--prefix=/opt/cross \
--with-endian-little \
--with-gnu-as \
--disable-gprof \
--disable-gdb \
--disable-werror

make --jobs "$(sysctl -n hw.ncpu)" cpp cc1 xgcc cc1plus g++ \
CFLAGS="-std=gnu89 -w -Wno-int-conversion -Wno-implicit-function-declaration -Wno-return-mismatch"

# Run the same tests as the Dockerfile
./cc1 -quiet -O2 "$SCRIPT_DIR/tests/little_endian.c" -o little_endian.s
grep -E 'lbu\s\$2,0\(\$4\)' little_endian.s
./cc1 -quiet -O2 "$SCRIPT_DIR/tests/section_attribute.c" -o /dev/null
./cc1 -quiet -help </dev/null 2>&1 | grep -- -msoft-float

mkdir -p "$OUTDIR"
cp cpp cc1 xgcc cc1plus g++ "$OUTDIR/"
mv "$OUTDIR/xgcc" "$OUTDIR/gcc"
echo "Done — $OUTDIR/ ($(file "$OUTDIR/cc1" | cut -d: -f2 | xargs))"
92 changes: 92 additions & 0 deletions gcc-2.8.1-psx-macos.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#!/bin/bash
# Build gcc-2.8.1-psx natively on macOS (x86_64 and aarch64).
# Produces Mach-O cc1 and companion binaries targeting mips-sony-psx.
set -e

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PATCHES="$SCRIPT_DIR/patches"
OUTDIR="$SCRIPT_DIR/build-gcc-2.8.1-psx"
WORKDIR="$(mktemp -d)"
trap 'rm -rf "$WORKDIR"' EXIT

echo "Building gcc-2.8.1-psx for macOS in $WORKDIR"

# Ensure we use the system compiler, not any cross-compiler wrappers that
# may be in PATH (e.g. from a nix shell).
export PATH="/usr/bin:/bin:/usr/sbin:/sbin:$PATH"
unset CC CXX

cd "$WORKDIR"
curl -fL "https://mirrors.kernel.org/gnu/gcc/gcc-2.8.1.tar.gz" | tar xz
cd gcc-2.8.1

# Apply the same patches as the Linux Dockerfile
# Replace varargs.h with stdarg.h; some files are read-only from the tarball.
grep -rl 'include <varargs\.h>' *.c | xargs chmod u+w
sed -i '' 's/include <varargs\.h>/include <stdarg\.h>/g' *.c
# macOS SDKs declare sys_nerr as 'const int'; fix the conflicting declarations.
for f in gcc.c cp/g++.c; do
[ -f "$f" ] && sed -i '' 's/^extern int sys_nerr;/extern const int sys_nerr;/' "$f"
done

patch -u -p1 obstack.h -i "$PATCHES/obstack-2.8.1.h.patch"
patch -u -p1 config/mips/mips.h -i "$PATCHES/mips.patch"
patch -su -p1 < "$PATCHES/psx.patch"

# macOS: replace config.guess/config.sub with modern versions that know
# about aarch64-apple-darwin, then add psx* to the OS list.
# Pinned to specific commits for reproducibility.
chmod +w config.guess config.sub
curl -fsL "https://raw.githubusercontent.com/gcc-mirror/gcc/74af13c174714dd3b9f1ded4b39955f003c16361/config.guess" -o config.guess
curl -fsL "https://raw.githubusercontent.com/gcc-mirror/gcc/6fad101f3063d722e3348d07dc93cf737f8709e4/config.sub" -o config.sub
chmod +x config.guess config.sub
sed -i '' 's/| hiux\* | abug | nacl\*/| psx* \\\
'"$(printf '\t')"' | hiux* | abug | nacl*/' config.sub

# Add xm-darwin.h and teach configure about *-apple-darwin* hosts.
cp "$PATCHES/xm-darwin.h" config/
chmod +w configure
awk '/^\t\*\)$/ { buf=$0; next }
buf != "" { if (!done && /echo.*Configuration.*not supported/) {
print "\t*-apple-darwin*)"; print "\t\txm_file=xm-darwin.h"
print "\t\tfixincludes=Makefile.in"; print "\t\t;;"; done=1 }
print buf; buf="" } { print }' configure > configure.tmp
mv configure.tmp configure
chmod +x configure

# Explicitly pass --host/--build so configure uses a single-arg config.sub
# call (which modern config.sub accepts), rather than its multi-arg form.
# Export CFLAGS so configure's compiler test (main(){return(0);}) passes under
# modern clang, which rejects implicit int without -std=gnu89.
DARWIN_HOST="$(uname -m)-apple-darwin"
export CFLAGS="-std=gnu89 -w -Wno-int-conversion -Wno-implicit-function-declaration -Wno-return-mismatch"
./configure \
--target=mips-sony-psx \
--host="$DARWIN_HOST" \
--build="$DARWIN_HOST" \
--prefix=/opt/cross \
--with-endian-little \
--with-gnu-as \
--disable-gprof \
--disable-gdb \
--disable-werror

# insn-config.h is generated during the build but referenced early; touch
# it to prevent spurious missing-file errors on some make versions.
touch insn-config.h

make --jobs "$(sysctl -n hw.ncpu)" cpp cc1 xgcc cc1plus g++ \
CFLAGS="-std=gnu89 -w -Wno-int-conversion -Wno-implicit-function-declaration -Wno-return-mismatch"

# Run the same tests as the Dockerfile
./cc1 -quiet -O2 "$SCRIPT_DIR/tests/little_endian.c" -o little_endian.s
grep -E 'lbu\s\$2,0\(\$4\)' little_endian.s
./cc1 -quiet -O2 "$SCRIPT_DIR/tests/section_attribute.c" -o /dev/null
./cc1 -version </dev/null 2>&1 | grep -- -msoft-float
./cc1 -version </dev/null 2>&1 | grep -- -msplit-addresses
./cc1 -version </dev/null 2>&1 | grep -- -mgpopt

mkdir -p "$OUTDIR"
cp cpp cc1 xgcc cc1plus g++ "$OUTDIR/"
mv "$OUTDIR/xgcc" "$OUTDIR/gcc"
echo "Done — $OUTDIR/ ($(file "$OUTDIR/cc1" | cut -d: -f2 | xargs))"
13 changes: 13 additions & 0 deletions patches/eprintf-darwin.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/* Stub for __eprintf, removed from macOS SDKs after 10.14.
Required by gcc-2.7.2-cdk's exception-handling code. */
#include <stdio.h>
#include <stdlib.h>

/* weak: if another object (e.g. tree.o in cdk) also defines __eprintf,
that strong definition takes precedence and no duplicate-symbol error occurs. */
__attribute__((weak)) void
__eprintf (const char *fmt, const char *file, unsigned line, const char *expr)
{
fprintf (stderr, fmt, file, line, expr);
abort ();
}
25 changes: 25 additions & 0 deletions patches/xm-darwin.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/* Host machine description for GCC running on macOS (Darwin).
Works for both x86_64 and aarch64 (Apple Silicon).

macOS uses the LP64 model: int is 32-bit, long and pointers are 64-bit. */

#define HOST_BITS_PER_CHAR 8
#define HOST_BITS_PER_SHORT 16
#define HOST_BITS_PER_INT 32
#define HOST_BITS_PER_LONG 64
#define HOST_BITS_PER_LONGLONG 64

#define FALSE 0
#define TRUE 1

#define SUCCESS_EXIT_CODE 0
#define FATAL_EXIT_CODE 33

#define HAVE_VPRINTF
#define HAVE_STRERROR
#define POSIX

/* macOS provides bcopy/bcmp/bzero via <string.h>. */
#define BSTRING

#include "tm.h"
Loading