Rewrote 20 issue writeups to the extern/runtime-class vocabulary (#foreign→extern, foreign_class_map→runtime_class_map, parseForeignClassDecl→parseRuntimeClassDecl, findForeignMethodInChain→findRuntimeMethodInChain, dedupeForeignSymbol→ dedupeExternSymbol, is_foreign_c_api→is_extern_c_api, stale filename refs to the renamed examples, foreign-class→runtime-class, bare foreign→extern). Renamed issues/0043-…-foreign-class-…→…-runtime-class-…. PHASE 9 COMPLETE — 9.4 GATE PASSES: zero 'foreign' across src/library/examples/ issues/docs/editors/specs/readme/CLAUDE, excluding only the SQLite API constant SQLITE_CONSTRAINT_FOREIGNKEY + vendored sqlite3.c/.h (upstream third-party). Suite green (644 corpus / 443 unit, 0 failed).
129 lines
5.8 KiB
Markdown
129 lines
5.8 KiB
Markdown
**FIXED.** Two parts, both needed for Finder/`open` to work:
|
|
|
|
1. **cwd-relative assets** — `SdlPlatform.init` now chdir's to
|
|
`SDL_GetBasePath()` when running from inside a `.app` (sx commit
|
|
`b31fbae`, `library/modules/platform/sdl3.sx`), mirroring uikit.sx's iOS
|
|
`chdir_to_bundle`. Gated to the `.app` case so the `sx run` dev flow keeps
|
|
the project CWD.
|
|
2. **Gatekeeper-rejected signature** — the bundle was signed with a
|
|
*Development* cert, which `spctl` rejects, so a standalone `open` wouldn't
|
|
launch it. Switched the macOS build to **ad-hoc** signing (the bundler's
|
|
macOS/sim default — just leave the codesign identity empty; game commit
|
|
`d80a350`, `build.sx`).
|
|
|
|
Verified: a plain `cd game && sx build main.sx` then `open
|
|
sx-out/macos/SxChess.app` launches and renders (was: instant `stbtt` segfault
|
|
on missing font, or no launch at all). It was NOT App Translocation — the
|
|
bundle had no `com.apple.quarantine` xattr.
|
|
|
|
# Symptom
|
|
|
|
A bundled macOS `.app` built with `sx build` crashes on launch when started
|
|
via Finder double-click or `open Foo.app`, but runs fine when launched from a
|
|
shell whose CWD is the bundle directory.
|
|
|
|
Observed: `open sx-out/macos/SxChess.app` → process exits within ~1s (segfaults
|
|
inside `stbtt_ScaleForPixelHeight` because the font buffer is null — the asset
|
|
wasn't found).
|
|
Expected: double-click / `open` launches the app and it finds its bundled
|
|
assets, same as on iOS.
|
|
|
|
Root: assets are loaded with **CWD-relative** paths (e.g.
|
|
`"assets/fonts/default.ttf"`), but Finder/`open` start a GUI app with `CWD=/`,
|
|
so the relative path resolves against `/` and the file is missing.
|
|
|
|
# Reproduction
|
|
|
|
Any consumer that bundles an `assets/` dir and loads from it by relative path.
|
|
Minimal shape (real case: `/Users/agra/projects/game`):
|
|
|
|
```sx
|
|
// main.sx — loads assets by CWD-relative path
|
|
g_pipeline.init_font("assets/fonts/default.ttf", 32.0, dpi); // -> read_file_bytes
|
|
g_chess_game.pieces.load("assets/chess/pieces.png", gpu); // -> read_file_bytes
|
|
```
|
|
|
|
```sh
|
|
cd game && sx build main.sx # produces sx-out/macos/SxChess.app (assets copied in)
|
|
|
|
# Works (CWD = bundle dir, so "assets/..." resolves):
|
|
cd sx-out/macos/SxChess.app && ./SxChess
|
|
|
|
# Fails (CWD = /, asset not found -> null buffer -> stbtt segfault):
|
|
open sx-out/macos/SxChess.app
|
|
# or double-click in Finder
|
|
```
|
|
|
|
`add_asset_dir("assets", "assets")` in `build.sx` correctly copies the tree
|
|
into the flat `.app` (binary at `SxChess.app/SxChess`, assets at
|
|
`SxChess.app/assets/...`), so the files ARE present in the bundle — they're just
|
|
not found because the lookup is CWD-relative and CWD isn't the bundle.
|
|
|
|
# Root cause
|
|
|
|
The macOS SDL startup never reorients CWD (or the asset root) to the bundle.
|
|
`SdlPlatform.init` ([library/modules/platform/sdl3.sx:35](../library/modules/platform/sdl3.sx#L35))
|
|
calls `SDL_Init(SDL_INIT_VIDEO)` and creates the window but does no `chdir`,
|
|
so `read_file_bytes`
|
|
([library/modules/ui/glyph_cache.sx:202](../library/modules/ui/glyph_cache.sx#L202),
|
|
and the chess `extern read_file_bytes`) opens paths relative to whatever CWD
|
|
the launcher set — `/` under Finder/`open`.
|
|
|
|
The other platforms already handle this:
|
|
- **iOS**: [library/modules/platform/uikit.sx:346](../library/modules/platform/uikit.sx#L346)
|
|
explicitly `chdir`s to the bundle's `resourcePath()` at startup, with the
|
|
comment "iOS apps start with CWD=/. chdir to the bundle's resourcePath so the
|
|
[assets resolve]".
|
|
- **Android**: [library/modules/platform/android.sx:71](../library/modules/platform/android.sx#L71)
|
|
routes `read_file_bytes` through `AAssetManager` so paths resolve against the
|
|
APK assets regardless of CWD.
|
|
|
|
macOS has neither — so it only works by accident when launched from a shell
|
|
sitting in the bundle dir.
|
|
|
|
# Investigation prompt
|
|
|
|
For a fresh session picking this up:
|
|
|
|
The fix mirrors the iOS precedent. In `SdlPlatform.init`
|
|
([sdl3.sx:35](../library/modules/platform/sdl3.sx#L35)), before any asset is
|
|
loaded, reorient to the bundle's resource directory **on macOS only** (leave
|
|
wasm/emscripten and the dev `sx run` path alone — those legitimately want the
|
|
project CWD).
|
|
|
|
Recommended approach — `SDL_GetBasePath()`:
|
|
- SDL3 `SDL_GetBasePath()` returns the directory containing the executable
|
|
(for a `.app`, that's `SxChess.app/` where the assets were copied). `chdir`
|
|
to it at the top of `init` when `BuildOptions.is_macos` (gate so `sx run`
|
|
during development isn't affected — or gate on "the base path differs from
|
|
CWD and contains an `assets/` dir").
|
|
- Add the `extern` decl for `SDL_GetBasePath` (returns `*u8`, SDL-owned) and
|
|
call `chdir` (already used by uikit.sx — reuse the same `extern`).
|
|
|
|
Alternative (no SDL dependency): `_NSGetExecutablePath` + `dirname`, same as a
|
|
plain macOS resolve. SDL_GetBasePath is simpler and already links SDL3.
|
|
|
|
Things to verify / watch:
|
|
- Don't chdir for the `sx run <file>` (JIT) dev flow or for wasm — only the
|
|
bundled AOT macOS app. The cleanest gate is the bundle context; if `init`
|
|
can't see `BuildOptions`, gate on `SDL_GetBasePath()` returning a path that
|
|
ends in `.app/` (bundled) vs the build dir (dev).
|
|
- After chdir, the existing `"assets/..."` relative loads resolve unchanged —
|
|
no call-site changes needed in consumers (chess, glyph_cache).
|
|
- Confirm the iOS path (uikit, doesn't use SdlPlatform) is untouched.
|
|
|
|
# Verification
|
|
|
|
```sh
|
|
cd game && sx build main.sx
|
|
open sx-out/macos/SxChess.app # must launch and stay up (board + pieces render)
|
|
# screenshot / pgrep -lf sx-out/macos/SxChess -> alive after a few seconds
|
|
```
|
|
|
|
Before the fix: `open` → exits ~1s (stbtt segfault, null font buffer).
|
|
After: `open` and Finder double-click both launch and render, matching the
|
|
`cd bundle && ./SxChess` behavior.
|
|
|
|
Also re-run host + cross suites to confirm no platform-module regression:
|
|
`zig build && zig build test && bash tests/run_examples.sh`.
|