Choose the asset that matches the machine
Batocera runs on x86_64 mini-PCs, on the Raspberry Pi and on the ARM handhelds alike. A cartridge is data for an emulator and runs anywhere, which is why this store has been portable so far — but a native build only starts on the architecture it was built for, and an x86_64 binary installed on a Pi is worse than one never offered. `kind` and `ext` may now be a map from architecture to value, with `*` as a fallback; a plain string still means "the same everywhere", so existing configs are untouched. The detected architecture is reported at the top of `list` and as `detected_arch` in `config`, and a title with no asset for the running machine is skipped with a reason that names it. Verified on aarch64 against the live catalog: the cartridge config behaves exactly as before, a bevy entry mapped per architecture pulls bevydemo-1.0.0-linux-arm64.zip, and the binary inside is an AArch64 ELF. A map without an entry for the machine skips and says so. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -16,6 +16,7 @@ Standard library only — Batocera ships python3 but no pip packages.
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import platform
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
@@ -281,6 +282,37 @@ def fetch_catalog(cfg, use_cache=False):
|
||||
die(f"cannot fetch catalog from {url}: {exc}")
|
||||
|
||||
|
||||
def machine():
|
||||
"""A gep architekturaja, `uname -m` szerint, normalizalt neven.
|
||||
|
||||
A gazdaplatform ugyanaz (Batocera), a gep viszont nem: x86_64 mini-PC,
|
||||
Raspberry Pi es kezikonzol egyaránt. Egy x86_64 binaris ARM-on feltelepul,
|
||||
de nem indul el, ezért a kiadasvalasztasnak tudnia kell, min fut.
|
||||
"""
|
||||
m = (platform.machine() or "").lower()
|
||||
if m in ("x86_64", "amd64"):
|
||||
return "x86_64"
|
||||
if m in ("aarch64", "arm64"):
|
||||
return "aarch64"
|
||||
if m.startswith("armv") or m == "arm":
|
||||
return "armhf"
|
||||
if m in ("i386", "i486", "i586", "i686"):
|
||||
return "x86"
|
||||
return m or "unknown"
|
||||
|
||||
|
||||
def resolve_for_arch(value, arch):
|
||||
"""Egy config-erteket architekturara oldunk fel.
|
||||
|
||||
A `kind` es az `ext` lehet egyszeru string (minden gepen ugyanaz — igy
|
||||
mukodik a cartridge), vagy architektura -> ertek leképezes. Az utóbbinal
|
||||
a `"*"` kulcs szolgal tartaleknak.
|
||||
"""
|
||||
if not isinstance(value, dict):
|
||||
return value
|
||||
return value.get(arch, value.get("*"))
|
||||
|
||||
|
||||
def asset_basename(path):
|
||||
"""`/file/blessingofra-2.0.0.prg` -> `blessingofra-2.0.0.prg`."""
|
||||
return os.path.basename(path.rstrip("/"))
|
||||
@@ -317,8 +349,9 @@ def pick_release(entry, kind, ext):
|
||||
return None, None
|
||||
|
||||
|
||||
def select_games(cfg, catalog, available_systems):
|
||||
def select_games(cfg, catalog, available_systems, arch=None):
|
||||
"""Catalog -> list of installable game dicts, plus a list of skip reasons."""
|
||||
arch = arch or machine()
|
||||
statuses = {s.lower() for s in cfg["catalog"].get("statuses") or []}
|
||||
only = {n.lower() for n in cfg["catalog"].get("only") or []}
|
||||
exclude = {n.lower() for n in cfg["catalog"].get("exclude") or []}
|
||||
@@ -344,9 +377,15 @@ def select_games(cfg, catalog, available_systems):
|
||||
if name.lower() in exclude:
|
||||
continue
|
||||
|
||||
release, file_name = pick_release(entry, spec["kind"], spec.get("ext", ""))
|
||||
kind = resolve_for_arch(spec["kind"], arch)
|
||||
if not kind:
|
||||
skipped.append(f"{name}: {sw.get('platform')} has no asset kind for {arch}")
|
||||
continue
|
||||
ext = resolve_for_arch(spec.get("ext", ""), arch) or ""
|
||||
|
||||
release, file_name = pick_release(entry, kind, ext)
|
||||
if not release:
|
||||
skipped.append(f"{name}: no '{spec['kind']}' asset in any release")
|
||||
skipped.append(f"{name}: no '{kind}' asset in any release")
|
||||
continue
|
||||
|
||||
games.append(
|
||||
@@ -793,7 +832,9 @@ def cmd_apply_gamelists(cfg, args):
|
||||
def cmd_list(cfg, args):
|
||||
systems = detect_systems(cfg)
|
||||
catalog = fetch_catalog(cfg, use_cache=True)
|
||||
games, skipped = select_games(cfg, catalog, systems)
|
||||
arch = machine()
|
||||
log(f"architecture: {arch}")
|
||||
games, skipped = select_games(cfg, catalog, systems, arch)
|
||||
installed = load_state()["installed"]
|
||||
|
||||
if not games:
|
||||
@@ -844,7 +885,9 @@ def cmd_config(cfg, args):
|
||||
write_json(args.config, DEFAULT_CONFIG)
|
||||
log(f"wrote default config to {args.config}")
|
||||
return 0
|
||||
print(json.dumps(cfg, indent=2, ensure_ascii=False))
|
||||
# A felismert architektura nem a configbol jon, de az asset-valasztast
|
||||
# eldonti, ezert itt is lathatonak kell lennie.
|
||||
print(json.dumps({"detected_arch": machine(), **cfg}, indent=2, ensure_ascii=False))
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user