diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e3df3ec4..16385ffd 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -509,16 +509,24 @@ jobs: mkdir -p "$outdir" cp "dist/mac/gen1recomp-macos.zip" "$outdir/gen1recomp-${v}-macos.zip" cp "dist/win/gen1recomp-win64.zip" "$outdir/gen1recomp-${v}-windows.zip" - cp "dist/linux/gen1recomp-linux.zip" "$outdir/gen1recomp-${v}-linux.zip" + # x86_64 desktop Linux: raw AppImage (no zip wrapper). + x64_appimage="dist/linux/gen1recomp-linux-x86_64.AppImage" + [ -f "$x64_appimage" ] || { echo "::error::$x64_appimage not found (expected from scripts/build.sh linux)"; exit 1; } + cp "$x64_appimage" "$outdir/gen1recomp-${v}-linux-x86_64.AppImage" + chmod +x "$outdir/gen1recomp-${v}-linux-x86_64.AppImage" # arm64 desktop Linux (Raspberry Pi, Armbian, arm64 VMs). Built on # its own runner because LÖVE publishes no aarch64 binary and the # AppImage has to be compiled natively; ships as a runnable - # AppImage rather than a zip so `chmod +x && ./it` just works. + # AppImage so `chmod +x && ./it` just works. arm64_appimage="dist/linux-arm64/gen1recomp-${v}-linux-arm64.AppImage" [ -f "$arm64_appimage" ] || { echo "::error::$arm64_appimage not found (expected from the linux-arm64 job)"; exit 1; } cp "$arm64_appimage" "$outdir/gen1recomp-${v}-linux-arm64.AppImage" chmod +x "$outdir/gen1recomp-${v}-linux-arm64.AppImage" + + flatpak_bundle="dist/flatpak/gen1recomp-${v}-linux.flatpak" + [ -f "$flatpak_bundle" ] || { echo "::error::$flatpak_bundle not found (expected from scripts/build_flatpak.sh)"; exit 1; } + cp "$flatpak_bundle" "$outdir/gen1recomp-${v}-linux.flatpak" apk="$(find dist/android/release -name '*.apk' | head -1)" [ -n "$apk" ] || { echo "::error::no Android APK found under dist/android/release"; exit 1; } cp "$apk" "$outdir/gen1recomp-${v}-android.apk" @@ -656,8 +664,9 @@ jobs: release_files=( "dist/release/gen1recomp-${v}-macos.zip" "dist/release/gen1recomp-${v}-windows.zip" - "dist/release/gen1recomp-${v}-linux.zip" + "dist/release/gen1recomp-${v}-linux-x86_64.AppImage" "dist/release/gen1recomp-${v}-linux-arm64.AppImage" + "dist/release/gen1recomp-${v}-linux.flatpak" "dist/release/gen1recomp-${v}-android.apk" "dist/release/gen1recomp++-${v}-ios.ipa" "dist/release/gen1recomp-${v}-switch.zip" diff --git a/README.md b/README.md index 141f35d4..e7d5a1ea 100644 --- a/README.md +++ b/README.md @@ -228,18 +228,27 @@ entry: a desktop shortcut per game, a Steam entry, or a handheld frontend. | `--launcher` | open the launcher anyway, so you can edit a shortcut you already made | -## Linux on arm64 (Raspberry Pi) +## Linux desktop (AppImage / Flatpak) -Alongside the x86_64 `gen1recomp-*-linux.zip`, every release ships -`gen1recomp-*-linux-arm64.AppImage` for 64-bit ARM desktop Linux — Raspberry -Pi 4/5, Armbian and other SBC distros, and arm64 VMs on Apple Silicon: +Releases ship raw AppImages (no zip wrapper) plus an optional Flatpak bundle: + +- `gen1recomp-*-linux-x86_64.AppImage` +- `gen1recomp-*-linux-arm64.AppImage` (Raspberry Pi 4/5, Armbian, arm64 VMs) +- `gen1recomp-*-linux.flatpak` (see [docs/linux-flatpak.md](docs/linux-flatpak.md)) + +```sh +chmod +x gen1recomp-*-linux-x86_64.AppImage +./gen1recomp-*-linux-x86_64.AppImage +``` ```sh chmod +x gen1recomp-*-linux-arm64.AppImage ./gen1recomp-*-linux-arm64.AppImage ``` -LÖVE publishes no aarch64 binary of any kind, so this artifact compiles the +Shared troubleshooting (FUSE, curl, portable mode): [docs/linux-appimage.md](docs/linux-appimage.md). + +LÖVE publishes no aarch64 binary of any kind, so the arm64 artifact compiles the engine — and SDL2, OpenAL and the codecs — from source inside a Debian bullseye arm64 container. It needs only glibc 2.29+, libstdc++, freetype and zlib on the host; OpenGL, X11, Wayland, KMSDRM, ALSA and PulseAudio are all diff --git a/docs/linux-appimage.md b/docs/linux-appimage.md new file mode 100644 index 00000000..2a6797dc --- /dev/null +++ b/docs/linux-appimage.md @@ -0,0 +1,58 @@ +# Linux AppImage packaging + +Releases ship raw AppImages (no zip wrapper): + +- `gen1recomp--linux-x86_64.AppImage` +- `gen1recomp--linux-arm64.AppImage` + +```sh +chmod +x gen1recomp-*-linux-x86_64.AppImage +./gen1recomp-*-linux-x86_64.AppImage +``` + +Flatpak users should prefer the `.flatpak` bundle (see +[linux-flatpak.md](linux-flatpak.md)); it avoids host glibc / FUSE / curl +mismatches on immutable desktops. + +## Common failure modes + +| Symptom | Cause | Fix | +|---|---|---| +| Won't start / `libfuse.so.2` | No FUSE | `sudo apt install libfuse2` (or `libfuse2t64`) **or** `./app.AppImage --appimage-extract-and-run` | +| Update check / mods / save sync fail | Host `curl` missing or broken by AppImage `LD_LIBRARY_PATH` | Install curl; current builds scrub `LD_LIBRARY_PATH` for **host** curl and keep it for a bundled AppDir curl | +| Settings / sync reset after quit | Portable mode next to a read-only AppImage parent (`/opt`, system dir) | Remove `portable.txt` or move the AppImage to a writable folder; the game falls back to the XDG save dir when the probe write fails | +| "Download AppImage update" | Shell/`minShell` gate needs a full native package | Download the new `.AppImage`, `chmod +x`, replace the old file | +| Steam / Game Mode weirdness after update | Overlay `LD_PRELOAD` / PID change | HostShell unsets `LD_PRELOAD` for children and `execv`s `$APPIMAGE` on restart | + +## Network transport (HostShell) + +Desktop Linux fetches go through host or bundled `curl`: + +1. Flatpak `/app/bin/curl` (bundled, keep sandbox libs) +2. `$APPDIR/usr/bin/curl` or `$APPDIR/bin/curl` (keep `$APPDIR` on `LD_LIBRARY_PATH`) +3. Host `curl` (`env -u LD_LIBRARY_PATH`, and always `-u LD_PRELOAD`) + +## Portable mode + +Drop `portable.txt` beside the `.AppImage` to keep saves next to the binary. +The launcher probes writability with a unique `.write_probe_