mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-12 08:21:02 +02:00
Unify --fused with OTA launcher and require DEVKITPRO preflight for release builds.
This commit is contained in:
+45
-33
@@ -22,19 +22,25 @@ WSL — not cmd.exe or PowerShell (AD-008).
|
||||
### macOS / Linux
|
||||
|
||||
1. Install [devkitPro pacman](https://devkitpro.org/wiki/devkitPro_pacman).
|
||||
2. Install Switch tools:
|
||||
2. Install Switch tools (**required for `--fused`**):
|
||||
|
||||
```sh
|
||||
sudo dkp-pacman -S switch-dev
|
||||
```
|
||||
|
||||
3. Ensure `nacptool` and `elf2nro` are on `PATH` (or under
|
||||
`$DEVKITPRO/tools/bin` — the fused script prepends that when set).
|
||||
3. OTA launcher toolchain — **native or Docker** (either is fine):
|
||||
|
||||
**Optional:** Install [Docker](https://docs.docker.com/get-docker/) so fused
|
||||
builds can fall back to the pinned image when native tools are missing.
|
||||
```sh
|
||||
bash scripts/switch/install_devkitpro_deps.sh # native
|
||||
# or install Docker (same pin as fused builds)
|
||||
```
|
||||
|
||||
### Native OTA launcher (optional but required for in-console updates)
|
||||
4. Ensure `DEVKITPRO` is exported (typical macOS: `/opt/devkitpro`) and
|
||||
`nacptool` / `elf2nro` are on `PATH` (or under `$DEVKITPRO/tools/bin`).
|
||||
|
||||
Fused game builds can also use Docker when native `nacptool`/`elf2nro` are absent.
|
||||
|
||||
### Native OTA launcher (included in `--fused`)
|
||||
|
||||
In-console OTA uses a **separate DEVKITPRO NRO** (not LÖVE). Source:
|
||||
`native/switch-ota-launcher/`. Host protocol tests (no toolchain):
|
||||
@@ -45,26 +51,14 @@ make -C native/switch-ota-launcher host-test
|
||||
scripts/switch/build_ota_launcher.sh # host-test first; NRO needs DEVKITPRO/Docker
|
||||
```
|
||||
|
||||
Extra packages beyond `switch-dev`:
|
||||
`--fused` always builds the fused game, native OTA launcher, and dual-NRO SD
|
||||
zip. The same `*-switch.zip` is the OTA download asset. **DEVKITPRO is
|
||||
required.** OTA launcher: native packages **or** Docker — both are supported.
|
||||
|
||||
Release-like build from repo root:
|
||||
|
||||
```sh
|
||||
sudo dkp-pacman -S --noconfirm --needed switch-curl switch-mbedtls switch-zlib switch-zziplib
|
||||
# or: bash scripts/switch/install_devkitpro_deps.sh
|
||||
```
|
||||
|
||||
Packaging dual-NRO SD zip (launcher entry + fused game):
|
||||
|
||||
```sh
|
||||
scripts/switch/pack_sd_zip.sh dist/switch/game.nro VERSION out.zip dist/switch/gen1recomp-launcher.nro
|
||||
```
|
||||
|
||||
One-shot OTA release build (fused game + launcher + dual-NRO SD zip;
|
||||
the same `*-switch.zip` is the OTA download asset):
|
||||
|
||||
```sh
|
||||
# once: bash scripts/switch/install_devkitpro_deps.sh
|
||||
export DEVKITPRO=/opt/devkitpro
|
||||
scripts/build_switch.sh --fetch --ota --version X.Y.Z
|
||||
scripts/build_switch.sh --fetch --fused --version X.Y.Z
|
||||
```
|
||||
|
||||
See `native/switch-ota-launcher/README.md` and
|
||||
@@ -86,8 +80,7 @@ See `native/switch-ota-launcher/README.md` and
|
||||
| You install | Script does **not** install |
|
||||
| ----------- | --------------------------- |
|
||||
| bash, git, zip tooling the repo already expects | — |
|
||||
| `dkp-pacman` + `switch-dev` (native fused) | `dkp-pacman -S …` |
|
||||
| Docker (optional fused fallback) | Docker Engine |
|
||||
| `dkp-pacman` + `switch-dev` + OTA packages **or** Docker | `dkp-pacman -S …` |
|
||||
| A legal `.gb` ROM (to play) | Any ROM or game data |
|
||||
|
||||
---
|
||||
@@ -100,7 +93,7 @@ See `native/switch-ota-launcher/README.md` and
|
||||
| ---- | ------------ |
|
||||
| `--fetch` | Downloads pinned **love.nro** + **love.elf** into `.bazinga/love-nx/11.5-nx1/` and verifies SHA-256 against `scripts/switch/love-nx-11.5-nx1.sha256`. |
|
||||
| `--loose` | Packs `game.love`, copies pinned `love.nro` → `dist/switch/loose/` as `gen1recomp.nro` + `game.love` side by side. Needs the pin. |
|
||||
| `--fused` | Builds `dist/switch/gen1recomp-<ver>-switch.nro` (game in romfs) via `nacptool` + `elf2nro`, then packs `dist/switch/gen1recomp-<ver>-switch.zip` (SD-ready tree). Needs the pin + toolchain (native or Docker). GitHub Releases publish the **zip only**. |
|
||||
| `--fused` | Builds fused game NRO, OTA launcher NRO, and dual-NRO SD zip. **Requires DEVKITPRO** + `switch-dev`. OTA launcher: native packages or Docker. GitHub Releases publish the **zip only**. |
|
||||
|
||||
Rules:
|
||||
|
||||
@@ -145,13 +138,15 @@ scripts/build_switch.sh --fetch
|
||||
# Loose pair for iteration (fetch + assemble)
|
||||
scripts/build_switch.sh --fetch --loose
|
||||
|
||||
# Single fused NRO + SD-ready zip for a release-like artifact
|
||||
# Fused game + OTA launcher + dual-NRO SD zip for a release-like artifact
|
||||
scripts/build_switch.sh --fetch --fused --version 0.2.0
|
||||
```
|
||||
|
||||
Outputs land under `dist/switch/` (and `dist/switch/loose/` for loose mode).
|
||||
The fused path also writes `gen1recomp-<ver>-switch.nro.sha256` and
|
||||
`gen1recomp-<ver>-switch.zip` (+ `.sha256` sidecar for the zip).
|
||||
The fused path also writes `gen1recomp-<ver>-switch.nro` (game),
|
||||
`gen1recomp-<ver>-launcher.nro`, `gen1recomp-<ver>-game.nro`,
|
||||
`gen1recomp-<ver>-switch.nro.sha256`, and `gen1recomp-<ver>-switch.zip`
|
||||
(+ `.sha256` sidecar for the zip).
|
||||
|
||||
Offline packaging smoke (no network, no nacptool required):
|
||||
|
||||
@@ -217,9 +212,26 @@ A Switch packaging failure fails the entire release job. The release asset is
|
||||
|
||||
### Runner provisioning
|
||||
|
||||
The self-hosted Mac runner must have **native switch-tools** (`nacptool` /
|
||||
`elf2nro`) **and/or Docker** available. CI and release do not silently run
|
||||
`dkp-pacman -S`; keep the runner image/host provisioned per this guide.
|
||||
The self-hosted Mac runner **must** have **DEVKITPRO** installed and exported.
|
||||
`--fused` preflight fails early with setup steps if it is missing.
|
||||
|
||||
**One-time setup on the runner** (if not already present):
|
||||
|
||||
```sh
|
||||
# devkitPro pacman installer from https://devkitpro.org/wiki/devkitPro_pacman
|
||||
sudo dkp-pacman -S switch-dev
|
||||
export DEVKITPRO=/opt/devkitpro
|
||||
export PATH="$DEVKITPRO/tools/bin:$PATH"
|
||||
|
||||
# OTA launcher — pick one:
|
||||
bash scripts/switch/install_devkitpro_deps.sh # native
|
||||
# or ensure Docker is installed (same pin as fused builds)
|
||||
```
|
||||
|
||||
CI and release still run `scripts/build_switch.sh --fetch --fused`. Preflight
|
||||
requires DEVKITPRO and either native OTA packages or Docker. Without all of
|
||||
that, the job fails with the setup steps above. Scripts never auto-run
|
||||
`dkp-pacman -S` during CI.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -30,15 +30,15 @@ Extract the zip at the **root** of the microSD so you get:
|
||||
|
||||
```text
|
||||
sdmc:/switch/gen1recomp/gen1recomp.nro # native OTA launcher (hbmenu entry)
|
||||
sdmc:/switch/gen1recomp/gen1recomp-game.nro # fused LÖVE game (when OTA layout ships)
|
||||
sdmc:/switch/gen1recomp/gen1recomp-game.nro # fused LÖVE game
|
||||
sdmc:/switch/gen1recomp/version.txt
|
||||
sdmc:/switch/gen1recomp/pokemon-love2d/imports/
|
||||
sdmc:/switch/gen1recomp/pokemon-love2d/imports/mods/
|
||||
sdmc:/switch/gen1recomp/pokemon-love2d/imports/saves/...
|
||||
```
|
||||
|
||||
Older single-NRO zips only had `gen1recomp.nro` (the fused game). New OTA-ready
|
||||
zips use the dual-NRO layout above — open `gen1recomp` in hbmenu (the launcher).
|
||||
Older single-NRO zips only had `gen1recomp.nro` (the fused game). Current
|
||||
releases use the dual-NRO layout above — open `gen1recomp` in hbmenu (the launcher).
|
||||
|
||||
Merge folders if your OS asks. Any method works: **MTP** (DBI → Run MTP
|
||||
responder + a client), **direct SD** (Hekate UMS or a card reader), or **FTP**.
|
||||
|
||||
@@ -45,7 +45,13 @@ make
|
||||
# → gen1recomp.nro
|
||||
```
|
||||
|
||||
Or from repo root:
|
||||
Or from repo root (as part of `--fused`):
|
||||
|
||||
```bash
|
||||
scripts/build_switch.sh --fetch --fused --version X.Y.Z
|
||||
```
|
||||
|
||||
Standalone launcher build:
|
||||
|
||||
```bash
|
||||
scripts/switch/build_ota_launcher.sh
|
||||
@@ -64,4 +70,4 @@ Manifest: `scripts/switch/ota_launcher.manifest`.
|
||||
- Zip extraction uses `switch-zziplib` (`ota_unzip.c`) on device.
|
||||
- OTA replaces launcher + game from the unified zip (NACP versions stay aligned).
|
||||
- Sphaira HOME forwarders cache metadata until reinstalled (see docs/switch-install.md).
|
||||
- Install toolchain deps once: `bash scripts/switch/install_devkitpro_deps.sh`
|
||||
- Release runner: `switch-dev` + (`install_devkitpro_deps.sh` **or** Docker)
|
||||
|
||||
+29
-37
@@ -5,10 +5,8 @@
|
||||
# scripts/build_switch.sh --fetch
|
||||
# scripts/build_switch.sh --loose [path/to/game.love]
|
||||
# scripts/build_switch.sh --fused [--version X.Y.Z]
|
||||
# scripts/build_switch.sh --ota [--version X.Y.Z]
|
||||
# scripts/build_switch.sh --fetch --loose
|
||||
# scripts/build_switch.sh --fetch --fused [--version X.Y.Z]
|
||||
# scripts/build_switch.sh --fetch --ota [--version X.Y.Z]
|
||||
#
|
||||
# Modes:
|
||||
# --fetch Download pinned love.nro + love.elf into
|
||||
@@ -21,22 +19,19 @@
|
||||
# (gen1recomp.nro + game.love side by side). Requires the pin
|
||||
# (run --fetch first, or combine --fetch --loose).
|
||||
#
|
||||
# --fused Build a single gen1recomp-<ver>-switch.nro via nacptool+elf2nro,
|
||||
# then pack dist/switch/gen1recomp-<ver>-switch.zip (SD-ready
|
||||
# tree under switch/gen1recomp/). Uses native tools (PATH or
|
||||
# $DEVKITPRO/tools/bin) first; else Docker from
|
||||
# scripts/switch/dkp-docker.image (override GEN1_DKP_IMAGE).
|
||||
# Requires the pin (run --fetch or combine). GitHub Releases
|
||||
# publish the zip only; the versioned .nro stays local / PR CI.
|
||||
# --fused Build fused gen1recomp-<ver>-switch.nro (game in romfs), native
|
||||
# OTA launcher NRO, and dual-NRO SD zip (gen1recomp.nro launcher +
|
||||
# gen1recomp-game.nro under switch/gen1recomp/). The same
|
||||
# gen1recomp-<ver>-switch.zip is the OTA download asset.
|
||||
# Requires DEVKITPRO + switch-dev; OTA launcher via native packages
|
||||
# (install_devkitpro_deps.sh) or Docker.
|
||||
# Uses native tools (PATH or $DEVKITPRO/tools/bin) first; else Docker
|
||||
# from scripts/switch/dkp-docker.image (override GEN1_DKP_IMAGE).
|
||||
# Requires the pin (run --fetch or combine). GitHub Releases publish
|
||||
# the zip only; versioned .nro files stay local / PR CI.
|
||||
#
|
||||
# --ota Like --fused, plus native OTA launcher NRO and dual-NRO SD zip
|
||||
# (gen1recomp.nro launcher + gen1recomp-game.nro). The same
|
||||
# gen1recomp-<ver>-switch.zip is the OTA download asset. Needs
|
||||
# DEVKITPRO switch-curl/mbedtls/zlib/zziplib — see
|
||||
# scripts/switch/install_devkitpro_deps.sh.
|
||||
#
|
||||
# Combinable: --fetch alone, or --fetch with --loose / --fused / --ota.
|
||||
# XOR: --loose, --fused, and --ota cannot be combined with each other.
|
||||
# Combinable: --fetch alone, or --fetch with --loose / --fused.
|
||||
# XOR: --loose and --fused cannot be combined with each other.
|
||||
#
|
||||
# Non-goals (never done by this script):
|
||||
# MTP push, ROM install, dkp-pacman auto-install (use install_devkitpro_deps.sh).
|
||||
@@ -49,7 +44,6 @@ DIST="$ROOT/dist/switch"
|
||||
LOOSE=0
|
||||
FUSED=0
|
||||
FETCH=0
|
||||
OTA=0
|
||||
GAME_LOVE=""
|
||||
VERSION="$(git -C "$ROOT" rev-parse --short HEAD 2>/dev/null || echo dev)"
|
||||
|
||||
@@ -58,14 +52,13 @@ say() { printf '\033[1;32m==>\033[0m %s\n' "$*" >&2; }
|
||||
fail() { printf '\033[1;31merror:\033[0m %s\n' "$*" >&2; exit 1; }
|
||||
|
||||
usage() {
|
||||
sed -n '2,40p' "$0" | sed 's/^# \{0,1\}//'
|
||||
sed -n '2,38p' "$0" | sed 's/^# \{0,1\}//'
|
||||
}
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--loose) LOOSE=1; shift ;;
|
||||
--fused) FUSED=1; shift ;;
|
||||
--ota) OTA=1; shift ;;
|
||||
--fetch) FETCH=1; shift ;;
|
||||
--version) VERSION="$2"; shift 2 ;;
|
||||
-h|--help)
|
||||
@@ -83,13 +76,12 @@ while [ $# -gt 0 ]; do
|
||||
esac
|
||||
done
|
||||
|
||||
MODE_COUNT=$((LOOSE + FUSED + OTA))
|
||||
if [ "$MODE_COUNT" -gt 1 ]; then
|
||||
fail "choose one of --loose, --fused, or --ota (XOR)"
|
||||
if [ "$LOOSE" -eq 1 ] && [ "$FUSED" -eq 1 ]; then
|
||||
fail "choose one of --loose or --fused (XOR)"
|
||||
fi
|
||||
|
||||
if [ "$FETCH" -eq 0 ] && [ "$LOOSE" -eq 0 ] && [ "$FUSED" -eq 0 ] && [ "$OTA" -eq 0 ]; then
|
||||
fail "specify --fetch, --loose, --fused, and/or --ota (see --help)"
|
||||
if [ "$FETCH" -eq 0 ] && [ "$LOOSE" -eq 0 ] && [ "$FUSED" -eq 0 ]; then
|
||||
fail "specify --fetch, --loose, and/or --fused (see --help)"
|
||||
fi
|
||||
|
||||
if [ "$FETCH" -eq 1 ]; then
|
||||
@@ -139,22 +131,22 @@ if [ "$LOOSE" -eq 1 ]; then
|
||||
exec "$ROOT/scripts/switch/assemble_loose.sh" "$GAME_LOVE"
|
||||
fi
|
||||
|
||||
if [ "$FUSED" -eq 1 ] || [ "$OTA" -eq 1 ]; then
|
||||
if [ "$FUSED" -eq 1 ]; then
|
||||
# shellcheck source=scripts/switch/common.sh
|
||||
. "$ROOT/scripts/switch/common.sh"
|
||||
preflight_fused_build
|
||||
|
||||
GAME_LOVE="$(pack_game_love)"
|
||||
OUT_NRO="$DIST/gen1recomp-${VERSION}-switch.nro"
|
||||
OUT_ZIP="$DIST/gen1recomp-${VERSION}-switch.zip"
|
||||
"$ROOT/scripts/switch/build_fused.sh" "$GAME_LOVE" "$VERSION" "$OUT_NRO"
|
||||
|
||||
if [ "$OTA" -eq 1 ]; then
|
||||
LAUNCHER_NRO="$DIST/gen1recomp-${VERSION}-launcher.nro"
|
||||
say "building native OTA launcher"
|
||||
"$ROOT/scripts/switch/build_ota_launcher.sh" "$LAUNCHER_NRO" "$VERSION"
|
||||
say "packing dual-NRO SD zip (also the OTA download asset)"
|
||||
"$ROOT/scripts/switch/pack_sd_zip.sh" "$OUT_NRO" "$VERSION" "$OUT_ZIP" "$LAUNCHER_NRO"
|
||||
cp "$OUT_NRO" "$DIST/gen1recomp-${VERSION}-game.nro"
|
||||
else
|
||||
"$ROOT/scripts/switch/pack_sd_zip.sh" "$OUT_NRO" "$VERSION" "$OUT_ZIP"
|
||||
fi
|
||||
LAUNCHER_NRO="$DIST/gen1recomp-${VERSION}-launcher.nro"
|
||||
say "building native OTA launcher"
|
||||
"$ROOT/scripts/switch/build_ota_launcher.sh" "$LAUNCHER_NRO" "$VERSION"
|
||||
say "packing dual-NRO SD zip (also the OTA download asset)"
|
||||
"$ROOT/scripts/switch/pack_sd_zip.sh" "$OUT_NRO" "$VERSION" "$OUT_ZIP" "$LAUNCHER_NRO"
|
||||
cp "$OUT_NRO" "$DIST/gen1recomp-${VERSION}-game.nro"
|
||||
|
||||
cp "$WORK/build-info.json" "$DIST/gen1recomp-${VERSION}-build-info.json"
|
||||
say "done. See $DIST/"
|
||||
@@ -167,4 +159,4 @@ if [ "$FETCH" -eq 1 ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
fail "specify --fetch, --loose, --fused, and/or --ota (see --help)"
|
||||
fail "specify --fetch, --loose, and/or --fused (see --help)"
|
||||
|
||||
@@ -22,15 +22,21 @@ DKP_IMAGE_FILE="$ROOT/scripts/switch/dkp-docker.image"
|
||||
[ -d "$LAUNCHER_DIR" ] || fail "missing $LAUNCHER_DIR"
|
||||
[ -f "$LAUNCHER_DIR/Makefile" ] || fail "missing Makefile"
|
||||
|
||||
if ! devkitpro_ready; then
|
||||
fail_missing_devkitpro
|
||||
fi
|
||||
|
||||
say "host-test ota_protocol (no DEVKITPRO required)"
|
||||
make -C "$LAUNCHER_DIR" host-test
|
||||
|
||||
mkdir -p "$(dirname "$OUT_NRO")"
|
||||
|
||||
if [ -n "${DEVKITPRO:-}" ] && [ -f "$DEVKITPRO/libnx/switch_rules" ]; then
|
||||
if ota_launcher_deps_ready; then
|
||||
say "building launcher NRO with native DEVKITPRO (NACP $APP_VERSION)"
|
||||
make -C "$LAUNCHER_DIR" clean || true
|
||||
make -C "$LAUNCHER_DIR" all APP_VERSION="$APP_VERSION"
|
||||
if ! make -C "$LAUNCHER_DIR" all APP_VERSION="$APP_VERSION"; then
|
||||
fail_ota_launcher_toolchain
|
||||
fi
|
||||
cp "$LAUNCHER_DIR/gen1recomp.nro" "$OUT_NRO"
|
||||
say "wrote $OUT_NRO"
|
||||
exit 0
|
||||
@@ -51,24 +57,17 @@ resolve_dkp_image() {
|
||||
if command -v docker >/dev/null 2>&1; then
|
||||
image="$(resolve_dkp_image)"
|
||||
say "building launcher NRO via Docker ($image, NACP $APP_VERSION)"
|
||||
docker run --rm \
|
||||
if ! docker run --rm \
|
||||
-v "$ROOT:/work" \
|
||||
-w /work/native/switch-ota-launcher \
|
||||
-e "APP_VERSION=$APP_VERSION" \
|
||||
"$image" \
|
||||
bash -lc 'pacman -Sy --noconfirm switch-curl switch-mbedtls switch-zlib switch-zziplib >/dev/null 2>&1 || true; make clean; make all APP_VERSION="$APP_VERSION"'
|
||||
bash -lc 'pacman -Sy --noconfirm switch-curl switch-mbedtls switch-zlib switch-zziplib >/dev/null 2>&1 || true; make clean; make all APP_VERSION="$APP_VERSION"'; then
|
||||
fail_ota_launcher_toolchain
|
||||
fi
|
||||
cp "$LAUNCHER_DIR/gen1recomp.nro" "$OUT_NRO"
|
||||
say "wrote $OUT_NRO"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
fail "$(cat <<EOF
|
||||
Cannot build Switch OTA launcher NRO: DEVKITPRO unset and Docker unavailable.
|
||||
|
||||
Host protocol tests already passed (make host-test).
|
||||
Install DEVKITPRO switch-dev + switch-curl, or Docker, then re-run:
|
||||
scripts/switch/build_ota_launcher.sh
|
||||
|
||||
See native/switch-ota-launcher/README.md and docs/switch-build.md.
|
||||
EOF
|
||||
)"
|
||||
fail_missing_ota_deps
|
||||
|
||||
+124
-3
@@ -38,16 +38,137 @@ fail_need_fetch() {
|
||||
fail "${1:-missing pinned love-nx} — run: scripts/build_switch.sh --fetch"
|
||||
}
|
||||
|
||||
# OTA launcher native build packages (shared with install_devkitpro_deps.sh).
|
||||
OTA_LAUNCHER_PKGS=(switch-curl switch-mbedtls switch-zlib switch-zziplib)
|
||||
|
||||
ota_launcher_deps_ready() {
|
||||
command -v dkp-pacman >/dev/null 2>&1 || return 1
|
||||
local pkg
|
||||
for pkg in "${OTA_LAUNCHER_PKGS[@]}"; do
|
||||
dkp-pacman -Q "$pkg" >/dev/null 2>&1 || return 1
|
||||
done
|
||||
}
|
||||
|
||||
# Space-separated list of missing OTA launcher packages (empty when all installed).
|
||||
ota_launcher_missing_pkgs() {
|
||||
command -v dkp-pacman >/dev/null 2>&1 || return 0
|
||||
local pkg missing=""
|
||||
for pkg in "${OTA_LAUNCHER_PKGS[@]}"; do
|
||||
if ! dkp-pacman -Q "$pkg" >/dev/null 2>&1; then
|
||||
missing="${missing} ${pkg}"
|
||||
fi
|
||||
done
|
||||
printf '%s' "$missing"
|
||||
}
|
||||
|
||||
devkitpro_ready() {
|
||||
[ -n "${DEVKITPRO:-}" ] && [ -f "$DEVKITPRO/libnx/switch_rules" ]
|
||||
}
|
||||
|
||||
fail_missing_devkitpro() {
|
||||
fail "$(cat <<'EOF'
|
||||
--fused requires DEVKITPRO (release builds ship the OTA launcher for in-console updates).
|
||||
|
||||
One-time setup on the Mac self-hosted runner (or your dev machine):
|
||||
|
||||
1. Install devkitPro pacman: https://devkitpro.org/wiki/devkitPro_pacman
|
||||
2. Install Switch tools: sudo dkp-pacman -S switch-dev
|
||||
3. Export DEVKITPRO (typical macOS):
|
||||
export DEVKITPRO=/opt/devkitpro
|
||||
export PATH="$DEVKITPRO/tools/bin:$PATH"
|
||||
4. OTA launcher toolchain (native or Docker — pick one):
|
||||
bash scripts/switch/install_devkitpro_deps.sh
|
||||
or install Docker (same pin as fused builds)
|
||||
|
||||
Then re-run: scripts/build_switch.sh --fetch --fused
|
||||
|
||||
See docs/switch-build.md (Runner provisioning).
|
||||
EOF
|
||||
)"
|
||||
}
|
||||
|
||||
fail_missing_ota_deps() {
|
||||
local missing
|
||||
missing="$(ota_launcher_missing_pkgs)"
|
||||
fail "$(cat <<EOF
|
||||
--fused needs a way to build the OTA launcher: native dkp packages or Docker.
|
||||
|
||||
Missing dkp packages:${missing:- (dkp-pacman not on PATH)}
|
||||
|
||||
Pick one:
|
||||
bash scripts/switch/install_devkitpro_deps.sh
|
||||
or install Docker (build_ota_launcher.sh uses the pinned devkitPro image)
|
||||
|
||||
Then re-run: scripts/build_switch.sh --fetch --fused
|
||||
|
||||
See docs/switch-build.md and native/switch-ota-launcher/README.md.
|
||||
EOF
|
||||
)"
|
||||
}
|
||||
|
||||
fail_ota_launcher_toolchain() {
|
||||
if ! devkitpro_ready; then
|
||||
fail_missing_devkitpro
|
||||
fi
|
||||
if ota_launcher_deps_ready; then
|
||||
fail "$(cat <<'EOF'
|
||||
OTA launcher native build failed after host-test passed.
|
||||
|
||||
Re-run with a clean tree:
|
||||
scripts/switch/build_ota_launcher.sh
|
||||
|
||||
If packages look wrong, reinstall:
|
||||
bash scripts/switch/install_devkitpro_deps.sh
|
||||
|
||||
See native/switch-ota-launcher/README.md.
|
||||
EOF
|
||||
)"
|
||||
fi
|
||||
fail_missing_ota_deps
|
||||
}
|
||||
|
||||
# Fail fast before packing when --fused is requested.
|
||||
preflight_fused_build() {
|
||||
if ! devkitpro_ready; then
|
||||
fail_missing_devkitpro
|
||||
fi
|
||||
ensure_dkp_tools_path
|
||||
|
||||
local game_ok=0
|
||||
if command -v nacptool >/dev/null 2>&1 && command -v elf2nro >/dev/null 2>&1; then
|
||||
game_ok=1
|
||||
elif command -v docker >/dev/null 2>&1; then
|
||||
game_ok=1
|
||||
fi
|
||||
if [ "$game_ok" -eq 0 ]; then
|
||||
fail_fused_toolchain
|
||||
fi
|
||||
|
||||
if ota_launcher_deps_ready; then
|
||||
return 0
|
||||
fi
|
||||
if command -v docker >/dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
fail_missing_ota_deps
|
||||
}
|
||||
|
||||
# Fused mode needs nacptool/elf2nro (native or Docker). Rich multi-OS hint.
|
||||
fail_fused_toolchain() {
|
||||
fail "$(cat <<'EOF'
|
||||
fused packaging needs nacptool and elf2nro (devkitPro switch-dev).
|
||||
fused packaging needs DEVKITPRO, nacptool, and elf2nro (devkitPro switch-dev).
|
||||
|
||||
Install options:
|
||||
macOS: https://devkitpro.org/wiki/devkitPro_pacman (installer / pacman)
|
||||
macOS: https://devkitpro.org/wiki/devkitPro_pacman
|
||||
sudo dkp-pacman -S switch-dev
|
||||
OTA launcher (native or Docker):
|
||||
bash scripts/switch/install_devkitpro_deps.sh
|
||||
or install Docker
|
||||
Linux: https://devkitpro.org/wiki/devkitPro_pacman
|
||||
Windows: Git Bash / MSYS2 / WSL with devkitPro tools on PATH
|
||||
Docker: install Docker; build_fused.sh falls back to the pinned image
|
||||
Docker: install Docker; fused game and OTA launcher can build in-container
|
||||
|
||||
Export DEVKITPRO (typical): export DEVKITPRO=/opt/devkitpro
|
||||
|
||||
See docs/switch-build.md for details.
|
||||
EOF
|
||||
|
||||
@@ -4,8 +4,15 @@
|
||||
#
|
||||
# bash scripts/switch/install_devkitpro_deps.sh
|
||||
#
|
||||
# Optional: speeds up local native OTA launcher builds. CI/release can fall back
|
||||
# to Docker when these packages are not installed.
|
||||
#
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
# shellcheck source=common.sh
|
||||
. "$SCRIPT_DIR/common.sh"
|
||||
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "==> re-running with sudo…"
|
||||
exec sudo -E bash "$0" "$@"
|
||||
@@ -25,14 +32,17 @@ if ! command -v dkp-pacman >/dev/null 2>&1; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! dkp-pacman -Q switch-dev >/dev/null 2>&1; then
|
||||
echo "error: switch-dev is not installed (needed for nacptool/elf2nro)." >&2
|
||||
echo " sudo dkp-pacman -S switch-dev" >&2
|
||||
echo "Then re-run: bash scripts/switch/install_devkitpro_deps.sh" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "==> DEVKITPRO=$DEVKITPRO"
|
||||
# Named packages only (avoid interactive switch-dev group member prompt).
|
||||
# ZIP reading uses switch-zziplib (dkp has no minizip port for Switch).
|
||||
dkp-pacman -Sy --noconfirm --needed \
|
||||
switch-curl \
|
||||
switch-mbedtls \
|
||||
switch-zlib \
|
||||
switch-zziplib
|
||||
dkp-pacman -Sy --noconfirm --needed "${OTA_LAUNCHER_PKGS[@]}"
|
||||
|
||||
echo "==> installed packages:"
|
||||
dkp-pacman -Q | grep -E 'switch-(curl|mbedtls|zlib|zziplib|tools)|libnx|devkitA64' || true
|
||||
|
||||
@@ -51,17 +51,17 @@ MISSING=""
|
||||
printf '%s' "$HELP_LC" | grep -q 'fetch' || MISSING="${MISSING} fetch"
|
||||
printf '%s' "$HELP_LC" | grep -q 'loose' || MISSING="${MISSING} loose"
|
||||
printf '%s' "$HELP_LC" | grep -q 'fused' || MISSING="${MISSING} fused"
|
||||
printf '%s' "$HELP_LC" | grep -q 'ota' || MISSING="${MISSING} ota"
|
||||
printf '%s' "$HELP_LC" | grep -Eq 'devkitpro' || MISSING="${MISSING} DEVKITPRO"
|
||||
printf '%s' "$HELP_LC" | grep -Eq 'auto-download|downloads' || MISSING="${MISSING} auto-download"
|
||||
printf '%s' "$HELP_LC" | grep -Eq 'non-goal|does not|never' || MISSING="${MISSING} non-goals"
|
||||
if [ -z "$MISSING" ]; then
|
||||
ok "build_switch.sh --help mentions fetch, loose, fused, ota (+ auto-download/non-goals)"
|
||||
ok "build_switch.sh --help mentions fetch, loose, fused, DEVKITPRO (+ auto-download/non-goals)"
|
||||
else
|
||||
bad "build_switch.sh --help missing:$MISSING"
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 3. XOR --loose --fused / --ota exits non-zero
|
||||
# 3. XOR --loose --fused exits non-zero
|
||||
# ---------------------------------------------------------------------------
|
||||
XOR_RC=0
|
||||
"$ROOT/scripts/build_switch.sh" --loose --fused >/dev/null 2>&1 || XOR_RC=$?
|
||||
@@ -70,13 +70,6 @@ if [ "$XOR_RC" -ne 0 ]; then
|
||||
else
|
||||
bad "build_switch.sh --loose --fused should exit non-zero"
|
||||
fi
|
||||
XOR_OTA_RC=0
|
||||
"$ROOT/scripts/build_switch.sh" --fused --ota >/dev/null 2>&1 || XOR_OTA_RC=$?
|
||||
if [ "$XOR_OTA_RC" -ne 0 ]; then
|
||||
ok "build_switch.sh --fused --ota exits non-zero ($XOR_OTA_RC)"
|
||||
else
|
||||
bad "build_switch.sh --fused --ota should exit non-zero"
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 4. assemble_loose without pin → stderr contains --fetch
|
||||
@@ -188,7 +181,41 @@ else
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 5c. fail_fused_toolchain mentions docs/switch-build.md
|
||||
# 5c2. fail_missing_devkitpro cites install_devkitpro_deps.sh
|
||||
# ---------------------------------------------------------------------------
|
||||
MDK_ERR="$STAGING/missing-dkp.err"
|
||||
MDK_RC=0
|
||||
(
|
||||
. "$SCRIPT_DIR/common.sh"
|
||||
fail_missing_devkitpro
|
||||
) >"$STAGING/missing-dkp.out" 2>"$MDK_ERR" || MDK_RC=$?
|
||||
|
||||
if [ "$MDK_RC" -ne 0 ] \
|
||||
&& grep -q 'install_devkitpro_deps.sh' "$MDK_ERR" \
|
||||
&& grep -q 'DEVKITPRO' "$MDK_ERR" \
|
||||
&& grep -q 'switch-dev' "$MDK_ERR"; then
|
||||
ok "fail_missing_devkitpro cites DEVKITPRO + switch-dev + install_devkitpro_deps.sh"
|
||||
else
|
||||
bad "fail_missing_devkitpro should cite setup steps (rc=$MDK_RC err=$(cat "$MDK_ERR"))"
|
||||
fi
|
||||
|
||||
OTA_ERR="$STAGING/missing-ota.err"
|
||||
OTA_RC=0
|
||||
(
|
||||
. "$SCRIPT_DIR/common.sh"
|
||||
fail_missing_ota_deps
|
||||
) >"$STAGING/missing-ota.out" 2>"$OTA_ERR" || OTA_RC=$?
|
||||
|
||||
if [ "$OTA_RC" -ne 0 ] \
|
||||
&& grep -q 'install_devkitpro_deps.sh' "$OTA_ERR" \
|
||||
&& grep -qi 'docker' "$OTA_ERR"; then
|
||||
ok "fail_missing_ota_deps cites native or Docker options"
|
||||
else
|
||||
bad "fail_missing_ota_deps should cite native + Docker (rc=$OTA_RC err=$(cat "$OTA_ERR"))"
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 5d. fail_fused_toolchain mentions docs/switch-build.md
|
||||
# ---------------------------------------------------------------------------
|
||||
FT_ERR="$STAGING/fused-toolchain.err"
|
||||
FT_RC=0
|
||||
@@ -365,6 +392,9 @@ else
|
||||
fi
|
||||
|
||||
if [ -f "$ROOT/scripts/switch/build_ota_launcher.sh" ] \
|
||||
&& grep -q 'ota_launcher_deps_ready' "$ROOT/scripts/switch/build_ota_launcher.sh" \
|
||||
&& grep -q 'fail_missing_devkitpro' "$ROOT/scripts/switch/build_ota_launcher.sh" \
|
||||
&& grep -q 'preflight_fused_build' "$ROOT/scripts/build_switch.sh" \
|
||||
&& [ -f "$ROOT/native/switch-ota-launcher/Makefile" ]
|
||||
then
|
||||
ok "native OTA launcher sources + build_ota_launcher.sh present"
|
||||
|
||||
@@ -529,12 +529,15 @@ test('AC-010: Fonte do launcher e Makefile DEVKITPRO existem @spec:AC-010', () =
|
||||
assert.match(read('native/switch-ota-launcher/src/ota_fs.c'), /ota_fs_atomic_replace_nro/);
|
||||
assert.doesNotMatch(read('scripts/switch/install_devkitpro_deps.sh'), /switch-minizip/);
|
||||
assert.match(read('scripts/switch/install_devkitpro_deps.sh'), /switch-zziplib/);
|
||||
assert.match(read('scripts/switch/install_devkitpro_deps.sh'), /switch-dev/);
|
||||
|
||||
const buildDoc = read('docs/switch-build.md');
|
||||
assert.match(buildDoc, /native\/switch-ota-launcher|build_ota_launcher/);
|
||||
assert.match(buildDoc, /switch-curl/);
|
||||
assert.match(buildDoc, /--ota|install_devkitpro_deps/);
|
||||
assert.match(buildDoc, /native packages.*or.*Docker|native or Docker/i);
|
||||
assert.match(buildDoc, /--fused|install_devkitpro_deps/);
|
||||
assert.match(buildDoc, /Requires DEVKITPRO|DEVKITPRO is[\s\S]*required/i);
|
||||
assert.doesNotMatch(buildDoc, /switch-ota\.zip/);
|
||||
assert.doesNotMatch(buildDoc, /--ota\b/);
|
||||
|
||||
const readme = read('native/switch-ota-launcher/README.md');
|
||||
assert.match(readme, /DEVKITPRO|devkitPro/i);
|
||||
@@ -555,11 +558,16 @@ test('AC-011: Empacotamento dual-NRO e selftest @spec:AC-011', () => {
|
||||
);
|
||||
|
||||
const buildSwitch = read('scripts/build_switch.sh');
|
||||
assert.match(buildSwitch, /--ota/);
|
||||
assert.doesNotMatch(buildSwitch, /--ota\b/);
|
||||
assert.doesNotMatch(buildSwitch, /pack_ota_zip\.sh/);
|
||||
assert.match(buildSwitch, /build_ota_launcher\.sh/);
|
||||
assert.match(buildSwitch, /dual-NRO SD zip|OTA download asset/i);
|
||||
|
||||
const buildOtaLauncher = read('scripts/switch/build_ota_launcher.sh');
|
||||
assert.match(buildOtaLauncher, /ota_launcher_deps_ready/);
|
||||
assert.match(buildOtaLauncher, /fail_missing_devkitpro/);
|
||||
assert.match(buildSwitch, /preflight_fused_build/);
|
||||
|
||||
const selftest = read('scripts/switch/selftest_build_switch.sh');
|
||||
assert.match(selftest, /dual-NRO|gen1recomp-game\.nro/);
|
||||
assert.match(selftest, /ota_launcher\.manifest/);
|
||||
|
||||
Reference in New Issue
Block a user