From 46583f562298b8c41c50df124c66aa11e2439d3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois?= Date: Sat, 30 May 2026 10:42:46 +0200 Subject: [PATCH] build_all: --ram mode (build scratch on tmpfs) for slow storage Redirect the per-channel build scratch to /dev/shm and skip UPX, a big win when building from a USB stick / SD card (I/O-bound on flash): - TMPDIR + PIP_CACHE_DIR -> tmpfs - PyInstaller: --workpath -> tmpfs (PYI_WORKPATH); UPX off via TESTIUM_NO_UPX - Flatpak: build dir + ostree repo -> tmpfs (FLATPAK_BUILDDIR/REPODIR); the .flatpak-builder download cache stays on disk - AppImage: bind-mount a tmpfs dir at the in-container AppDir path (APPIMAGE_APPDIR_TMPFS) Scratch is freed on exit. Each build.sh honors the env vars with on-disk defaults, so behavior is unchanged without --ram. With --ram, prefer --serial on RAM-limited machines (flatpak+appimage are ~1 GB each). Co-Authored-By: Claude Opus 4.8 --- build_all.sh | 31 +++++++++++++++++++++++++++++++ package/appimage/build.sh | 9 +++++++++ package/flatpak/build.sh | 10 +++++++--- package/pyinstaller/build.sh | 8 ++++++-- package/pyinstaller/testium.spec | 4 +++- 5 files changed, 56 insertions(+), 6 deletions(-) diff --git a/build_all.sh b/build_all.sh index b5bbe24..0a3a6ab 100755 --- a/build_all.sh +++ b/build_all.sh @@ -20,6 +20,11 @@ # of the parallel phase is captured under dist/.build-logs/.log and the # log of any failing step is printed at the end. # +# Pass --ram to redirect the per-channel build scratch (PyInstaller workpath, +# Flatpak build dir + ostree repo, AppImage AppDir) and TMPDIR/PIP_CACHE_DIR to +# /dev/shm, and skip UPX. Big speedup on slow/flash storage. On a RAM-limited +# machine combine with --serial (e.g. ./build_all.sh --ram --serial). +# # All artifacts are collected (copied) under /dist/. Original outputs in # src/dist/, package/*/dist/, doc/manual/ are left in place. Wheel and AppImage # keep their original names (which already contain the version); manual, @@ -36,10 +41,12 @@ set -e CLEAN=0 SERIAL=0 +RAM=0 for arg in "$@"; do case "$arg" in --clean|-c) CLEAN=1 ;; --serial) SERIAL=1 ;; + --ram) RAM=1 ;; *) echo "Unknown option: $arg" >&2; exit 1 ;; esac done @@ -74,6 +81,30 @@ export REQ_PATH="$SCRIPT_DIR/src/requirements.txt" bash "$SCRIPT_DIR/scripts/build_env.sh" source "$SCRIPT_DIR/scripts/set_env.sh" +# ---------- RAM mode: put build scratch on tmpfs (--ram) ---------------------- +# On slow storage (USB stick, SD card) the per-channel build dirs and temp +# churn dominate. --ram redirects them to /dev/shm and skips UPX. The +# .flatpak-builder cache stays on disk so source downloads persist. The tmpfs +# scratch is freed on exit. +if [ "$RAM" -eq 1 ]; then + RAMROOT="/dev/shm/testium-build-${VERSION}" + echo "-- RAM mode: build scratch under $RAMROOT (tmpfs), freed on exit" + rm -rf "$RAMROOT" + mkdir -p "$RAMROOT"/{tmp,pip,pyi-work,flatpak-build,flatpak-repo,appdir} + export TMPDIR="$RAMROOT/tmp" + export PIP_CACHE_DIR="$RAMROOT/pip" + export PYI_WORKPATH="$RAMROOT/pyi-work" # pyinstaller --workpath + export FLATPAK_BUILDDIR="$RAMROOT/flatpak-build" # flatpak-builder build dir + export FLATPAK_REPODIR="$RAMROOT/flatpak-repo" # ostree repo + export APPIMAGE_APPDIR_TMPFS="$RAMROOT/appdir" # AppDir bind-mount + export TESTIUM_NO_UPX=1 # skip slow UPX in the spec + trap 'rm -rf "$RAMROOT"' EXIT + if [ "$SERIAL" -ne 1 ]; then + echo " note: with --ram, prefer adding --serial so each step gets the" + echo " full tmpfs and you don't risk OOM (flatpak+appimage are ~1 GB each)." + fi +fi + step() { echo echo "================================================================" diff --git a/package/appimage/build.sh b/package/appimage/build.sh index ad00830..ace54b7 100755 --- a/package/appimage/build.sh +++ b/package/appimage/build.sh @@ -17,11 +17,20 @@ else fi echo "Using $RUNTIME — building testium $APP_VERSION AppImage..." +# APPIMAGE_APPDIR_TMPFS (set by build_all --ram) bind-mounts a host tmpfs dir at +# the AppDir build path, keeping the ~1 GB AppDir churn off slow storage. +APPDIR_MOUNT="" +if [ -n "$APPIMAGE_APPDIR_TMPFS" ]; then + mkdir -p "$APPIMAGE_APPDIR_TMPFS" + APPDIR_MOUNT="-v $APPIMAGE_APPDIR_TMPFS:/work/package/appimage/AppDir" +fi + # APPIMAGE_EXTRACT_AND_RUN=1 lets appimagetool run without FUSE in the container. $RUNTIME run --rm \ --privileged \ -e APPIMAGE_EXTRACT_AND_RUN=1 \ -v "$REPO_ROOT:/work" \ + $APPDIR_MOUNT \ -w /work/package/appimage \ debian:bookworm bash -c " set -e diff --git a/package/flatpak/build.sh b/package/flatpak/build.sh index 812a5da..d4d7044 100755 --- a/package/flatpak/build.sh +++ b/package/flatpak/build.sh @@ -7,11 +7,15 @@ set -e -# Build + install local -flatpak-builder --user --verbose --force-clean --install --repo=repo build org.testium.Testium.yaml +# Build + install local. FLATPAK_BUILDDIR / FLATPAK_REPODIR (set by build_all +# --ram) redirect the build dir and the ostree repo to tmpfs. The +# .flatpak-builder cache stays local so source downloads persist between runs. +BUILDDIR="${FLATPAK_BUILDDIR:-build}" +REPODIR="${FLATPAK_REPODIR:-repo}" +flatpak-builder --user --verbose --force-clean --install --repo="$REPODIR" "$BUILDDIR" org.testium.Testium.yaml # Génère le bundle distribuable -flatpak build-bundle repo testium.flatpak org.testium.Testium +flatpak build-bundle "$REPODIR" testium.flatpak org.testium.Testium echo "Bundle généré : $(pwd)/testium.flatpak" # Crée ~/.local/bin/testium pour pouvoir taper "testium" en console diff --git a/package/pyinstaller/build.sh b/package/pyinstaller/build.sh index a54b313..23cfe37 100755 --- a/package/pyinstaller/build.sh +++ b/package/pyinstaller/build.sh @@ -2,11 +2,15 @@ SCRIPT_DIR=$(realpath $( dirname "$0")) -rm -r "${SCRIPT_DIR}/build" "${SCRIPT_DIR}/dist" +rm -rf "${SCRIPT_DIR}/build" "${SCRIPT_DIR}/dist" pwd=$(pwd) cd ${SCRIPT_DIR} -pyinstaller testium.spec +# PYI_WORKPATH (set by build_all --ram) puts the big intermediate build tree on +# tmpfs; dist/ stays local so build_all can collect the binary. +WORKARG="" +[ -n "$PYI_WORKPATH" ] && WORKARG="--workpath $PYI_WORKPATH" +pyinstaller $WORKARG testium.spec RESULT=$? if [ -n "$1" ] && [ "$1" = "install" ]; then if [ $RESULT -eq 0 ]; then diff --git a/package/pyinstaller/testium.spec b/package/pyinstaller/testium.spec index 7e2f191..6d2de79 100644 --- a/package/pyinstaller/testium.spec +++ b/package/pyinstaller/testium.spec @@ -89,7 +89,9 @@ exe = EXE( debug=False, bootloader_ignore_signals=False, strip=False, - upx=True, + # UPX is CPU+IO heavy for a marginal size gain — build_all --ram sets + # TESTIUM_NO_UPX=1 to skip it (much faster on slow/flash storage). + upx=not os.environ.get("TESTIUM_NO_UPX"), upx_exclude=[], runtime_tmpdir=None, console=True,