Skip to content

Cloud session: Rust workspace off macOS, rewriter fixes, gfx proposals

Status: done in a Linux cloud container (no Xcode, Metal, codesign or game files). The Rust changes were tested there; everything under gfx/ and runtime/ was only checked by reading the code and still needs a build and a game run on a Mac.

1. Tested here (cargo test, whole workspace green)

  • napple-build compiles off macOS: errno via std::io::Error::last_os_error() (was libc::__error, macOS only); clonefile(2) declared only on macOS, plain copy elsewhere. Behaviour on macOS is unchanged.
  • e2e::keep_cache_allows_resume was flaky (about 1 run in 4): it took any RomFS cache for the test title in the shared temp dir, and parallel tests delete theirs. It now looks only at its own cache dir (pipeline::cache_dir_name). 30 consecutive runs pass.
  • Rewriter, windows.rs: a64::direct_target matches bl too, so a bl inside an ldxr/stxr window was retargeted to an exit stub; the callee would have returned into the window copy with the scratch registers already restored. Now refused (the module is reported unhandled instead of silently wrong). Regression test call_inside_exclusive_window_is_refused.
  • Rewriter, rewrite.rs: a site that failed after emitting br x18 landing pads left them in the pad cache after rollback; a later site using the same table would branch into overwritten patch code. The cache is now pruned on rollback.
  • Build outputs untracked and ignored: gfx/build-disp/, audio|input|frontend/lib*.a, *.o, *.dSYM.

2. Proposed, needs a Mac (build + run)

  1. Pipeline-build hang (gfx/src/mtl_shader.m, gfx/src/mtl_priv.h). Shader builds get their own queue; background pipeline builds run on a serial queue; a pipeline is claimed before it is built, so a draw needing one still queued for prewarm builds it itself. Check: make -C gfx test; a cold start with a large pipelines.bin (LAS after a long session) reaches the title with no hang, and the pipeline_wait_us counter stays low. Compare first-room load time against the previous binary.
  2. Controller applet player counts (runtime/src/services/applet.c). Check the new log lines controller support: input storage N size ... in a game that shows the applet: one storage should be about 0x21C or larger, and game asked should then show the real counts (before: 1..0). Open question, not changed: libnx reads the result as 0xC bytes (player_count, selected_id, result); the runtime returns 8. If a game reads 0xC, the storage read fails or returns garbage. (applet.c uses strlcpy, so it only builds against macOS libc; that is fine for this project.)

3. Review notes on macOS-only code (not changed; for you to judge)

  • bundle::codesign uses --deep, which Apple deprecated for signing. It works for ad-hoc signing; signing the nested executables explicitly (runtime, then launcher, then the bundle) is the supported way if it ever starts failing.
  • bundle::find_tool takes a prebuilt napple-runtime from the checkout without checking it is newer than its sources, so a stale runtime can be packaged. runtime/Makefile also links ../frontend|input|audio/lib*.a without building them: run make -C input, -C audio, -C frontend first on a fresh clone (these libraries are no longer in git).
  • util::clean_stale_staging treats any live process with the same pid as the owner. Harmless (a stale directory is kept until later).
  • Info.plist has no NSMicrophoneUsageDescription. The games request audin:u; if the runtime ever opens the microphone, macOS will deny it.