5.1 Make targets¶
The place to start is make with no arguments, which prints every target
together with its description:
$ make
Available targets:
sdl-debug Configure and build the SDL-only frontend in Debug mode ...
...
There are 69 documented targets at the time of writing. The sections below
group them into families rather than listing them one by one, because make
is the authority here and the exact number changes.
The self-documenting convention¶
The convention is a single rule: a # comment line immediately above a
target is that target's description. The default target is a small awk
program over $(MAKEFILE_LIST) that pairs each such comment with the target
underneath it. Nothing else is maintained — there is no second list of targets
to keep in sync — so a target that exists is a target make shows.
There is one sharp edge. The awk keeps only the last # line before a
target, so a second comment line silently replaces the description rather than
extending it. That is not a hypothetical: eight targets, unit-test and
regression among them, advertised a sentence fragment for as long as nobody
happened to re-read the listing. The rule is therefore enforced rather than
remembered. make lint-makefile-help fails if any target's description would
be discarded, and it is a prerequisite of both make unit-test and
make regression; it costs about 8 ms of awk over one file, so it fails long
before anything expensive has started.
That gives you the rule to follow when you add a target: one # line above
it, and every word of rationale inside the recipe as @# comment lines. The
Makefile is full of those, and they are where the reasoning actually lives.
Build¶
sdl-* builds the SDL-only frontend and gui-* builds the Qt6 GUI, each in a
-debug and a -release flavour. Every build variant also has a -run target,
which builds and then runs, and a -clean target; make clean removes all of
them along with build/.
gui-release is the binary JNEXT ships and tests, and it is a PGO build: it depends on gui-release-pgo-gen, the instrumented twin, runs the
training and then compiles build/gui-release with the profile — see
5.5.
gui-release-non-pgo is the same Release build without PGO, in its own tree;
it is the one to measure code changes with.
The win-* family cross-compiles Windows executables with the MinGW toolchain.
win-release is the x64 Qt6 build; win-qt5-release and win32-qt5-release
are the legacy Qt5 legs, 64- and 32-bit, which keep a lower Windows floor than
the Qt6 build can offer; and win-sdl-release / win32-sdl-release are
SDL-only legs used to validate the cross-build rather than to publish anything.
The three published legs are PGO builds trained under wine; WIN_PGO=0 builds
any of them without, and win-release-non-pgo does that for the x64 one.
Separately, qt5-guard-build compiles the GUI against native Linux Qt5, purely
to keep that combination building.
Test¶
make unit-test builds build/ and runs every declared subsystem suite, and
make regression runs the screenshot and functional suite headless. Between
them they pull in a set of structural gates as prerequisites —
lint-assertions, lint-makefile-help, lint-thread-detach, lint-ascii-text, cli-check,
docs-check (which includes docs-devguide-cites-check),
traceability-check and friends — which is deliberate: it puts those checks in
your inner loop instead of leaving them for CI to discover. make regression
also runs make fuse-pgo, the FUSE Z80 opcode suite built against the PGO
tree's CPU core, because build/ — where make unit-test runs it — is neither
the shipped build nor a Release one. Alongside them,
make harness-selftest proves that the test harness itself fails loudly when
faults are injected into it, make build-matrix builds every combination of the
frontend options, make unit-test-sdl runs the declared suites a second time in
the SDL-only configuration (its own build/sdl-unit-test tree, so build/ stays
the Qt one), and make unit-test-dashboard runs the unit tests and refreshes the
committed per-subsystem status table.
Two more targets run the SDL-only suites on other operating systems.
make unit-test-sdl also works on macOS, where the test harness needs Homebrew's
bash, coreutils and grep (brew install bash coreutils grep; the target
puts them first on PATH for its own recipe only, and the harness refuses with
that install line when they are missing). make unit-test-win cross-builds the
same suites for Windows with the Fedora MinGW toolchain into
build/win-sdl-unit-test (dnf install mingw64-gcc mingw64-gcc-c++
mingw64-SDL3 mingw64-zlib mingw64-libpng mingw64-winpthreads wine-core
wine-common) and runs them under wine through test/wine-run.sh, with no
display variable set so no window can open on your desktop, under a UTF-8
locale (a non-ASCII file name cannot exist under LC_ALL=C), and, when run as
root (the CI container), with CAP_DAC_OVERRIDE and CAP_DAC_READ_SEARCH dropped for
wine and wineserver: wine emulates the Windows read-only attribute with a
permission bit that root ignores, where real Windows refuses even an
administrator. The test executables
link with an 8 MB stack (their fixtures hold emulators on the stack; Linux gives
a main thread 8 MB, MinGW 2 MB), while jnext.exe keeps the default and its
frame gate. Both need the SD image, which make sdcard-image provisions through
jnext's own download if it is missing. make unit-test-win is two steps,
unit-test-win-build (cross-build the tree) and unit-test-win-run (run it under
wine, no compiler needed), so the run step could later be taken over by a real
Windows host; it is part of the merge gate for every code change.
make regression-win runs the regression suite's screenshots and the
functional rows Windows can run against MinGW-built exes under wine: the Qt exe
as shipped minus PGO (win-release-non-pgo, with qoffscreen.dll bundled into
that test tree only), the SDL-only exe, and the native helpers from the SDL
unit-test tree. make regression-macos is its macOS twin (CI macos-regression).
ROWS="..." names rows. Neither is stamped; see
the regression suite.
The built tree is not yet a relocatable directory, so there is no recipe for
running it by hand on a real Windows machine, and none has been tried. What
stands in the way, in order of effort: JNEXT_BINARY (the CLI suite) and the
ffmpeg stub's path are compiled in as absolute paths; the suites run with the
source checkout as their working directory and read fixtures from it; the unit
harness itself needs bash 4, GNU timeout/grep -P and perl, and checks every
reported row ID against the suite's source files; the SD image is reached by
absolute path through JNEXT_TEST_SD_IMAGE. A bundle (executables, the MinGW
DLLs packaging/windows/bundle-dlls.sh copies, the manifest, the harness and
the sources it reads) is feasible, but it is its own piece of work.
Chapter 4. Testing covers what each of these actually proves.
Documentation¶
Each documentation source generates a committed output, and each output has a staleness check guarding it:
| Target | Renders | Guard |
|---|---|---|
docs-man |
doc/man/jnext.1 + USAGE.md from doc/man/jnext.1.md |
docs-man-check |
docs-userguide |
doc/user-guide from src/doc/user-guide |
docs-userguide-check |
docs-devguide |
doc/developer-guide from src/doc/developer-guide |
docs-devguide-check |
docs-devguide-diagrams |
the guide's committed SVGs from Graphviz .dot sources |
(same check) |
| (none) | the guide's file and line cites, checked against the code | docs-devguide-cites-check |
docs-screenshots |
the user guide's Qt screenshots (img/debugger-*.png, the main window, Preferences) from the running debugger |
none — see below |
make docs-check runs the first three guards and the cite check and aggregates their results, so
one stale document never hides another behind it. It is a prerequisite of both test
targets. For reading rather than checking, make read-userguide and
make read-devguide serve the rendered sites on localhost.
docs-screenshots is the odd one out: it regenerates pictures rather than
text, it needs a Qt build, an offscreen QPA platform and an SD image to boot,
and it has no staleness guard — a byte comparison would fail on any Qt or font
update rather than on a stale image.
1.3 explains what it
covers, what it does not, and why the gate was declined.
Packaging and version¶
package-src, package-rpm, package-deb, package-flatpak, package-macos
and the five package-win* variants each build one distributable.
package-test builds them all except macOS and Flatpak (the flatpak CI job builds
that) and then asserts their contents,
while package-contract-test runs only the hermetic script contract suites.
version prints the current version, and bump-patch / bump-minor /
bump-major bump it, commit, and tag. 5.3 covers
what those actually do.