Files
goldeneye-pc-port/docs/building.md
T
2026-10-22 16:24:11 +02:00

213 lines
8.4 KiB
Markdown

---
title: Building
description: Full build and asset-extraction guide for the GoldenEye 007 PC port on Windows, Linux, and macOS.
---
## Building the PC port
Stages:
1. **Extract assets from your ROM** (§2): a one-time step using the
decompilation's own toolchain to pull levels, models, textures, fonts and
music into `assets/`. *(Only needed to regenerate the committed data files;
a plain `git clone` already has what the PC build compiles.)*
2. **Build the port** (§3): a CMake build compiling the game sources plus the
`port/` layer into a native executable. Needs no ROM.
3. **Generate the PC asset sidecars** (§4): two pure-Python converters turn
ROM model / stage data into the PC-layout `data/pcmodels-*` / `data/pccg-*`
files the port loads at runtime. **Required to run.**
You need a GoldenEye 007 N64 ROM you legally own (`.z64`, big-endian). See the
[ROM table in the user guide](user-guide.md#whats-a-rom)
for accepted versions and hashes.
---
## 1. Dependencies
### Port build
> **The Windows (MSYS2 MINGW64) path is the primary one.** Linux is compiled
> by CI and ships in the release bundle. **macOS on Apple Silicon is
> experimental as of v0.6.0**: the release has a `macos-arm64` download
> (`scripts/package-macos.sh` makes it on a Mac; CI runs it) that is not
> notarized, so clear the quarantine flag once before the first launch with
> `xattr -dr com.apple.quarantine <folder>`. This guide covers building it from
> source. On an arm64 Mac the build moves the N64 address window to a
> high host base (`PORT_ADDR_BASE`, set automatically); Windows and Linux builds
> are unaffected. The x86_64 macOS path (Julio C. Rocha, #88) is still in the
> tree but was never verified on Intel hardware.
| Need | Windows (MSYS2 MINGW64) | Debian/Ubuntu | macOS (Homebrew) |
|------|------------------------|---------------|------------------|
| toolchain | `mingw-w64-x86_64-toolchain` | `build-essential` | Xcode CLT + Homebrew `gcc` |
| CMake | `mingw-w64-x86_64-cmake` | `cmake` | `cmake` |
| SDL2 | `mingw-w64-x86_64-SDL2` | `libsdl2-dev` | `sdl2` |
| zlib | `mingw-w64-x86_64-zlib` | `zlib1g-dev` | `zlib` |
| OpenGL | (in the toolchain) | `libgl1-mesa-dev` | (system) |
| Python 3 | `mingw-w64-x86_64-python` | `python3` | `python3` |
On macOS, install the build dependencies with:
```sh
brew install cmake gcc sdl2 zlib python3
```
The project requires real GNU GCC for the decomp's Plan 9 struct extensions.
Apple's `/usr/bin/gcc` is Clang and is not compatible. CMake automatically
selects Homebrew's versioned `gcc-N`/`g++-N` (or MacPorts' `gcc-mp-N`/`g++-mp-N`)
executables; set `CC`/`CXX` to pick a specific one. Delete the build directory
after switching compilers.
If GCC fails with `fatal error: _bounds.h: No such file or directory`, it was
built against a newer macOS SDK than the one CMake picked (the `xcode-select`
default). Point `SDKROOT` at the SDK GCC was built with (`gcc -v` shows it as
`--with-sysroot`), for example with MacPorts GCC 15:
```sh
SDKROOT=/Library/Developer/CommandLineTools/SDKs/MacOSX15.sdk \
CC=/opt/local/bin/gcc-mp-15 CXX=/opt/local/bin/g++-mp-15 ./build-pc.sh ntsc-final
```
### Asset extraction (decompilation toolchain)
The extraction scripts need `binutils-mips-linux-gnu` (or an equivalent MIPS
binutils), `make`, `git`, and `python3`. They build a small host-compiled
`tools/extractor` and slice blobs straight out of the ROM; **no IDO / IRIX
toolchain is involved in extraction or in the PC build.** (The IDO toolchain is
only needed to build the N64 ROM itself, and its proprietary SGI binaries are
not distributed here; see [`SetupGuide.md`](https://github.com/jkdansereau/goldeneye-pc-port/blob/main/docs/SetupGuide.md) "Recompile IDO".)
On Windows this is easiest under WSL or a Linux VM. Full details and
alternatives (Docker) are in `SetupGuide.md`.
---
## 2. Extract assets
Put your **US** ROM at the repository root as `baserom.u.z64` (this name is
required by the extraction scripts; it is git-ignored and never committed),
then:
```sh
./scripts/extract_baserom.u.sh
```
For PAL or JP, additionally place `baserom.e.z64` / `baserom.j.z64` at the root
and run:
```sh
./scripts/extract_baserom.u.sh && ./scripts/extract_diff.e.sh # PAL
./scripts/extract_baserom.u.sh && ./scripts/extract_diff.j.sh # JP
```
(US extraction is a prerequisite for the others.)
This populates `assets/` with the generated `.bin` blobs the build needs. See
[`SetupGuide.md`](https://github.com/jkdansereau/goldeneye-pc-port/blob/main/docs/SetupGuide.md) for the in-depth build/asset pipeline.
---
## 3. Build
```sh
./build-pc.sh ntsc-final # or: pal-final / jpn-final
```
which is equivalent to:
```sh
cmake -S . -B build-pc -DROMID=ntsc-final
cmake --build build-pc -j
```
On Windows, `build-pc.sh` also locates the MSYS2 MinGW64 toolchain itself
(so it works from Git Bash or a non-login shell too, even with another
`cmake` earlier on PATH) and, if native child processes would get an
unwritable `TMP`, re-runs the configure+build under PowerShell with a
writable one. If MSYS2 is not installed at `C:\msys64`, set
`GE_MSYS2_ROOT` (e.g. `GE_MSYS2_ROOT='C:\tools\msys64'` for a custom
install location). Re-exec logs:
`build-pc/ge007-native-reexec-*.log`.
For PAL/JP you must first generate that region's ROM-asset symbol file
(the US one is committed):
```sh
python3 scripts/gen_romassets.py e # PAL -> port/src/romassets_e.s
python3 scripts/gen_romassets.py j # JP -> port/src/romassets_j.s
```
The executable lands at `build-pc/ge007.x86_64` (`.exe` on Windows). PAL/JP
builds are named `ge007.pal-final.x86_64` / `ge007.jpn-final.x86_64`.
---
## 4. Generate the PC asset sidecars (required to run)
The port does **not** read model geometry, stage bg/stan data, or per-level
setup data from the raw ROM at runtime; it reads them from PC-layout *sidecar*
files under `data/`, produced offline by three converters. **Without them the
game shows the intro logos and then crashes** in
`modelPromoteNodeOffsetsToPointers` (finding D179) or on the first level load
(missing stage setup).
Put your ROM in `data/` first (same file the game runs from):
```sh
mkdir -p data
cp /path/to/your/rom.z64 data/ge007.ntsc-final.z64 # or pal-final / jpn-final
```
Then run all three emit passes for that region, **in this order** (d88 appends
to d69's output):
```sh
python3 tools_pc/d43_emit.py ntsc-final # -> data/pcmodels-ntsc-final/{pcmodels.bin,manifest.csv} (~1.3 MB)
python3 tools_pc/d69_emit.py ntsc-final # -> data/pccg-ntsc-final/{pccg.bin,manifest.csv} (bg + stan)
python3 tools_pc/d88_emit.py ntsc-final --regen # appends the 21 solo Usetup*Z + 13 multiplayer Ump_setup*Z stage-setup files -> ~3.6 MB
```
**PAL / JP note:** both regions convert, build and boot from source (finding
D258, fixed 2026-10-02; D487/D488 fixed the PAL frame height and TV type).
Run the three emit passes with `pal-final` or `jpn-final`, and build into a
separate directory, for example `BUILD_DIR=build-pal ./build-pc.sh pal-final`.
Release packages are still NTSC-U only until per-region packaging lands
(issue #85).
These are **pure-stdlib Python 3** (no MIPS toolchain, independent of the
step-2 asset extraction) and read only the ROM plus files already committed to
the repo (`scripts/filelist.u.csv`, `assets/obseg/file_resource_table.inc.c`,
`assets/**/ModelFileHeader.inc.c`, the bg/stan `.inc.c`). Output is a
deterministic function of the ROM. Re-run after any change to `d43_emit.py` /
`d69_emit.py` / `d88_emit.py` or the model/bg converters (`d43_*`, `d69_*`,
`d88_propdefs.py`).
> The release bundle ships the same converter frozen as
> `prepare-assets/ge007-convert`; the game spawns it on first launch when the
> sidecars are missing, so end users never run it by hand. See the bundled
> `README.md`.
> `data/pcmodels-*/` and `data/pccg-*/` are gitignored ROM-derived game data;
> never commit or redistribute them.
---
## 5. Run
```sh
./build-pc/ge007.x86_64 # run from the repo root
```
The ROM in `data/` (from step 4) and the sidecars are both required at
runtime. `ge007.ini` is written under `data/` on first launch.
### Useful flags / env
| | |
|---|---|
| `-level_NN` | boot straight into a solo level (e.g. `-level_09` = Bunker 1) |
| `GE_PCDUMP="first-last:step"` | dump rendered frames as PPM (debugging) |
More diagnostic switches are cataloged in
[`dev/GE-ENV-PROBES.md`](https://github.com/jkdansereau/goldeneye-pc-port/blob/main/docs/dev/GE-ENV-PROBES.md).