Files
BFM-decomp/docs/wiki/Toolchain-setup.md
T

5.6 KiB
Raw Blame History

Toolchain setup

Everything runs inside one Linux environment (the project uses WSL2 Ubuntu 24.04 on a single ext4 clone; builds never run on a Windows-mounted path — the 9P bridge is slow and breaks file watching). The authoritative, evolvable reference for every version, path and command is docs/SETUP.md; this page is the map of it.

The pinned triple — and why it is pinned

The compiler, assembler and their flags were fixed in Phase 6 by fingerprint evidence from the binary itself, not by copying a sibling project (the tempting choice, sotn-decomp's GCC 2.6.3, would have produced systematic near-miss diffs on every function — an invisible poison). The evidence: twelve genuine PsyQ library version stamps in the executable (PsyQ 4.0 with 4.2 updates ⇒ the GCC 2.7.2 family), then idiom-revealing probe functions run down a candidate ladder of cc1 builds × ASPSX assembler versions × -G settings until one reproduced the bytes.

cpp (modern, mipsel)  →  gcc-2.7.2-psx cc1 -O2 -G0 -mips1 -mcpu=3000 -mgas -msoft-float -fgnu-linker
                      →  maspsx --aspsx-version=2.56 --expand-div
                      →  mipsel-linux-gnu-as -march=r3000 -mtune=r3000 -no-pad-sections -O1 -G0
                      →  ld (splat's linker script)  →  objcopy

Two details that cost time and are worth knowing: --expand-div turned out to be mandatory (Phase 6), and maspsx's default ASPSX version is not the latest, so the version is always passed explicitly (rule G8). A handful of modules compile at -O0 where the bytes demand it (the boot module and the _o0 splits carved out of otherwise -O2 files); the Makefile carries those as per-file flags.

Versions (as built)

Component Version / pin Notes
Ubuntu / Python 24.04 / 3.12 older Pythons fail mid-build on f-string syntax
binutils-mipsel-linux-gnu 2.42 the "≥ 2.38 is broken for PS1" warning did not bite: the all-assembly build was SHA1-identical on the first try (Phase 5) — no downgrade to 2.35
splat splat64[mips] 0.41.0 the PyPI package is splat64, and the [mips] extra is required
gcc-2.7.2 cc1 old-gcc release 0.17, gcc-2.7.2-psx (primary) and gcc-2.7.2-cdk (cygnus-2.7.2-970404, the base of PsyQ's CC1PSX) 32-bit i386 static binaries, run under the kernel's IA-32 emulation; the tarballs are tracked (GCC is GPL) with sha256s 500a459b… / 42bb0df9… in tools/bin/CHECKSUMS.sha256
maspsx submodule, commit 874855c5 decomp.me's pin, so local results compare to decomp.me scratches
decomp-permuter submodule, commit b44b0622 with the project's masked scorer and warm-restart wrapper (tools/permuter/)
asm-differ / m2c submodules, 2ad4a4a4 / 4266cc28 pinned at adoption; blindly updating submodules breaks tooling (sotn precedent)

make bootstrap (tools/bootstrap.sh) performs the whole setup idempotently — apt presence check (prints the install line, never runs sudo), the venv, the submodules, the checksummed tarballs — and ends with make check-env, which asserts each component and the state of the extracted disc.

The optional Sony SDK

The main executable links 1,256 functions of Sony's PsyQ libraries (libcd, libgs, libgte, libgpu, libspu/libsnd, libetc, libapi, libcard, libpad 4.2.1 …). They are not our C and are never redistributed. The build handles them two ways, and both produce the identical executable:

  • Without the SDK (every fresh clone): the library regions are carried as INCLUDE_ASM tiles whose bytes come from your disc (src/lib*.c, src/apicard*.c). This is the public build.
  • With the SDK (tools/fetch_psyq.sh): if you own the PsyQ 4.0 libraries (the DTL-S2002 disc) and the RTL 4.2 archive, the script verifies each file against tools/psyq_CHECKSUMS.sha256, converts the objects with psyq-obj-parser, and the link uses Sony's real objects.

make sdk-dual proves the two are the same bytes (sdk-dual: OK — main 143dbb89… byte-identical WITH and WITHOUT the PsyQ objects) and is part of make tools-health when the objects exist. Twelve functions that had been recorded as "compiler walls" in Phase 31 were in fact the libpad 4.2.1 objects — provenance is asked before the compiler is blamed.

Reverse-engineering tools (not needed to build)

  • Ghidra 12.1 with ghidra_psx_ldr (the PlayStation loader: PsyQ signatures, the GTE macro segment) and GhidrAssistMCP — the static oracle. The project runs it headless with an MCP server (tools/ghidra_mcp_start.sh / tools/ghidra_mcp_stop.sh) so the agent can query it; symbol renames persist only through the headless ApplySymbols script, never through MCP renames. The database itself is not in git — see Ghidra rebuild from text. Install steps and the pinned extension zips (sha256-recorded, download-only) are in SETUP §2.
  • PCSX-Redux — the runtime oracle, bridged over its web API for RAM snapshots; every overlay load address in docs/memory-map.md was proven against a live RAM image (SETUP §3).
  • The gcc-2.7.2 source (tools/reference/, gitignored; GPL, from ftp.gnu.org) — read, not built: it is what the codegen map (docs/gcc-2.7.2-map/) cites. A community "2.7.2" tree in circulation is gcc 2.8.1; the map's audit found the drift and the vanilla source was staged.