Generates build.ninja + compile_commands.json from a ps2.yaml build definition for PS2 EE/IOP homebrew targets
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
techwritescode 7e702b4111
All checks were successful
Build / build (push) Successful in 16m39s
Generate .clangd every run instead of hand-maintaining it
compiledb.ClangdConfig renders a project's .clangd: strips PS2-only
flags (-G*/-m*/-fno-toplevel-reorder), adds a _EE/_IOP fallback define,
and bakes in the same compiler-queried implicit include dirs
isystem.go's discoverImplicitIncludeDirs already provides for
compile_commands.json - reused directly, not duplicated.

generate.Run gates this behind Options.WriteClangdConfig (off by
default - Run's own golden-file tests point ConfigPath at the real
fixtures under internal/explain/testdata/fixtures, not a temp copy, so
an unconditional write would pollute those repo files on every test
run). The CLI's generate/build/init commands all turn it on.

Fixes a real, twice-repeated problem during this project's own
development: wavekit's hand-maintained .clangd had an incomplete
-isystem list (missing the libstdc++ dirs entirely at first, then
missing the target-specific one bits/c++config.h lives in), causing
'cstdlib'/'bits/c++config.h' file-not-found errors in clangd. A
generated file can't silently desync from the actual toolchain the way
a hand-copied one did twice, and regenerates itself if an IDE deletes
it (as CLion did once during this same session).
2026-08-24 20:08:29 -05:00
.forgejo/workflows Add tagged release workflow: cross-platform binaries on v* tags 2026-08-24 17:13:00 -05:00
cmd/ps2build Implement ps2build: ps2.yaml -> build.ninja + compile_commands.json 2026-08-23 11:03:47 -05:00
internal Generate .clangd every run instead of hand-maintaining it 2026-08-24 20:08:29 -05:00
testdata/invalid Implement ps2build: ps2.yaml -> build.ninja + compile_commands.json 2026-08-23 11:03:47 -05:00
.gitignore Implement ps2build: ps2.yaml -> build.ninja + compile_commands.json 2026-08-23 11:03:47 -05:00
CLAUDE.md Generate .clangd every run instead of hand-maintaining it 2026-08-24 20:08:29 -05:00
go.mod Implement ps2build: ps2.yaml -> build.ninja + compile_commands.json 2026-08-23 11:03:47 -05:00
go.sum Implement ps2build: ps2.yaml -> build.ninja + compile_commands.json 2026-08-23 11:03:47 -05:00
LICENSE Add LICENSE 2026-08-24 15:49:37 -05:00
README.md Add README 2026-08-23 13:27:17 -05:00

ps2build

A small Go CLI that reads a ps2.yaml build definition describing Sony PlayStation 2 Emotion Engine (EE) and IOP build targets, and generates a build.ninja plus a compile_commands.json (a JSON Compilation Database for clangd/IDE tooling) that build them with the real PS2SDK/ps2toolchain cross-compilers.

ps2build only generates files — it never invokes the PS2 cross-compilers itself. You still need a working PS2DEV/PS2SDK install and the toolchain binaries (mips64r5900el-ps2-elf-gcc, mipsel-none-elf-gcc, bin2c, iopfixup) and ninja on PATH.

Install / build

go build -o ps2build ./cmd/ps2build

Requires Go 1.26+.

Usage

ps2build generate            # reads ./ps2.yaml, writes ./build/{build.ninja,compile_commands.json}
ninja -C build                # actually builds it
ps2build generate [-c ps2.yaml] [-o build] [--ps2sdk PATH] [--ps2dev PATH]
ps2build schema [--indent N]              # JSON Schema for the ps2.yaml format
ps2build explain [--json] [--section N]   # documentation, meant to be LLM-readable too
ps2build --version

PS2SDK/PS2DEV are resolved in this order: --ps2sdk/--ps2dev flags → ps2sdk/ps2dev fields in ps2.yamlPS2SDK/PS2DEV environment variables.

A minimal ps2.yaml

project: hello

targets:
  - name: hello
    type: ee
    sources:
      - src/main.c

An EE target embedding a built IOP module (via the PS2SDK bin2c host tool):

project: embed-irx-example

targets:
  - name: helper
    type: iop
    sources:
      - src/iop/helper.c

  - name: main
    type: ee
    sources:
      - src/ee/main.c
    embed_irx:
      - helper

Run ps2build explain for the full field reference, worked examples, and what's explicitly out of scope for now (DVP/VU targets, IOP imports.lst/exports.tab), or ps2build schema for a machine-readable JSON Schema of the whole format.

Development

See CLAUDE.md for package layout, where the toolchain invocation logic actually lives, known sharp edges around path handling, and the testing approach.

go build ./...
go vet ./...
gofmt -l .
go test ./...