Skip to content

Add CMake build support alongside the autotools build#23

Open
floitsch wants to merge 8 commits into
dciabrin:masterfrom
floitsch:cmake-support
Open

Add CMake build support alongside the autotools build#23
floitsch wants to merge 8 commits into
dciabrin:masterfrom
floitsch:cmake-support

Conversation

@floitsch

@floitsch floitsch commented Jul 7, 2026

Copy link
Copy Markdown

This adds a complete CMake build for all the examples, coexisting with the autotools/make build: the two systems are fully independent, neither references the other, and no existing file changes behavior. Users pick whichever they prefer:

cmake -B build
cmake --build build
# run an example:
cmake --build build --target 01-helloworld-gngeo   # also -gngeo-mvs, -mame, -mame-mvs

Layout

  • cmake/ngdevkit-toolchain.cmake — m68k-neogeo-elf cross toolchain, applied automatically by the top-level CMakeLists.txt (a plain cmake -B build works out of the box).
  • cmake/NGDevKit.cmake — the counterpart of build.mk/rom.mk/emu.mk: ELF → byte-swapped/padded P-ROMs (incl. .text2 2MB and bankswitching modes), z80 sound drivers via sdas/sdld, asset conversions (tiletool/paltool/vromtool/nsstool/furtool/soundtool), cartridge zip + MAME/GnGeo hash files via romtool, BIOS staging, memory card, and emulator run targets.
  • cmake/SharedAssets.cmake — builds the shared ngdevkit assets (fonts, logo, base sound driver, eye-catcher lib) once in the build tree; replaces the configure-time rsync/.prebuild copying. The CMake build never writes into the source tree.
  • One small CMakeLists.txt per example (including 00-template), mirroring its Makefile.
  • cmake/concat.py — portable replacement for cat + truncate (macOS has no truncate; python3 is already required by the ngdevkit tools).
  • CI: three new jobs building with CMake + Ninja on Linux, macOS and Windows/MSYS2, next to the unchanged make jobs. All six are green.

Notes

  • The BIOS can be overridden like with configure: cmake -B build -DAES_BIOS=path -DMVS_BIOS=path.
  • GnGeo probing (data file, GLSL blitter, CRT shader from the submodule, default ~/.gngeo/ngdevkit-gngeorc) is done at configure time, mirroring configure.ac.
  • On MSYS2 the prefixed z80-neogeo-ihx-* tools and m68k-neogeo-elf-{ar,ranlib} are currently shell-script wrappers that only work when spawned from an MSYS shell; the CMake build uses the real per-target binaries (<prefix>/z80-neogeo-ihx/bin, <prefix>/m68k-neogeo-elf/bin) so it also works with native process spawning. This keeps working unchanged once the wrappers are replaced upstream in ngdevkit-toolchain.
  • The macOS CI jobs (including the existing make ones) needed brew trust dciabrin/ngdevkit: recent Homebrew refuses formulae from untrusted third-party taps. That fix is included here and is probably wanted in ngdevkit's own CI as well.

floitsch added 8 commits July 7, 2026 16:08
Both build systems coexist and are fully independent:

- cmake/ngdevkit-toolchain.cmake: m68k-neogeo-elf cross toolchain,
  applied automatically by the top-level CMakeLists.txt
- cmake/NGDevKit.cmake: build rules mirroring build.mk/rom.mk/emu.mk
  (ELF -> byte-swapped P-ROMs, z80 sound drivers, asset conversions,
  cartridge zip + MAME/GnGeo hash files, emulator run targets)
- cmake/SharedAssets.cmake: shared ngdevkit assets built once for all
  examples, replacing the configure-time rsync/.prebuild mechanism
- one CMakeLists.txt per example, mirroring its Makefile
- CI jobs building with CMake on Linux, macOS and Windows/MSYS2

Usage: cmake -B build && cmake --build build
Run:   cmake --build build --target 01-helloworld-gngeo
The Makefile says 03_palette, which looks like a copy-paste slip;
the Makefile fix is done separately to keep the build systems'
changes independent.
Passing the raw `pkg-config --libs` output to target_link_libraries
mis-handles the two-token `-specs ngdevkit` form: the bare file name
would be rewritten into -lngdevkit. Instead of re-parsing the flags,
use the decomposition pkg-config already provides: -L directories via
target_link_directories, plain driver options via target_link_options
(passed verbatim), and libraries via target_link_libraries.
Recent Homebrew versions refuse to install formulae from untrusted
third-party taps, which broke both macOS jobs (make and cmake alike).
- resolve relative z80 sources against the example's source directory;
  the assembler runs in the binary directory, so user_commands.s was
  not found
- skip the compiler sanity checks: they archive a test object with
  ar/ranlib, and the MSYS2 ngdevkit-toolchain ships a non-functional
  m68k-neogeo-elf-ar.exe (unnoticed by the Makefile build, which never
  invokes ar)
The MSYS2 ngdevkit-toolchain package installs the prefixed tools
(m68k-neogeo-elf-{ar,ranlib}, z80-neogeo-ihx-*) as shell-script
wrappers named .exe. Those only work when spawned through an MSYS
shell, which is how the Makefile build runs them; native process
creation (cmake/ninja) fails with ERROR_BAD_EXE_FORMAT.

Prefer the real PE binaries from the per-target bin directories
(<prefix>/m68k-neogeo-elf/bin, <prefix>/z80-neogeo-ihx/bin), falling
back to the prefixed names on other platforms. With a working ar and
ranlib the compiler sanity checks pass again, so the earlier
CMAKE_<LANG>_COMPILER_WORKS workaround is reverted.
Freshly generated z80 sources failed to open ~30ms after nsstool
wrote them (?ASxxxx-Error-<cannot open>), while checked-out sources
assembled fine. Defender's real-time scan holds a transient exclusive
handle on new files; ninja's parallelism reopens them within
milliseconds, unlike the serial Makefile build. Exclude the workspace
from scanning, and make the build script list the generated assets on
failure for diagnosis.
The launcher decision tested WIN32, which describes the target system
and is false under the Generic cross toolchain. On the MSYS2 runner
the .py tools were thus 'executed' directly: cmd.exe resolves them via
file association, which exits 0 without running anything, so every
python-generated file (nss/instrument asm, srom.bmp, snd_commands.*)
was silently missing. Test CMAKE_HOST_WIN32 instead.

Also drop the speculative Defender exclusion from CI: the failure is
fully explained by the launcher bug.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant