Matthew Stanley
5959ef2fdd
feat(tools): shared macOS release packager for game repos
...
tools/package_release.ps1 packages this framework's BIOS-only runtime, and
each game repo carries its own Windows packager. There was no macOS
equivalent at either level, so the first macOS release (Crash Bandicoot) was
assembled by hand and TombaRecomp already carries a private copy of most of
this logic. Add the generic one here so titles configure rather than
duplicate it.
Takes an already-built runtime plus the per-game identity and produces a
signed, relocatable .app in a staged release folder, archived as
<package>-<version>-macos-<arch>.zip with a .sha256 sidecar — the naming the
game repos' Windows releases already use. It does not build; the game's
build script builds, then calls this.
Release gates, porting the intent of the Windows packager to macOS:
- self-containment via otool (only OS libraries or bundled Frameworks)
- no baked absolute BIOS path, and no build-machine home path. The Windows
gate keys on a drive letter; the macOS tell is a path rooted under
/Users, /Volumes and friends. Matching bare "/...SCPH*.BIN" instead would
flag both the correct relative default "bios/SCPH1001.BIN" and the usage
string "/path/to/SCPH1001.BIN" in every binary.
- the 512 KiB OpenBIOS image and its MIT notice are present
- every --require-mod package is present, so a title cannot ship a launcher
whose Mods page silently vanished
- no disc / retail BIOS / memory-card / generated / local-state files
- saves/ ships empty
- the .app carries a valid signature
The mod catalog is taken from the repo's reviewed source, never the build
tree: a developer build dir accumulates mods/state.toml with enhancements
switched on, which would silently flip a title's default presentation for
every player. Packaging from a build tree without --mods-src is refused.
Bundle layout: staged data lives in Contents/Resources with symlinks from
Contents/MacOS. The runtime resolves bios/, assets/ and mods/ beside the
real executable, but codesign treats anything non-executable under
Contents/MacOS as nested code and rejects the whole bundle —
mods/packages/<pkg>/<version>/ parses as a versioned bundle. codesign seals
a symlink without descending, so this signs cleanly and path resolution is
unchanged. Signing is deliberately not --deep for the same reason.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com >
2026-08-03 18:19:34 -07:00
..
2026-07-20 14:13:46 -07:00
2026-07-02 16:27:57 -07:00
2026-06-25 23:23:15 -07:00
2026-07-06 11:51:36 -07:00
2026-06-27 21:06:04 -07:00
2026-05-07 17:57:34 -07:00
2026-05-03 16:43:07 -07:00
2026-05-05 21:06:44 -07:00
2026-05-05 21:06:44 -07:00
2026-05-05 21:06:44 -07:00
2026-05-07 17:57:34 -07:00
2026-05-07 17:57:34 -07:00
2026-05-07 17:57:34 -07:00
2026-05-03 16:43:07 -07:00
2026-05-03 16:43:07 -07:00
2026-05-03 16:43:07 -07:00
2026-05-07 17:57:34 -07:00
2026-05-07 17:57:34 -07:00
2026-05-07 17:57:34 -07:00
2026-05-07 17:57:34 -07:00
2026-05-07 17:57:34 -07:00
2026-05-07 17:57:34 -07:00
2026-05-07 17:57:34 -07:00
2026-05-07 17:57:34 -07:00
2026-05-03 16:43:07 -07:00
2026-05-07 17:57:34 -07:00
2026-05-07 17:57:34 -07:00
2026-05-07 17:57:34 -07:00
2026-05-03 16:43:07 -07:00
2026-05-07 17:57:34 -07:00
2026-05-07 17:57:34 -07:00
2026-04-11 21:26:04 -07:00
2026-05-07 17:57:34 -07:00
2026-05-05 21:06:44 -07:00
2026-05-05 21:06:44 -07:00
2026-05-05 21:06:44 -07:00
2026-05-05 21:06:44 -07:00
2026-05-05 21:06:44 -07:00
2026-05-05 21:06:44 -07:00
2026-05-07 17:57:34 -07:00
2026-05-05 21:06:44 -07:00
2026-05-07 17:57:34 -07:00
2026-04-11 21:26:04 -07:00
2026-05-07 17:57:34 -07:00
2026-05-07 17:57:34 -07:00
2026-05-07 17:57:34 -07:00
2026-05-05 21:06:44 -07:00
2026-05-07 17:57:34 -07:00
2026-05-07 17:57:34 -07:00
2026-05-07 17:57:34 -07:00
2026-04-11 21:26:04 -07:00
2026-04-11 21:26:04 -07:00
2026-05-07 17:57:34 -07:00
2026-05-07 17:57:34 -07:00
2026-05-07 17:57:34 -07:00
2026-05-07 17:57:34 -07:00
2026-05-07 17:57:34 -07:00
2026-05-03 16:43:07 -07:00
2026-05-03 16:43:07 -07:00
2026-05-03 16:43:07 -07:00
2026-05-03 16:43:07 -07:00
2026-05-07 17:57:34 -07:00
2026-05-05 22:13:06 -07:00
2026-05-07 17:57:34 -07:00
2026-05-07 17:57:34 -07:00
2026-05-03 16:43:07 -07:00
2026-05-03 16:43:07 -07:00
2026-05-03 16:43:07 -07:00
2026-05-07 17:57:34 -07:00
2026-05-07 17:57:34 -07:00
2026-05-07 17:57:34 -07:00
2026-05-07 17:57:34 -07:00
2026-05-07 17:57:34 -07:00
2026-05-07 17:57:34 -07:00
2026-07-06 11:51:36 -07:00
2026-05-03 16:43:07 -07:00
2026-05-07 17:57:34 -07:00
2026-05-09 19:09:48 -07:00
2026-07-06 11:51:36 -07:00
2026-05-03 16:43:07 -07:00
2026-05-07 17:57:34 -07:00
2026-05-07 17:57:34 -07:00
2026-05-07 17:57:34 -07:00
2026-05-17 11:29:26 -07:00
2026-05-07 17:57:34 -07:00
2026-05-03 16:43:07 -07:00
2026-05-07 17:57:34 -07:00
2026-05-09 19:09:48 -07:00
2026-05-09 19:09:48 -07:00
2026-05-09 19:09:48 -07:00
2026-05-07 17:57:34 -07:00
2026-07-06 11:51:36 -07:00
2026-05-11 12:34:49 -07:00
2026-05-07 17:57:34 -07:00
2026-05-07 17:57:34 -07:00
2026-05-07 17:57:34 -07:00
2026-05-05 22:13:06 -07:00
2026-05-07 17:57:34 -07:00
2026-05-03 16:43:07 -07:00
2026-04-14 01:34:27 -07:00
2026-04-14 01:34:27 -07:00
2026-04-28 21:29:19 -07:00
2026-05-03 16:43:07 -07:00
2026-04-28 21:29:19 -07:00
2026-04-28 21:29:19 -07:00
2026-04-28 21:29:19 -07:00
2026-04-28 21:29:19 -07:00
2026-04-28 21:29:19 -07:00
2026-07-10 00:00:09 -07:00
2026-07-10 00:00:09 -07:00
2026-07-10 01:54:46 -07:00
2026-07-10 00:00:09 -07:00
2026-07-10 01:54:46 -07:00
2026-07-10 00:00:09 -07:00
2026-05-29 21:14:30 -07:00
2026-07-23 17:10:23 -03:00
2026-05-03 16:43:07 -07:00
2026-07-28 22:46:55 -07:00
2026-05-29 21:14:30 -07:00
2026-05-29 21:14:30 -07:00
2026-07-28 09:22:28 -07:00
2026-05-03 16:43:07 -07:00
2026-05-03 16:43:07 -07:00
2026-05-03 16:43:07 -07:00
2026-05-03 16:43:07 -07:00
2026-04-26 00:36:15 -07:00
2026-04-30 14:26:19 -07:00
2026-04-28 21:29:19 -07:00
2026-04-14 02:03:14 -07:00
2026-05-03 16:43:07 -07:00
2026-05-03 16:43:07 -07:00
2026-04-30 14:26:19 -07:00
2026-05-03 16:43:07 -07:00
2026-05-03 16:43:07 -07:00
2026-04-30 14:26:19 -07:00
2026-05-03 16:43:07 -07:00
2026-05-03 16:43:07 -07:00
2026-05-03 16:43:07 -07:00
2026-06-12 15:15:08 -07:00
2026-05-13 01:31:27 -07:00
2026-05-13 01:31:27 -07:00
2026-05-29 23:42:16 -07:00
2026-07-26 09:39:24 -07:00
2026-07-06 11:51:36 -07:00
2026-07-20 15:58:43 -07:00
2026-06-26 21:18:26 -07:00
2026-07-14 15:29:50 -07:00
2026-05-03 16:43:07 -07:00
2026-04-28 21:29:19 -07:00
2026-04-28 21:29:19 -07:00
2026-04-21 14:23:09 -07:00
2026-04-21 14:23:09 -07:00
2026-04-28 21:29:19 -07:00
2026-07-06 11:21:20 -07:00
2026-04-24 00:29:06 -07:00
2026-04-14 01:34:27 -07:00
2026-04-14 01:34:27 -07:00
2026-04-29 14:46:26 -07:00
2026-04-24 00:29:06 -07:00
2026-04-24 00:29:06 -07:00
2026-04-24 00:29:06 -07:00
2026-04-14 01:34:27 -07:00
2026-04-14 01:34:27 -07:00
2026-04-14 01:34:27 -07:00
2026-04-14 01:34:27 -07:00
2026-04-14 01:34:27 -07:00
2026-04-14 01:34:27 -07:00
2026-04-14 01:34:27 -07:00
2026-05-03 16:43:07 -07:00
2026-04-28 21:29:19 -07:00
2026-04-26 00:36:15 -07:00
2026-04-24 00:29:06 -07:00
2026-06-07 12:32:19 -07:00
2026-05-03 16:43:07 -07:00
2026-04-26 00:36:15 -07:00
2026-05-30 00:02:33 -07:00
2026-05-03 16:43:07 -07:00
2026-04-28 21:29:19 -07:00
2026-06-18 14:56:12 -07:00
2026-07-18 06:30:37 -07:00
2026-04-14 01:34:27 -07:00
2026-04-14 01:34:27 -07:00
2026-04-23 17:50:47 -07:00
2026-04-28 21:29:19 -07:00
2026-04-24 00:29:06 -07:00
2026-04-28 21:29:19 -07:00
2026-04-24 00:29:06 -07:00
2026-05-03 16:43:07 -07:00
2026-04-28 21:29:19 -07:00
2026-04-14 01:34:27 -07:00
2026-05-29 21:14:30 -07:00
2026-04-24 00:29:06 -07:00
2026-07-29 03:18:10 -04:00
2026-05-29 21:14:30 -07:00
2026-07-29 03:18:10 -04:00
2026-04-24 00:29:06 -07:00
2026-05-13 01:31:27 -07:00
2026-05-17 21:58:55 -07:00
2026-07-02 22:42:26 -07:00
2026-04-28 21:29:19 -07:00
2026-05-03 16:43:07 -07:00
2026-04-30 14:26:19 -07:00
2026-07-20 00:07:33 -07:00
2026-07-14 22:44:31 -07:00
2026-04-21 14:23:09 -07:00
2026-07-29 03:18:10 -04:00
2026-08-03 18:19:34 -07:00
2026-07-28 09:22:28 -07:00
2026-06-29 20:43:40 -07:00
2026-04-28 21:29:19 -07:00
2026-04-28 21:29:19 -07:00
2026-04-28 21:29:19 -07:00
2026-04-28 21:29:19 -07:00
2026-04-29 22:20:55 -07:00
2026-05-03 16:43:07 -07:00
2026-05-03 16:43:07 -07:00
2026-04-13 21:19:32 -07:00
2026-04-29 22:20:55 -07:00
2026-04-29 22:20:55 -07:00
2026-04-29 22:20:55 -07:00
2026-05-29 23:29:05 -07:00
2026-05-03 16:43:07 -07:00
2026-05-03 16:43:07 -07:00
2026-07-29 03:18:10 -04:00
2026-04-28 21:29:19 -07:00
2026-04-24 00:29:06 -07:00
2026-04-21 18:13:51 -07:00
2026-05-03 16:43:07 -07:00
2026-05-03 16:43:07 -07:00
2026-04-29 14:46:26 -07:00
2026-04-28 21:29:19 -07:00
2026-04-24 00:29:06 -07:00
2026-04-29 14:46:26 -07:00
2026-07-23 17:10:23 -03:00
2026-04-13 21:19:32 -07:00
2026-04-13 21:19:32 -07:00
2026-05-29 21:14:30 -07:00
2026-04-28 21:29:19 -07:00
2026-07-06 11:51:36 -07:00
2026-04-14 01:34:27 -07:00
2026-04-14 01:34:27 -07:00
2026-04-14 01:34:27 -07:00
2026-04-14 01:34:27 -07:00
2026-04-28 21:29:19 -07:00
2026-04-28 21:29:19 -07:00
2026-07-28 09:22:28 -07:00
2026-07-06 11:51:36 -07:00
2026-05-03 16:43:07 -07:00
2026-04-28 21:29:19 -07:00
2026-05-03 16:43:07 -07:00
2026-06-21 13:43:34 -07:00
2026-04-28 21:29:19 -07:00
2026-04-29 21:15:09 -07:00
2026-04-29 14:46:26 -07:00
2026-04-29 14:46:26 -07:00
2026-05-03 16:43:07 -07:00
2026-07-19 12:11:56 -07:00
2026-07-20 14:06:26 -07:00
2026-07-06 11:51:36 -07:00
2026-04-29 14:46:26 -07:00
2026-04-29 14:46:26 -07:00
2026-04-29 14:46:26 -07:00
2026-04-29 14:46:26 -07:00
2026-04-29 14:46:26 -07:00
2026-07-06 11:51:36 -07:00
2026-04-29 14:46:26 -07:00
2026-04-30 13:10:05 -07:00
2026-04-30 13:10:05 -07:00
2026-05-30 12:06:59 -07:00
2026-04-28 21:29:19 -07:00
2026-07-03 09:04:17 -07:00
2026-04-29 14:46:26 -07:00