Skip to content

Decouple emulator build from launcher submodule + multi-arch CI#2

Merged
eggfly merged 7 commits into
mainfrom
fix/decouple-and-multiarch
Jun 3, 2026
Merged

Decouple emulator build from launcher submodule + multi-arch CI#2
eggfly merged 7 commits into
mainfrom
fix/decouple-and-multiarch

Conversation

@eggfly

@eggfly eggfly commented Jun 2, 2026

Copy link
Copy Markdown
Collaborator

Summary

Make the emulator robust against upstream launcher reshuffles, and ship cross-platform release artifacts.

Why

Main has been red since 2026-05-22 (f03ba9e Migrate vendor submodule from UserDemo to Launcher). All 4 build jobs fail with fatal error: 'miniaudio.h' file not found — symptom of a deeper problem: every time the launcher submodule reshuffles (adds a component, moves a file, gains a SDL guard), the emulator CMake silently falls behind. This PR addresses the structural issue, not just the symptom.

What changes

Structural (cmake/)

  1. cmake/launcher_sources.cmake — single source-of-truth for which files/paths the emulator pulls from vendor/M5CardputerZero-Launcher. Probes both old and new locations for files that have moved (keyboard_input.c: src/hal/; images: ui/imagesAPPLaunch/share/images). Adding a launcher third-party include is now a one-liner here.

  2. cmake/third_party.cmakeemu::compat_stubs / emu::miniaudio / emu::launcher_apply INTERFACE libs. Centralizes platform audio framework links (CoreAudio/AudioToolbox/AudioUnit on macOS, asound/dl/pthread on Linux). Gates src/compat to Windows-only so the sys/wait.h stub doesn't shadow real system headers on Unix.

  3. cmake/patches/apply_vendor_workarounds.cmake — temporary, narrowly-scoped patches against the launcher submodule with explicit tracking PR links. Idempotent (re-running cmake on a patched tree is a no-op). Each entry self-skips once upstream is fixed, and is removed in the same emu commit that bumps the submodule.

    Currently one entry: drops the #if !defined(HAL_PLATFORM_SDL) guard around UISetupPage in launcher, because (a) ui_app_launch.cpp references the class regardless of guard, and (b) the class body already uses HAL — residual ioctl/i2c are already #ifdef __linux__. Proper upstream fix will follow as a Launcher PR.

CI (.github/workflows/build.yml)

Job Runner Artifact
macos-arm64 macos-14 M5CardputerZero-Emulator-macOS-arm64.tar.gz
macos-x64 macos-13 M5CardputerZero-Emulator-macOS-x64.tar.gz
macos-universal macos-14 M5CardputerZero-Emulator-macOS-universal.tar.gz (lipo merge)
windows-x64 windows-latest (MSYS2 MINGW64) M5CardputerZero-Emulator-Windows-x64.zip
linux-x64 ubuntu-22.04 M5CardputerZero-Emulator-Linux-x64.tar.gz
web ubuntu-22.04 M5CardputerZero-Emulator-Web.zip + Playground
  • actions/checkout bumped to v5 (Node 20 deprecation).
  • macOS uses dylibbundler for self-contained bundles.
  • Windows DLL walker now does a transitive pass.
  • Linux installs libasound2-dev (miniaudio ALSA backend).

Local verification

$ file build/cardputer-emu
build/cardputer-emu: Mach-O 64-bit executable arm64
$ ./build/cardputer-emu  # opens, loads APPLaunch.dylib, renders skin

Follow-up (separate PRs)

  • M5CardputerZero-Launcher PR: drop the SDL guard properly, route remaining raw ioctl//sys/class/... calls through HAL. Once merged, bump the submodule here and remove entry Some submodules are misssing or wrong url #1 from apply_vendor_workarounds.cmake.
  • Optional: pin the launcher submodule to a tested SHA (rather than tracking main) so launcher's main can move freely without breaking emu CI.

Tracking

eggfly added 2 commits June 2, 2026 22:25
Three structural changes to make the emulator robust against upstream
launcher reshuffles and to ship cross-platform release artifacts:

1. cmake/launcher_sources.cmake — single source-of-truth for which files
   and include paths the emulator pulls from vendor/M5CardputerZero-Launcher.
   Probes for keyboard_input.c at both old (src/) and new (hal/) locations.
   Probes for the APPLAUNCH images dir at both old (ui/images) and new
   (APPLaunch/share/images) locations. Adding a launcher third-party
   component (e.g. miniaudio) is now a one-line edit here, not three
   target_include_directories calls scattered across CMakeLists.txt.

2. cmake/third_party.cmake — emu::compat_stubs / emu::miniaudio /
   emu::launcher_apply INTERFACE libraries. Centralizes platform audio
   framework links (CoreAudio/AudioToolbox/AudioUnit on macOS,
   asound/dl/pthread on Linux). Gates src/compat to Windows-only so the
   sys/wait.h stub doesn't shadow real system headers on Unix. Picks up
   the launcher's own thpool.h stub if shipped.

3. cmake/patches/apply_vendor_workarounds.cmake — temporary, narrowly
   scoped patches against the launcher submodule with explicit upstream
   PR references. Idempotent: re-running cmake on an already-patched
   tree is a no-op; once upstream merges the fix, the entry self-skips
   and is removed in the same emu commit that bumps the submodule.

   Currently patches:
   - ui_app_setup.hpp: drop the  guard
     so UISetupPage compiles on emu (the class body already uses HAL,
     residual ioctl/i2c are inside #ifdef __linux__). Tracking PR TBD
     against M5CardputerZero-Launcher.

CI rewrite:
- macOS arm64 (macos-14) + macOS x64 (macos-13) parallel build matrix
- macOS Universal: lipo-merge of arm64 + x64 artifacts
- Windows x64 (MinGW), Linux x64 (ubuntu-22.04), Web (WASM)
- actions/checkout bumped to v5 (Node 20 deprecation)
- macOS dylibbundler bundles non-system dylibs next to the binary
- Windows DLL walker now does a transitive pass for nested deps
- Linux installs libasound2-dev (miniaudio backend)
- Pre-release artifacts renamed with explicit arch suffixes
Three follow-ups for the matrix CI:

1. cmake/patches: tighten ui_app_launch.cpp Linux-only registrations to
   also skip when HAL_PLATFORM_SDL is set. The launcher source uses
   #ifdef __linux__ to gate Linux-only page registrations, but the page
   header files themselves use #if !defined(HAL_PLATFORM_SDL). When emu
   builds on a Linux runner, both __linux__ and HAL_PLATFORM_SDL are
   defined: the registrations activate but the classes are excluded,
   producing 'UICameraPage' was not declared errors. Patch the cpp to
   use #if defined(__linux__) && !defined(HAL_PLATFORM_SDL) so the two
   guards align. Tracking PR TBD against Launcher.

2. CMakeLists: include APPLAUNCH_HAL_SDL_C/CPP sources in both the
   Windows static-link cardputer-emu target and the Emscripten web
   target. Both are statically linked (no dlopen / dynamic_lookup
   escape hatch), so they need every hal_* symbol resolved at link
   time. Linux + macOS shared dylib path was unaffected.
eggfly added 5 commits June 2, 2026 22:45
…orkaround

Two follow-ups discovered after the previous CI round:

1. src/emu_launcher_stubs.c — provides LV_EVENT_BATTERY,
   LV_EVENT_WIFI_INFO, g_launch_thread_pool. Launcher's own main.cpp
   defines these globals on device, but the emulator runs its own
   src/main.cpp. The Unix shared-library path resolves them at dlopen
   time via dynamic_lookup; static-linked targets (Windows + Web) need
   real storage. Linked into both windows and web targets only.

2. cmake/patches: workaround #3 — hal_filesystem_sdl.cpp is missing
   <stdio.h> for snprintf. Compiles on glibc/libc++ where <string.h>
   transitively pulls it in, fails on MSYS2. Trivial header patch
   tracked by Launcher PR #48; will self-skip once that lands.

Tracking PR (Launcher): CardputerZero/launcher#48
Launcher's ui_app_hack.hpp includes <winsock2.h> on Windows and calls
gethostname() in build_netinfo_page(). Statically-linked Windows emu
needs ws2_32 to resolve __imp_gethostname; macOS/Linux were unaffected
because gethostname is in libc there.
Launcher PR #48 merged: HAL_PLATFORM_SDL guard removed from
ui_app_setup.hpp, ui_app_launch.cpp gates Linux-only registrations
with the right (linux && !sdl) combination, hal_filesystem_sdl now
includes <stdio.h>, and hal_wifi_disconnect has an SDL stub.

- Bump vendor/M5CardputerZero-Launcher: cff863b → 92d4434
- Drop all three workaround entries in cmake/patches; the file remains
  as the documented hook for the next time we need one.
- Add page_app.h generation to cmake/launcher_sources.cmake. Launcher's
  SConstruct runs generate_page_app_includes.py at build time to
  produce that header from the .hpp files in page_app/. The launcher
  repo gitignores it. We replicate the generator in pure CMake so a
  vanilla cmake build works without invoking SCons.
The shared APPLaunch dylib gets HAL_PLATFORM_SDL=1 via target_compile_
definitions, but the web (cardputer-emu-web) and Windows static-link
(cardputer-emu) targets that compile the same source files inline did
not — they fell back to the un-SDL'd code paths and tried to include
<linux/dma-buf.h> from ui_app_camera.hpp.

Set HAL_PLATFORM_SDL=1 explicitly on both targets.
GitHub-hosted macos-13 (Intel) free runners have been queueing for 1+
hour, blocking PR completion. Apple Silicon shipped in 2020; users
still on Intel Macs without Rosetta 2 are negligible for this project.
Drop the x64 build (which fed the universal lipo) and ship a single
arm64 tarball.

If x64 demand surfaces, build it offline from a developer machine and
attach to the release manually, or revisit the matrix once GitHub
runner availability improves.
@eggfly eggfly merged commit 5de762b into main Jun 3, 2026
5 checks passed
@eggfly eggfly deleted the fix/decouple-and-multiarch branch June 3, 2026 04:45
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