Skip to content

Commit b2f1008

Browse files
Add native macOS build scripts (2.7.2-psx, 2.7.2-cdk, 2.8.1-psx) (#34)
* Add native macOS build scripts for 2.7.2-psx, 2.7.2-cdk, 2.8.1-psx Produces native Mach-O arm64/x86_64 cc1 binaries on macOS without Docker. Approach: - Replace config.guess/config.sub with modern versions + psx* OS entry - Add xm-darwin.h (LP64 host descriptor) and patch configure for *-apple-darwin* - Pass --host/--build explicitly to avoid multi-arg config.sub calls - Export CFLAGS=-std=gnu89 so configure's compiler test (main(){}) passes clang - 2.7.2-cdk: requires byacc, single-threaded build (yacc race), __eprintf stub - 2.8.1-psx: touch insn-config.h, unset CC/CXX, prepend system PATH Also adds Makefile PLATFORM=macos support and a build-macos.yml GitHub Actions workflow (macos-latest runner, matrix: 2.7.2-psx, 2.7.2-cdk, 2.8.1-psx). Closes #33 * Address review feedback: pin URLs, use sed/awk, build all binaries - Pin config.guess/config.sub fetches to specific commits (74af13c, 6fad101) instead of tracking master, for reproducibility - Replace Python text substitutions with grep+sed (varargs) and awk (configure patch); add PATH=/usr/bin:... to all scripts so BSD sed is used - Build cpp/cc1/xgcc/cc1plus/g++ to match the Linux Dockerfiles; fixes needed: - sys_nerr declared 'const int' in macOS SDKs — patch gcc.c and cp/g++.c - __eprintf in eprintf-darwin.c marked weak so tree.o's strong definition wins in cdk (avoids duplicate symbol error when linking cc1plus) - awk configure patch made context-aware: buffer each \t*) line and only insert *-apple-darwin* before the one followed by the "not supported" echo (2.8.1 configure has an unrelated \t*) earlier that fooled the first pass)
1 parent f03871e commit b2f1008

7 files changed

Lines changed: 355 additions & 0 deletions

File tree

.github/workflows/build-macos.yml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: Compile GCC (macOS)
2+
on:
3+
push:
4+
tags: '*'
5+
branches: [master]
6+
paths-ignore:
7+
- README.md
8+
pull_request:
9+
branches: [master]
10+
jobs:
11+
build:
12+
runs-on: macos-latest
13+
strategy:
14+
fail-fast: false
15+
matrix:
16+
version:
17+
- 2.7.2-psx
18+
- 2.7.2-cdk
19+
- 2.8.1-psx
20+
name: Build GCC ${{ matrix.version }} (macOS)
21+
steps:
22+
- name: Clone repository
23+
uses: actions/checkout@v4
24+
- name: Install dependencies
25+
run: |
26+
# byacc is required for gcc-2.7.2-cdk
27+
brew install byacc
28+
- name: Build GCC
29+
run: VERSION=${{ matrix.version }} PLATFORM=macos make
30+
- name: Create release archive
31+
shell: bash
32+
run: |
33+
cd build-gcc-${{ matrix.version }}
34+
tar -czvf ../gcc-${{ matrix.version }}-macos.tar.gz *
35+
- name: Create artifact
36+
uses: actions/upload-artifact@v4
37+
with:
38+
name: gcc-${{ matrix.version }}-macos
39+
path: gcc-${{ matrix.version }}-macos.tar.gz
40+
- name: Publish release
41+
uses: softprops/action-gh-release@v2
42+
if: startsWith(github.ref, 'refs/tags/')
43+
with:
44+
files: |
45+
gcc-${{ matrix.version }}-macos.tar.gz

Makefile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
1+
PLATFORM ?= linux
2+
13
all: check-version
4+
ifeq ($(PLATFORM),macos)
5+
bash gcc-$(VERSION)-macos.sh
6+
else
27
docker build -f gcc-$(VERSION).Dockerfile --target export --output build-gcc-$(VERSION) .
8+
endif
39

410
clean:
511
rm -rf build-gcc-*/
@@ -8,8 +14,14 @@ check-version:
814
ifndef VERSION
915
$(error You must specify a VERSION e.g. `make VERSION=2.8.1`)
1016
endif
17+
ifeq ($(PLATFORM),macos)
18+
ifeq ($(wildcard gcc-$(VERSION)-macos.sh),)
19+
$(error Building GCC $(VERSION) for macOS is not currently supported)
20+
endif
21+
else
1122
ifeq ($(wildcard gcc-$(VERSION).Dockerfile),)
1223
$(error Building GCC $(VERSION) is not currently supported)
1324
endif
25+
endif
1426

1527
.PHONY: all check-version

gcc-2.7.2-cdk-macos.sh

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
#!/bin/bash
2+
# Build gcc-2.7.2-cdk natively on macOS (x86_64 and aarch64).
3+
# Produces Mach-O cc1 and companion binaries targeting mips-sony-psx.
4+
#
5+
# Requires: byacc (install via Homebrew: brew install byacc)
6+
set -e
7+
8+
if ! command -v byacc >/dev/null 2>&1; then
9+
echo "Error: byacc is required. Install it with: brew install byacc" >&2
10+
exit 1
11+
fi
12+
13+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
14+
PATCHES="$SCRIPT_DIR/patches"
15+
OUTDIR="$SCRIPT_DIR/build-gcc-2.7.2-cdk"
16+
WORKDIR="$(mktemp -d)"
17+
trap 'rm -rf "$WORKDIR"' EXIT
18+
19+
echo "Building gcc-2.7.2-cdk for macOS in $WORKDIR"
20+
21+
# Ensure we use the system compiler and tools, not any cross-compiler wrappers
22+
# that may be in PATH (e.g. from a nix shell).
23+
export PATH="/usr/bin:/bin:/usr/sbin:/sbin:$PATH"
24+
unset CC CXX
25+
26+
cd "$WORKDIR"
27+
curl -fL "https://github.com/decompals/old-gcc/releases/download/0.14/b18.tar.gz" | tar xz
28+
cd cdk-gcc-b18
29+
30+
# Apply the same patches as the Linux Dockerfile
31+
# macOS SDKs declare sys_nerr as 'const int'; fix the conflicting declarations.
32+
for f in gcc.c cp/g++.c; do
33+
[ -f "$f" ] && sed -i '' 's/^extern int sys_nerr;/extern const int sys_nerr;/' "$f"
34+
done
35+
patch -u -p1 Makefile.in -i "$PATCHES/Makefile-2.7.2-cdk.in.patch"
36+
patch -u -p1 obstack.h -i "$PATCHES/obstack-2.7.2-cdk.h.patch"
37+
patch -u -p1 config/mips/mips.h -i "$PATCHES/mipsel-2.7-cdk.patch"
38+
patch -su -p1 < "$PATCHES/psx-2.7.2-cdk.patch"
39+
40+
# macOS: replace config.guess/config.sub with modern versions that know
41+
# about aarch64-apple-darwin, then add psx* to the OS list.
42+
# Pinned to specific commits for reproducibility.
43+
chmod +w config.guess config.sub
44+
curl -fsL "https://raw.githubusercontent.com/gcc-mirror/gcc/74af13c174714dd3b9f1ded4b39955f003c16361/config.guess" -o config.guess
45+
curl -fsL "https://raw.githubusercontent.com/gcc-mirror/gcc/6fad101f3063d722e3348d07dc93cf737f8709e4/config.sub" -o config.sub
46+
chmod +x config.guess config.sub
47+
sed -i '' 's/| hiux\* | abug | nacl\*/| psx* \\\
48+
'"$(printf '\t')"' | hiux* | abug | nacl*/' config.sub
49+
50+
# Add xm-darwin.h and teach configure about *-apple-darwin* hosts.
51+
cp "$PATCHES/xm-darwin.h" config/
52+
chmod +w configure
53+
awk '/^\t\*\)$/ { buf=$0; next }
54+
buf != "" { if (!done && /echo.*Configuration.*not supported/) {
55+
print "\t*-apple-darwin*)"; print "\t\txm_file=xm-darwin.h"
56+
print "\t\tfixincludes=Makefile.in"; print "\t\t;;"; done=1 }
57+
print buf; buf="" } { print }' configure > configure.tmp
58+
mv configure.tmp configure
59+
chmod +x configure
60+
61+
./configure \
62+
--target=mips-sony-psx \
63+
--prefix=/opt/cross \
64+
--with-endian-little \
65+
--with-gnu-as \
66+
--disable-gprof \
67+
--disable-gdb \
68+
--disable-werror
69+
70+
# Compile the __eprintf stub — this symbol was removed from macOS SDKs
71+
# after 10.14 but is referenced by the exception-handling code.
72+
EPRINTF_OBJ="$PWD/eprintf-darwin.o"
73+
cc -std=gnu89 -c "$PATCHES/eprintf-darwin.c" -o "$EPRINTF_OBJ"
74+
75+
# Build single-threaded: parallel yacc invocations race on y.tab.h,
76+
# causing bi-parser.h to be generated with the wrong grammar.
77+
make cpp cc1 xgcc cc1plus g++ \
78+
CFLAGS="-std=gnu89 -w -Wno-int-conversion -Wno-implicit-function-declaration -Wno-return-mismatch" \
79+
LDFLAGS="$EPRINTF_OBJ"
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+
86+
mkdir -p "$OUTDIR"
87+
cp cpp cc1 xgcc cc1plus g++ "$OUTDIR/"
88+
mv "$OUTDIR/xgcc" "$OUTDIR/gcc"
89+
echo "Done — $OUTDIR/ ($(file "$OUTDIR/cc1" | cut -d: -f2 | xargs))"

gcc-2.7.2-psx-macos.sh

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#!/bin/bash
2+
# Build gcc-2.7.2-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.7.2-psx"
9+
WORKDIR="$(mktemp -d)"
10+
trap 'rm -rf "$WORKDIR"' EXIT
11+
12+
echo "Building gcc-2.7.2-psx for macOS in $WORKDIR"
13+
14+
# Ensure we use the system compiler and tools, not any cross-compiler wrappers
15+
# that 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://ftp.gnu.org/old-gnu/gcc/gcc-2.7.2.tar.gz" | tar xz
21+
cd gcc-2.7.2
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.7.2.h.patch"
33+
patch -u -p1 configure -i "$PATCHES/configure.patch"
34+
patch -u -p1 config/mips/mips.h -i "$PATCHES/mipsel-2.7.patch"
35+
patch -su -p1 < "$PATCHES/psx-2.5.7.patch"
36+
37+
# macOS: replace config.guess/config.sub with modern versions that know
38+
# about aarch64-apple-darwin, then add psx* to the OS list.
39+
# Pinned to specific commits for reproducibility.
40+
chmod +w config.guess config.sub
41+
curl -fsL "https://raw.githubusercontent.com/gcc-mirror/gcc/74af13c174714dd3b9f1ded4b39955f003c16361/config.guess" -o config.guess
42+
curl -fsL "https://raw.githubusercontent.com/gcc-mirror/gcc/6fad101f3063d722e3348d07dc93cf737f8709e4/config.sub" -o config.sub
43+
chmod +x config.guess config.sub
44+
sed -i '' 's/| hiux\* | abug | nacl\*/| psx* \\\
45+
'"$(printf '\t')"' | hiux* | abug | nacl*/' config.sub
46+
47+
# Add xm-darwin.h and teach configure about *-apple-darwin* hosts.
48+
cp "$PATCHES/xm-darwin.h" config/
49+
chmod +w configure
50+
awk '/^\t\*\)$/ { buf=$0; next }
51+
buf != "" { if (!done && /echo.*Configuration.*not supported/) {
52+
print "\t*-apple-darwin*)"; print "\t\txm_file=xm-darwin.h"
53+
print "\t\tfixincludes=Makefile.in"; print "\t\t;;"; done=1 }
54+
print buf; buf="" } { print }' configure > configure.tmp
55+
mv configure.tmp configure
56+
chmod +x configure
57+
58+
./configure \
59+
--target=mips-sony-psx \
60+
--prefix=/opt/cross \
61+
--with-endian-little \
62+
--with-gnu-as \
63+
--disable-gprof \
64+
--disable-gdb \
65+
--disable-werror
66+
67+
make --jobs "$(sysctl -n hw.ncpu)" cpp cc1 xgcc cc1plus g++ \
68+
CFLAGS="-std=gnu89 -w -Wno-int-conversion -Wno-implicit-function-declaration -Wno-return-mismatch"
69+
70+
# Run the same tests as the Dockerfile
71+
./cc1 -quiet -O2 "$SCRIPT_DIR/tests/little_endian.c" -o little_endian.s
72+
grep -E 'lbu\s\$2,0\(\$4\)' little_endian.s
73+
./cc1 -quiet -O2 "$SCRIPT_DIR/tests/section_attribute.c" -o /dev/null
74+
./cc1 -quiet -help </dev/null 2>&1 | grep -- -msoft-float
75+
76+
mkdir -p "$OUTDIR"
77+
cp cpp cc1 xgcc cc1plus g++ "$OUTDIR/"
78+
mv "$OUTDIR/xgcc" "$OUTDIR/gcc"
79+
echo "Done — $OUTDIR/ ($(file "$OUTDIR/cc1" | cut -d: -f2 | xargs))"

gcc-2.8.1-psx-macos.sh

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
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))"

patches/eprintf-darwin.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/* Stub for __eprintf, removed from macOS SDKs after 10.14.
2+
Required by gcc-2.7.2-cdk's exception-handling code. */
3+
#include <stdio.h>
4+
#include <stdlib.h>
5+
6+
/* weak: if another object (e.g. tree.o in cdk) also defines __eprintf,
7+
that strong definition takes precedence and no duplicate-symbol error occurs. */
8+
__attribute__((weak)) void
9+
__eprintf (const char *fmt, const char *file, unsigned line, const char *expr)
10+
{
11+
fprintf (stderr, fmt, file, line, expr);
12+
abort ();
13+
}

patches/xm-darwin.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/* Host machine description for GCC running on macOS (Darwin).
2+
Works for both x86_64 and aarch64 (Apple Silicon).
3+
4+
macOS uses the LP64 model: int is 32-bit, long and pointers are 64-bit. */
5+
6+
#define HOST_BITS_PER_CHAR 8
7+
#define HOST_BITS_PER_SHORT 16
8+
#define HOST_BITS_PER_INT 32
9+
#define HOST_BITS_PER_LONG 64
10+
#define HOST_BITS_PER_LONGLONG 64
11+
12+
#define FALSE 0
13+
#define TRUE 1
14+
15+
#define SUCCESS_EXIT_CODE 0
16+
#define FATAL_EXIT_CODE 33
17+
18+
#define HAVE_VPRINTF
19+
#define HAVE_STRERROR
20+
#define POSIX
21+
22+
/* macOS provides bcopy/bcmp/bzero via <string.h>. */
23+
#define BSTRING
24+
25+
#include "tm.h"

0 commit comments

Comments
 (0)