Files
Joseph MattielloandClaude Opus 4.7 ee93fe5bde perf: make benchmark target + docs/profiling.md
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]>
2026-05-01 01:39:01 -04:00

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, not fixed 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).