Skip to content

Commit a1b069a

Browse files
committed
Fix up older builds, and set up the claudeses
1 parent 4452bb0 commit a1b069a

4 files changed

Lines changed: 249 additions & 12 deletions

File tree

CLAUDE.md

Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
This repository builds Docker images used to compile various GCC versions for [Compiler Explorer](https://godbolt.org/). The build system supports:
8+
- Standard GCC releases (4.x through trunk)
9+
- Experimental/proposal branches (contracts, coroutines, modules, etc.)
10+
- Cross-compilers (AVR, CEGCC)
11+
- Historical versions (GCC 1.27 + G++ 1.27)
12+
13+
## Build Commands
14+
15+
### Testing Locally
16+
17+
```bash
18+
# Build the Docker image
19+
docker build -t gccbuilder .
20+
21+
# Run a build inside the container
22+
docker run gccbuilder ./build.sh trunk
23+
24+
# Interactive debugging
25+
docker run -t -i gccbuilder bash
26+
./build.sh trunk
27+
```
28+
29+
### Build Script Invocation
30+
31+
All build scripts follow this pattern:
32+
```bash
33+
./build.sh VERSION [OUTPUTPATH] [LAST_REVISION]
34+
./build-1.27.sh VERSION [OUTPUTPATH]
35+
./build-avr.sh VERSION [OUTPUTPATH]
36+
./build-ce.sh VERSION [OUTPUTPATH]
37+
```
38+
39+
**OUTPUTPATH** can be:
40+
- **A directory**: Creates `{dir}/gcc-{VERSION}.tar.xz` (or appropriate prefix)
41+
- **A file path**: Creates the exact file specified
42+
- **An S3 URL** (`s3://...`): Creates local temp file and uploads to S3
43+
- **Omitted**: Defaults to `${ROOT}/gcc-{VERSION}.tar.xz`
44+
45+
**Directory detection is critical**: The scripts check `[[ -d "${2}" ]]` to determine if OUTPUTPATH is a directory. Without this check, passing `/build` would fail with "Cannot open: Is a directory".
46+
47+
### Build Output
48+
49+
Successful builds emit:
50+
```
51+
ce-build-revision:gcc-{GCC_SHA}-binutils-{BINUTILS_SHA}
52+
ce-build-output:/path/to/output.tar.xz
53+
ce-build-status:OK
54+
```
55+
56+
If revision matches LAST_REVISION:
57+
```
58+
ce-build-status:SKIPPED
59+
```
60+
61+
## Architecture
62+
63+
### Build Scripts
64+
65+
**build/build.sh** - Main build script
66+
- Handles 200+ VERSION patterns (trunk, experimental branches, release versions)
67+
- Supports special version prefixes: `assertions-`, `embed-trunk`, `lock3-contracts-trunk`, etc.
68+
- Downloads GCC source from git (various repos/branches based on VERSION)
69+
- Downloads prerequisites (GMP, MPFR, MPC, ISL) via `contrib/download_prerequisites`
70+
- Optionally builds binutils from source (configurable per version)
71+
- Applies patches and config overrides (see below)
72+
- Builds with extensive configure flags for multilib, languages, plugins
73+
- Creates compressed tarball with `tar Jcf` (xz compression)
74+
- Optionally uploads to S3
75+
76+
**build/build-1.27.sh** - Historic GCC 1.27 + G++ 1.27 builder
77+
- Builds GCC 1.27 and G++ 1.27.0 separately
78+
- Links G++ sources with GCC sources (symlink approach)
79+
- Uses hardcoded staging directory: `/opt/compiler-explorer/gcc-1.27`
80+
- Special patches in `patches/gcc1.27/` and `patches/g++1.27/`
81+
82+
**build/build-avr.sh** - AVR cross-compiler builder
83+
- Builds binutils, GCC, and avr-libc in sequence
84+
- Cross-compilation target: `avr`
85+
- Uses staging directory for install prefix
86+
87+
**build/build-ce.sh** - CEGCC (Windows cross-compiler) builder
88+
- Clones GCC, w32api, mingwrt, and binutils from MaxKellermann's GitHub repos
89+
- Uses branch pattern: `ce-{VERSION}`
90+
- Runs `cegcc-build.sh` wrapper script
91+
92+
### Patch and Config System
93+
94+
The `applyPatchesAndConfig()` function applies version-specific customizations:
95+
96+
**Patches** (`build/patches/`):
97+
- Applied with `patch -p1` from GCC source root
98+
- Hierarchy: `patches/{dir}/` where `{dir}` can be:
99+
- `gcc{MAJOR}` (e.g., `gcc4`)
100+
- `gcc{MAJOR_MINOR}` (e.g., `gcc4.7`)
101+
- `gcc{VERSION}` (e.g., `gcc1.27`)
102+
- Common patches: `cfns.patch`, `unwind.patch`, `msgfmt_lib.patch`, `symbol-versioning.patch`
103+
104+
**Config files** (`build/config/`):
105+
- Bash scripts sourced to modify build variables
106+
- Modify `CONFIG`, `CC`, `CXX`, `INSTALL_TARGET`, `BINUTILS_VERSION`, etc.
107+
- Examples:
108+
- `disable_multilib` - Removes `--enable-multilib` from CONFIG
109+
- `gnu89` - Sets `CC='gcc -fgnu89-inline'`
110+
- `binutils_2_28` - Sets `BINUTILS_VERSION=2.28`
111+
- `host_binutils` - Uses system binutils instead of building
112+
- `install_without_strip` - Changes `INSTALL_TARGET=install`
113+
114+
**Application order**:
115+
```bash
116+
applyPatchesAndConfig "gcc${MAJOR}" # e.g., gcc4
117+
applyPatchesAndConfig "gcc${MAJOR_MINOR}" # e.g., gcc4.7
118+
applyPatchesAndConfig "gcc${PATCH_VERSION:-$VERSION}" # e.g., gcc4.7.4
119+
```
120+
121+
### Docker Environment
122+
123+
**Dockerfile**:
124+
- Base: Ubuntu 22.04
125+
- Key dependencies: build-essential, binutils, texinfo, libelf-dev, git, subversion
126+
- AWS CLI v2 (for optional S3 uploads)
127+
- Rust toolchain (required for GCC Rust frontend)
128+
- Working directory: `/opt/compiler-explorer/gcc-build`
129+
- Copies entire `build/` directory into container
130+
131+
**Important**: Build directory must be in `/opt/compiler-explorer/*` to avoid EPERM issues with older GCC versions that search the build prefix at runtime.
132+
133+
## Build System Details
134+
135+
### Staging and Output
136+
137+
1. **Staging directory**: `$(pwd)/staging`
138+
- Temporary install location (`--prefix`)
139+
- Cleaned before each build
140+
- Contains final compiler installation
141+
142+
2. **Output archive**: Created with:
143+
```bash
144+
tar Jcf "${OUTPUT}" --transform "s,^./,./${FULLNAME}/," -C "${STAGING_DIR}" .
145+
```
146+
- `Jcf` = xz compression, create file
147+
- `--transform` = Prepends `gcc-{VERSION}/` to all paths in archive
148+
- Archive root becomes `gcc-{VERSION}/bin`, `gcc-{VERSION}/lib`, etc.
149+
150+
### Version String Patterns
151+
152+
The build system recognizes many special VERSION patterns:
153+
- `trunk` - Latest GCC master branch
154+
- `{major}.{minor}.{patch}` - Release versions (e.g., `11.2.0`)
155+
- `{major}.{minor}` - Latest point release (e.g., `11.2`)
156+
- `{major}-snapshot` - Snapshot builds
157+
- `embed-trunk` - ThePhD's embed proposal branch
158+
- `lock3-contracts-trunk` - Lock3's contracts branch
159+
- `contracts-nonattr` - Ville Voutilainen's contracts branch
160+
- `lambda-p2034` - P2034 lambda proposal
161+
- `p1144-trunk` - Quuxplusone's trivially relocatable proposal
162+
- `cxx-modules-trunk` - C++ modules development branch
163+
- `cxx-coroutines-trunk` - Coroutines branch
164+
- `static-analysis-trunk` - Static analyzer branch
165+
- `gccrs-master` - GCC Rust frontend
166+
- `algol68-master` - Algol68 frontend
167+
- `assertions-{version}` - Adds `--enable-checking=yes,rtl,extra`
168+
169+
### Revision Tracking
170+
171+
Builds track GCC and binutils git SHA:
172+
```bash
173+
GCC_REVISION=$(git ls-remote --heads ${URL} "refs/heads/${BRANCH}" | cut -f 1)
174+
BINUTILS_REVISION=$(git ls-remote --heads ${BINUTILS_GITURL} refs/heads/master | cut -f 1)
175+
REVISION="gcc-${GCC_REVISION}-binutils-${BINUTILS_REVISION}"
176+
```
177+
178+
If `REVISION == LAST_REVISION`, build is skipped (outputs `SKIPPED` status).
179+
180+
## Key Conventions
181+
182+
### Build Script Parameters
183+
184+
All build scripts must:
185+
1. Accept VERSION as `$1`
186+
2. Accept optional OUTPUTPATH as `$2`
187+
3. Detect if `$2` is a directory using `[[ -d "${2}" ]]`
188+
4. Create `FULLNAME` variable for archive naming
189+
5. Use proper quoting: `"${OUTPUT}"`, `"${STAGING_DIR}"`, `"$2"`
190+
6. Emit status output: `ce-build-revision:`, `ce-build-output:`, `ce-build-status:`
191+
192+
### Tar Transform Pattern
193+
194+
Always use `--transform "s,^./,./${FULLNAME}/,"` to ensure archive contents are in a top-level directory named after the compiler version.
195+
196+
### S3 Support (Optional)
197+
198+
While builds now primarily output to directories, S3 upload support remains:
199+
```bash
200+
if [[ -n "${S3OUTPUT}" ]]; then
201+
aws s3 cp --storage-class REDUCED_REDUNDANCY "${OUTPUT}" "${S3OUTPUT}"
202+
fi
203+
```
204+
205+
## CI/CD
206+
207+
GitHub Actions workflow (`.github/workflows/build.yml`):
208+
- Triggers on push to `main` or manual dispatch
209+
- Builds Docker image with BuildKit
210+
- Pushes to Docker Hub: `compilerexplorer/gcc-builder:latest`
211+
- Uses layer caching for faster rebuilds
212+
213+
No automated GCC builds in CI - the Docker image is the deliverable. Actual GCC compilation happens separately using this image.

build/build-1.27.sh

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,19 @@ if [[ "$VERSION" != "1.27" ]]; then
99
exit 1
1010
fi
1111

12-
OUTPUT=/root/gcc-${VERSION}.tar.xz
12+
FULLNAME=gcc-${VERSION}
13+
OUTPUT=${ROOT}/${FULLNAME}.tar.xz
1314
S3OUTPUT=""
14-
if echo $2 | grep s3://; then
15+
if echo "$2" | grep s3://; then
1516
S3OUTPUT=$2
1617
else
17-
OUTPUT=${2-/root/gcc-${VERSION}.tar.xz}
18+
if [[ -d "${2}" ]]; then
19+
OUTPUT=$2/${FULLNAME}.tar.xz
20+
else
21+
OUTPUT=${2-$OUTPUT}
22+
fi
1823
fi
24+
echo "ce-build-output:${OUTPUT}"
1925

2026
STAGING_DIR=/opt/compiler-explorer/gcc-${VERSION}
2127

@@ -90,8 +96,10 @@ make -j$(nproc) install
9096
popd
9197

9298
export XZ_DEFAULTS="-T 0"
93-
tar Jcf ${OUTPUT} --transform "s,^./,./gcc-${VERSION}/," -C ${STAGING_DIR} .
99+
tar Jcf "${OUTPUT}" --transform "s,^./,./${FULLNAME}/," -C "${STAGING_DIR}" .
94100

95101
if [[ -n "${S3OUTPUT}" ]]; then
96102
aws s3 cp --storage-class REDUCED_REDUNDANCY "${OUTPUT}" "${S3OUTPUT}"
97103
fi
104+
105+
echo "ce-build-status:OK"

build/build-avr.sh

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,19 @@ VER_LIBC=2.0.0
77
VER_GCC=$1
88

99
ROOT=$(pwd)
10-
OUTPUT=/root/avr-gcc-${VER_GCC}.tar.xz
10+
FULLNAME=avr-gcc-${VER_GCC}
11+
OUTPUT=${ROOT}/${FULLNAME}.tar.xz
1112
S3OUTPUT=""
12-
if echo $2 | grep s3://; then
13+
if echo "$2" | grep s3://; then
1314
S3OUTPUT=$2
1415
else
15-
OUTPUT=${2-/root/avr-gcc-${VER_GCC}.tar.xz}
16+
if [[ -d "${2}" ]]; then
17+
OUTPUT=$2/${FULLNAME}.tar.xz
18+
else
19+
OUTPUT=${2-$OUTPUT}
20+
fi
1621
fi
22+
echo "ce-build-output:${OUTPUT}"
1723

1824
# Workaround for Ubuntu builds
1925
export LIBRARY_PATH=/usr/lib/x86_64-linux-gnu
@@ -79,8 +85,10 @@ make ${INSTALL_TARGET}
7985
popd
8086

8187
export XZ_DEFAULTS="-T 0"
82-
tar Jcf ${OUTPUT} --transform "s,^./,./avr-gcc-${VER_GCC}/," -C ${STAGING_DIR} .
88+
tar Jcf "${OUTPUT}" --transform "s,^./,./${FULLNAME}/," -C "${STAGING_DIR}" .
8389

8490
if [[ -n "${S3OUTPUT}" ]]; then
8591
aws s3 cp --storage-class REDUCED_REDUNDANCY "${OUTPUT}" "${S3OUTPUT}"
8692
fi
93+
94+
echo "ce-build-status:OK"

build/build-ce.sh

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,19 @@ MAJOR_MINOR=$(echo ${VERSION} | grep -oE '^[0-9]+\.[0-9]+')
99
URL=https://github.com/MaxKellermann/gcc.git
1010
BRANCH=ce-${VERSION}
1111

12-
OUTPUT=/root/gcc-ce-${VERSION}.tar.xz
12+
FULLNAME=gcc-ce-${VERSION}
13+
OUTPUT=${ROOT}/${FULLNAME}.tar.xz
1314
S3OUTPUT=""
14-
if echo $2 | grep s3://; then
15+
if echo "$2" | grep s3://; then
1516
S3OUTPUT=$2
1617
else
17-
OUTPUT=${2-/root/gcc-${VERSION}.tar.xz}
18+
if [[ -d "${2}" ]]; then
19+
OUTPUT=$2/${FULLNAME}.tar.xz
20+
else
21+
OUTPUT=${2-$OUTPUT}
22+
fi
1823
fi
24+
echo "ce-build-output:${OUTPUT}"
1925

2026
# Workaround for Ubuntu builds
2127
export LIBRARY_PATH=/usr/lib/x86_64-linux-gnu
@@ -41,8 +47,10 @@ cd ${BUILD_DIR}
4147
bash ${SOURCE_DIR}/build.sh --prefix=${STAGING_DIR} -j $(nproc)
4248

4349
export XZ_DEFAULTS="-T 0"
44-
tar Jcf ${OUTPUT} --transform "s,^./,./gcc-ce-${VERSION}/," -C ${STAGING_DIR} .
50+
tar Jcf "${OUTPUT}" --transform "s,^./,./${FULLNAME}/," -C "${STAGING_DIR}" .
4551

4652
if [[ -n "${S3OUTPUT}" ]]; then
4753
aws s3 cp --storage-class REDUCED_REDUNDANCY "${OUTPUT}" "${S3OUTPUT}"
4854
fi
55+
56+
echo "ce-build-status:OK"

0 commit comments

Comments
 (0)