e0bc4785e9
Flashes the diskOS custom UI onto the FiiO Snowsky Disc over Ingenic mask-ROM USB, building the image from your own stock firmware. Runs from source via install.sh.
71 lines
2.9 KiB
RPMSpec
71 lines
2.9 KiB
RPMSpec
# PyInstaller spec - one self-contained diskos-installer executable.
|
|
# Bundles the native flashing tools (vendor/<os>-<arch>/) and the payload
|
|
# (mq_ui + on-device init scripts) as data, plus pyusb. The result needs no
|
|
# system Python and no system packages: "remove the tool" = delete this file.
|
|
import os
|
|
|
|
ROOT = os.path.abspath(os.path.join(os.getcwd())) # run from installer/
|
|
# host tag for the vendor dir to bundle (build on each target OS)
|
|
import platform
|
|
_sys = platform.system().lower()
|
|
_os = {"darwin": "macos", "linux": "linux"}.get(_sys, _sys)
|
|
_arch = {"x86_64": "x86_64", "amd64": "x86_64", "arm64": "arm64",
|
|
"aarch64": "arm64"}.get(platform.machine().lower(), platform.machine().lower())
|
|
TAG = f"{_os}-{_arch}"
|
|
|
|
# files under vendor/ that must NOT be bundled into the app (dev-only backups, notes)
|
|
def _skip_vendor(fn):
|
|
return fn.endswith(".bak") or fn.endswith(".dynamic.bak") or fn in ("README.md",)
|
|
|
|
datas = []
|
|
vend = os.path.join(ROOT, "vendor", TAG)
|
|
if os.path.isdir(vend):
|
|
for fn in os.listdir(vend):
|
|
if _skip_vendor(fn) or os.path.isdir(os.path.join(vend, fn)):
|
|
continue
|
|
datas.append((os.path.join(vend, fn), f"vendor/{TAG}"))
|
|
libdir = os.path.join(vend, "lib")
|
|
if os.path.isdir(libdir):
|
|
for fn in os.listdir(libdir):
|
|
datas.append((os.path.join(libdir, fn), f"vendor/{TAG}/lib"))
|
|
payload = os.path.join(ROOT, "payload")
|
|
if os.path.isdir(payload):
|
|
for fn in os.listdir(payload):
|
|
datas.append((os.path.join(payload, fn), "payload"))
|
|
|
|
# FAIL the build (don't ship an unusable artifact) if any required native tool or
|
|
# payload for this host is missing.
|
|
_required_native = ["usbboot", "mksquashfs", "unsquashfs",
|
|
"my_write5_dram.bin", "disc_spl_lpddr3.bin"]
|
|
_required_payload = ["mq_ui", "S97diskos_install", "S99usbserial", "diskos-debug.sh", "dropbearmulti"]
|
|
_missing = [n for n in _required_native if not os.path.exists(os.path.join(vend, n))]
|
|
_missing += [f"payload/{n}" for n in _required_payload if not os.path.exists(os.path.join(payload, n))]
|
|
if _missing:
|
|
raise SystemExit(f"REFUSING to build: missing bundled files for {TAG}: {_missing}. "
|
|
f"Populate vendor/{TAG}/ and payload/ first.")
|
|
|
|
# pycryptodome loads C submodules dynamically; collect them all so the frozen
|
|
# app can AES-decrypt the FiiO OTA chunks.
|
|
from PyInstaller.utils.hooks import collect_submodules
|
|
hidden = ["usb", "usb.core", "usb.backend.libusb1"] + collect_submodules("Crypto")
|
|
|
|
a = Analysis(
|
|
[os.path.join(ROOT, "diskos_installer", "__main__.py")],
|
|
pathex=[ROOT],
|
|
binaries=[],
|
|
datas=datas,
|
|
hiddenimports=hidden,
|
|
hookspath=[],
|
|
runtime_hooks=[],
|
|
excludes=[],
|
|
noarchive=False,
|
|
)
|
|
pyz = PYZ(a.pure)
|
|
# onefile: pass binaries + datas straight into EXE with no COLLECT step.
|
|
exe = EXE(
|
|
pyz, a.scripts, a.binaries, a.datas, [],
|
|
name="diskos-installer",
|
|
debug=False, bootloader_ignore_signals=False, strip=False, upx=False,
|
|
console=True,
|
|
)
|