The harness at test/tools/test_benchmark.c already existed but had no build wiring -- it just sat there waiting. Now \`make benchmark\` builds the harness and runs it against a default ROM (test/roms/yarc.j64), with overrides for ROM, frame count, warmup, and blitter mode: make benchmark # 600 frames, fast blitter make benchmark BENCH_FRAMES=3000 # longer = smoother numbers make benchmark BENCH_BLITTER=accurate # A/B against slow path make benchmark BENCH_ROM=test/roms/private/X.j64 Local sanity: ./test/tools/test_benchmark on yarc.j64 reports ~240 FPS / 4.2ms per frame on Apple Silicon, fast blitter. Use as a same-host commit-to-commit delta during the upcoming perf work. docs/profiling.md is the new reference: macOS Instruments invocation, Linux perf + flame graph, the SIMD A/B knob, known hot paths (OPProcessFixedBitmap, BlitterMidsummer2, GPUExec, DSPExec), build flavors for profiling vs sanitizing vs coverage, and a regression-triage checklist. CONTRIBUTING.md and CLAUDE.md cross-reference the new doc. The harness binary is built inline in the benchmark recipe (not via a separate rule under the TEST_EXPORTS=1 block), so \`make benchmark\` works without TEST_EXPORTS=1 -- the harness only uses the production retro_* exports. Co-Authored-By: Claude Opus 4.7 <[email protected]>
3.7 KiB
Contributing
Thanks for considering a contribution. This guide covers the practical mechanics — branching, build, test, lint — that keep CI green and reviews fast. For architecture context, see CLAUDE.md.
Branching (GitFlow)
This repo uses a GitFlow-style layout:
| Branch | Role |
|---|---|
master |
Release-only. Tagged commits, hotfix merges, release-branch merges. |
develop |
Integration branch. Default base for new PRs. |
feature/* |
New work. Branch from develop, PR back into develop. |
release/X.Y.Z |
Release stabilization. Branched from develop, merged into master. |
hotfix/X.Y.Z |
Urgent fix off a tagged release. Branched from master, back-merged to develop. |
PRs targeting master directly trigger an auto-comment from .github/workflows/warn-pr-base.yml asking you to retarget to develop (skipped automatically if your branch is release/* or hotfix/*).
git checkout develop
git pull libretro develop
git checkout -b feature/my-thing
# ... commits ...
git push -u origin feature/my-thing
gh pr create --base develop
Build
make -j$(getconf _NPROCESSORS_ONLN) # default platform (auto-detect)
make -j$(getconf _NPROCESSORS_ONLN) DEBUG=1 # -O0 -g
make platform=ios-arm64 # cross-compile target
make clean
Output: virtualjaguar_libretro.{dylib,so,dll} at the repo root.
Test
make test # full white-box test suite
./test/regression_test.sh ./virtualjaguar_libretro.so # screenshot regression vs test/baselines/
make benchmark # headless wall-clock perf (see docs/profiling.md)
make test re-invokes the build with TEST_EXPORTS=1 (link-test.T / exports-test.list) so the test binaries can dlsym into the emulator internals. make (default) restores the production-slim symbol set.
Lint (run before pushing)
CI runs all of these as gates. Run them locally to avoid round-trips:
bash scripts/c89-lint.sh # mid-block declarations, declaration-after-statement
bash scripts/check-info-version.sh # display_version matches Makefile CORE_BASE_VERSION
ec # editorconfig-checker (install: brew install editorconfig-checker)
cppcheck --enable=warning,performance,portability \
--suppressions-list=cppcheck-suppressions.txt \
-i src/m68000 -i src/bios -i libretro-common src/ libretro.c
clang-format-diff -p1 -style=file < <(git diff -U0 develop...HEAD) # advisory; format check on changed lines
Pre-commit hook
scripts/install-hooks.sh installs a one-line pre-commit that runs c89-lint.sh against staged .c files. Run it once after cloning:
bash scripts/install-hooks.sh
Commit style
- Imperative present (
fix bug, notfixed bug). - Subject ≤ 72 chars; body wrap ~72.
- Prefix tags help skim
git log:ci:,build:,fix:,feat:,docs:,test:,refactor:,perf:. - Reference issues / PRs in the body, not the subject.
C89 / GNU89 strict
The libretro buildbot uses MSVC on Windows — MSVC C89 mode is strict about declarations-before-statements and forbids C99 features. See CLAUDE.md for the full rule set.
Releases
See docs/release-process.md for the full release flow (cut release/X.Y.Z from develop, tag on master, back-merge to develop).