Add native macOS simulator app packaging

This commit is contained in:
Adolfo Reyna
2026-09-22 16:21:05 -04:00
parent 72089f74f3
commit fd82efe08f
3 changed files with 85 additions and 12 deletions
@@ -99,12 +99,10 @@ logs. HTTP 200 or a package simply appearing in `/api/apps` is insufficient.
## Host simulator (buildsim) + web viewer
The POSIX simulator runs the real firmware (LVGL, services, web server) on
macOS/Linux with an SDL backend. macOS has no visible window (upstream
`.github/workflows/build-simulator.yml`: "macOS simulator currently fails due
to main thread requirement for rendering" — AppKit menu init must happen on
the process main thread, but FreeRTOS-POSIX parks main in `sigwait` and runs
everything on pthreads). The supported loop is **headless + web viewer**:
screenshots render server-side regardless of any window.
macOS/Linux with an SDL backend. On current firmware, `Main.cpp` runs SDL's
event loop on the process main thread while FreeRTOS runs on a separate thread.
This is required by AppKit and supports a native macOS window as well as the
web viewer. `SDL_VIDEODRIVER=dummy` remains useful for headless automation.
Code locations:
@@ -133,11 +131,14 @@ env -u ESP_IDF_VERSION -u IDF_PATH cmake --build buildsim --target TactilityKern
app-module crypt-module gps-module http-module lvgl-module lvgl-window-manager-module service-module
env -u ESP_IDF_VERSION -u IDF_PATH python3 Buildscripts/release-sdk-posix.py /tmp/sim-sdk
# release + headless run (MUST run from the firmware root: release-simulator.sh
# uses relative version.txt / Data paths)
# release (MUST run from the firmware root: release-simulator.sh uses relative
# version.txt / Data paths)
sh Buildscripts/release-simulator.sh buildsim /tmp/simrun
(cd /tmp/simrun && SIM_DISPLAY_W=480 SIM_DISPLAY_H=320 SDL_VIDEODRIVER=dummy \
nohup ./Tactility > /tmp/sim_web.log 2>&1 &)
# Native macOS window + web API. Run this from the release directory because
# data/ and system/ are relative to the process working directory.
(cd /tmp/simrun && SIM_DISPLAY_W=480 SIM_DISPLAY_H=320 \
nohup ./Tactility > /tmp/sim_gui.log 2>&1 &)
# For CI/headless operation, set SDL_VIDEODRIVER=dummy instead.
curl -s --max-time 5 http://127.0.0.1/api/sysinfo | head -c 120
```
@@ -146,7 +147,8 @@ matching on-device screenshots). ES3C35P panel is 320x480 portrait in DTS but
presents 480x320 landscape; ES3C28P is 320x240. The chosen geometry is logged
as `Simulator Sim display WxH`. `SDL_VIDEODRIVER=dummy` is expected to log one
`SdlDisplay Failed to create SDL window: Couldn't find matching render
driver` line — LVGL still renders and screenshots work.
driver` line — LVGL still renders and screenshots work. A native macOS launch
must not emit that line.
### Web viewer, touch, screenshots
@@ -187,6 +189,14 @@ URLs would 404 at the edge (no `/api` mount there).
- **Rebuild ≠ redeploy.** `cmake --build buildsim` updates `buildsim/` only.
Re-run `release-simulator.sh`, restart the process, then retest. A stale
`/tmp/simrun/Tactility` serves old handlers with new logs nowhere to be found.
- **One simulator owns port 80.** Do not launch a second instance while another
simulator is listening: it will initialize LVGL but fail `bind/listen`, so its
app API and viewer target the other process. Identify the listener with
`lsof -nP -iTCP:80 -sTCP:LISTEN`, stop only the intended simulator, then
release/restart it before installing or running POSIX apps.
- **Input is cross-thread on macOS.** SDL event pumping occurs on the real main
thread; LVGL and web touch injection run elsewhere. Keep all shared pointer,
key-queue, and touch-override state under `sdl_input.cpp`'s mutex.
- **C array `sizeof` decay.** A helper like
`f(HttpServerRequest*, char uri[256])` sees `sizeof(uri) == 8`, truncating
`get_uri` output to 7 chars (`/api/sy`, `/sim/ap` 404s). Pass the size