Files
nxnative-easy/docs/reference/packing.md
T
seedds f171b23289 Discover Homebrew .NET runtimes for standalone build tools
Derive DOTNET_ROOT from dotnet's Microsoft.NETCore.App runtime listing and
export it to both explicit and inherited build environments. Preserve caller
overrides, use the build environment for discovery, and leave discovery
unchanged on probe failures instead of treating Homebrew's wrapper directory
as a runtime root.

Add regression coverage and document the packing failure and its resolution.
Based on PR #284.

Co-authored-by: Jose Rosendo <josemrb99@gmail.com>
(cherry picked from commit 89744da753)
2026-10-26 19:35:11 -06:00

3.7 KiB

Packing

Build tools

Homebrew .NET is on PATH but apphosts cannot find the runtime

  • Symptom: the first extraction stops with nx_extract exit code 131 and .NET location: Not found, even though dotnet is on PATH. The shader translator can fail the same way.
  • Cause: standalone .NET apphosts search runtime roots and registered installations, not PATH (.NET runtime discovery). Homebrew's formula installs the runtime under libexec and its bin/dotnet can be a wrapper that sets DOTNET_ROOT only for its own child (Homebrew caveat). Resolving that wrapper's symlink gives bin, not the runtime root.
  • Fix: scripts/build_ipa_from_nsp.py configure_dotnet derives the root from the Microsoft.NETCore.App entry in dotnet --list-runtimes, using the build's environment, before any extraction or survey. It exports DOTNET_ROOT both to that environment and to os.environ, for tools launched with an explicit environment and those that inherit it. Caller-supplied roots, including architecture-specific overrides, retain precedence. A failed or malformed probe leaves the environment unchanged rather than guessing the wrapper's directory.
  • Found on: Balatro, first extraction with Homebrew .NET (PR #284). Applies to every game's build on that installation setup.

Compressed inputs

NSZ decompression rejects --keys

  • Symptom: decompress NSZ stops immediately with nsz: error: unrecognized arguments: --keys ….
  • Cause: nsz 4.6.1 has no --keys argument. It loads keys.txt beside sys.argv[0], or falls back to ~/.switch/prod.keys, while importing its modules, before parsing arguments (4.6.1 key loader). Newer upstream code supports --keys; staging keys.txt also supports 4.6.1.
  • Fix: scripts/build_ipa_from_nsp.py decompress_nsz links the file selected by -k as keys.txt in the conversion's temporary folder and runs nsz -D there, with sys.argv[0] set to nsz before import. Input and output paths are absolute. The temporary folder and link are removed on success or failure; the user's default keys are untouched.
  • Found on: Super Mario Odyssey, converting its v0 NSZ. Applies to NSZ and XCZ inputs for every game.

Desktop build worker

Prepare game fails at os.setsid()

  • Symptom: clicking Prepare game stops before any build tools start, with PermissionError: [Errno 1] Operation not permitted at build_session.py os.setsid().
  • Cause: Foundation Process already launches the worker as its own process-group leader on macOS. POSIX rejects setsid() for a group leader. A normal Python subprocess launch did not expose this difference, so the original regression test missed the GUI path.
  • Fix: reuse the existing group when os.getpgrp() == os.getpid(); call setsid() only for a worker that still shares its parent's group. Cancellation still signals the worker's separate group. Do not suppress unrelated permission failures. Added regression coverage for Foundation Process, an existing group leader, an existing session leader and a normal subprocess launch, including cancellation.
  • Found on: a user's clean desktop installation, before game detection; reproduced locally with a Swift Foundation launcher. Applies to every Mac/iPhone game preparation, independent of the game, keys or saves. Released in 1.4.2/build 7.