From 4199f42f7094a86f0b24c3a5c073e16127ae82c2 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 1 Sep 2026 15:03:57 +0000 Subject: [PATCH] wolf: fix wrong-architecture AppImage downloads (aarch64 picked on x86_64 hosts) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit _wolf_download_emulator_appimage picked whatever release asset happened to be first in the GitHub API's asset list among files ending in .AppImage, with no architecture filtering. Confirmed live: pkgforge-dev's Dolphin AppImage release lists an aarch64 build ahead of the x86_64 one, so the downloaded file silently failed at launch with a bare "exec format error" and no indication why — the earlier "emulator not found" symlink fix (previous commit) got ES-DE to find the file at all, which is what surfaced this as the next failure. Now prefers whichever release asset's filename actually tags the host's own architecture, falls back to an untagged asset (Azahar/PCSX2's releases carry no arch tag and are unaffected either way), and only then falls back to "take the first one". Also verifies the downloaded file's real ELF architecture against the host post-download and warns loudly if it still doesn't match, since filename tagging isn't something every release can be trusted to get right. --- services/wolf.sh | 49 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/services/wolf.sh b/services/wolf.sh index 33018bd..c47f559 100644 --- a/services/wolf.sh +++ b/services/wolf.sh @@ -227,11 +227,33 @@ _wolf_download_emulator_appimage() { [[ "$_get" =~ ^[Yy]$ ]] || return 0 log_info "Fetching latest $_display_name release from GitHub..." + # A release can publish AppImages for more than one CPU architecture + # (x86_64 and aarch64 both showing up as plain "*.AppImage" assets) with + # no guarantee the one this host needs sorts first in the GitHub API's + # asset list. Prefer whichever asset's filename actually tags the host's + # own architecture; fall back to an asset with no arch tag at all before + # ever falling back to "just take the first one". local _url _url=$(curl -fsSL "https://api.github.com/repos/${_owner_repo}/releases/latest" \ - | python3 -c "import sys,json; r=json.load(sys.stdin); \ - print(next((a['browser_download_url'] for a in r['assets'] \ - if a['name'].endswith('.AppImage')), ''))" 2>/dev/null) + | HOST_ARCH="$(uname -m)" python3 -c ' +import sys, json, os +host = os.environ.get("HOST_ARCH", "") +arch_tags = { + "x86_64": ["x86_64", "amd64", "x64"], + "aarch64": ["aarch64", "arm64"], + "arm64": ["aarch64", "arm64"], +}.get(host, [host] if host else []) +all_arch_tags = ["x86_64", "amd64", "x64", "aarch64", "arm64", "armv7", "armhf", "i386", "i686"] +def has(name, tags): + n = name.lower() + return any(t in n for t in tags) +r = json.load(sys.stdin) +assets = [a for a in r["assets"] if a["name"].endswith(".AppImage")] +matching = [a for a in assets if arch_tags and has(a["name"], arch_tags)] +untagged = [a for a in assets if not has(a["name"], all_arch_tags)] +pick = matching or untagged or assets +print(pick[0]["browser_download_url"] if pick else "") +' 2>/dev/null) if [[ -z "$_url" ]]; then log_warning "Could not resolve download URL — get it manually from https://github.com/${_owner_repo}/releases" return 1 @@ -241,7 +263,26 @@ _wolf_download_emulator_appimage() { && chmod +x "$_file" \ && chown "$ACTUAL_USER:$ACTUAL_USER" "$_file" \ && log_success "$_display_name downloaded: $_file" \ - || log_warning "Download failed — get it manually from https://github.com/${_owner_repo}/releases" + || { log_warning "Download failed — get it manually from https://github.com/${_owner_repo}/releases"; return 1; } + + # Belt-and-suspenders: the filename-based preference above can't help + # when a release tags no architecture in the name at all, so verify the + # actual ELF header matches this host post-download. Confirmed live: a + # wrong-arch AppImage downloads with no error and no visible symptom + # until launch time, where it fails as a bare "exec format error" with + # nothing pointing back at the cause. + local _got_arch + _got_arch=$(file -b "$_file" 2>/dev/null) + case "$(uname -m)" in + x86_64) + echo "$_got_arch" | grep -qi 'x86-64\|x86_64' || \ + log_warning "$_file doesn't look like an x86_64 build ($_got_arch) — it will fail with 'exec format error'. Grab the x86_64 asset by hand from https://github.com/${_owner_repo}/releases" + ;; + aarch64|arm64) + echo "$_got_arch" | grep -qi 'aarch64\|arm64' || \ + log_warning "$_file doesn't look like an aarch64 build ($_got_arch) — it may fail to run. Grab the aarch64 asset by hand from https://github.com/${_owner_repo}/releases" + ;; + esac } install_wolf() {