diff --git a/Client/Packaging/BuildAppImage.sh b/Client/Packaging/BuildAppImage.sh index 81a5a5a..a89be54 100755 --- a/Client/Packaging/BuildAppImage.sh +++ b/Client/Packaging/BuildAppImage.sh @@ -1,20 +1,30 @@ #!/bin/bash # Builds dist/SaraView-x86_64.AppImage: a PyInstaller one-file build (with # the font and icon bundled) wrapped by appimagetool, the same way SaraSort's, -# SaraSuite's and SaraFem's AppImages are made. Needs appimagetool on PATH. +# SaraSuite's and SaraFem's AppImages are made. Needs podman and +# appimagetool on PATH. set -euo pipefail cd "$(dirname "$(readlink -f "$0")")/.." -[ -d .venv ] || python3 -m venv .venv -.venv/bin/pip install --quiet --disable-pip-version-check -r requirements.txt pyinstaller - +# PyInstaller runs in a manylinux_2_28 container (glibc 2.28) with uv's +# portable Python, not with Fedora's: PyInstaller bundles libpython, and +# Fedora's needs a newer glibc than many distros have ("GLIBC_ABI_GNU2_TLS +# not found"). The whole repository goes in, for ../Backend/VarEngine.py. +# The Python, venv and downloads are cached in build/Container. # --collect-data flet: without it ft.Icons crashes when frozen. -.venv/bin/pyinstaller --noconfirm --clean --log-level WARN \ - --onefile --windowed --name SaraView --collect-data flet \ - --add-data "$PWD/assets:assets" \ - --paths "$PWD/../Backend" --hidden-import VarEngine \ - --distpath build/PyInstaller/dist --workpath build/PyInstaller/work --specpath build/PyInstaller \ - "$PWD/Main.py" +mkdir -p build/Container +podman run --rm --security-opt label=disable -v "$PWD/..:/src" -w /src/Client \ + -e UV_CACHE_DIR=/src/Client/build/Container/cache -e UV_PYTHON_INSTALL_DIR=/src/Client/build/Container/python \ + quay.io/pypa/manylinux_2_28_x86_64 bash -euo pipefail -c ' + uv venv --quiet --allow-existing --managed-python --python 3.14 build/Container/venv + uv pip install --quiet --python build/Container/venv -r requirements.txt pyinstaller + build/Container/venv/bin/pyinstaller --noconfirm --clean --log-level WARN \ + --onefile --windowed --name SaraView --collect-data flet \ + --runtime-hook "$PWD/Packaging/RestoreLibraryPath.py" \ + --add-data "$PWD/assets:assets" \ + --paths "$PWD/../Backend" --hidden-import VarEngine \ + --distpath build/PyInstaller/dist --workpath build/PyInstaller/work --specpath build/PyInstaller \ + "$PWD/Main.py"' AppDir=build/AppDir rm -rf "$AppDir" diff --git a/Client/Packaging/RestoreLibraryPath.py b/Client/Packaging/RestoreLibraryPath.py new file mode 100644 index 0000000..446798a --- /dev/null +++ b/Client/Packaging/RestoreLibraryPath.py @@ -0,0 +1,11 @@ +# PyInstaller runtime hook. The frozen app runs with LD_LIBRARY_PATH pointing +# at its bundled libraries, and programs it starts inherit that: Flet's +# desktop client then loads the bundled (older) libstdc++ instead of the +# system's and won't start ("GLIBCXX_3.4.29 not found"). Give them the +# original value back; the app itself has already loaded what it needs. +import os + +if "LD_LIBRARY_PATH_ORIG" in os.environ: + os.environ["LD_LIBRARY_PATH"] = os.environ["LD_LIBRARY_PATH_ORIG"] +else: + os.environ.pop("LD_LIBRARY_PATH", None)