From a16e593fa8b709e72683d1d670bcafefba9d91bc Mon Sep 17 00:00:00 2001 From: spectranator Date: Sun, 6 Apr 2025 19:15:22 +0200 Subject: [PATCH] Made AppImages way more robust, compatible and reproducible using containerization and by using system-provided glibc --- AppImage-build-debian-inner.sh | 37 ++++++++++++++++++++ AppImage-build-debian.sh | 27 ++++++++++++++ AppImage-build.sh => AppImage-build-local.sh | 0 AppImageBuilder/assets_aarch64/yuzu.sh | 5 +-- AppImageBuilder/assets_x86_64/yuzu.sh | 2 +- AppImageBuilder/build.sh | 29 +++++++++++++-- 6 files changed, 92 insertions(+), 8 deletions(-) create mode 100755 AppImage-build-debian-inner.sh create mode 100755 AppImage-build-debian.sh rename AppImage-build.sh => AppImage-build-local.sh (100%) diff --git a/AppImage-build-debian-inner.sh b/AppImage-build-debian-inner.sh new file mode 100755 index 000000000..2486d46f2 --- /dev/null +++ b/AppImage-build-debian-inner.sh @@ -0,0 +1,37 @@ +#! /bin/bash +set -e + +# Make sure script is called from inside our container +test -e /tmp/torzu-src || (echo "Script MUST NOT be called directly!" ; exit 1) + +# Install dependencies +apt -y install cmake ninja-build build-essential pkg-config locales wget git file +apt -y install libfmt-dev libenet-dev liblz4-dev nlohmann-json3-dev zlib1g-dev libopus-dev libsimpleini-dev libstb-dev libzstd-dev libusb-1.0-0-dev libcubeb-dev libcpp-jwt-dev libvulkan-dev gamemode-dev libasound2-dev libglu1-mesa-dev libxext-dev mesa-common-dev qtbase5-dev qtmultimedia5-dev qtbase5-private-dev libva-dev glslang-tools libavcodec-dev libavfilter-dev libavutil-dev libswscale-dev + +# Install correct version of boost +cd /tmp +wget https://web.archive.org/web/20241120101759id_/https://boostorg.jfrog.io/artifactory/main/release/1.84.0/source/boost_1_84_0.tar.bz2 +tar xf boost_1_84_0.tar.bz2 +cd boost_1_84_0 +./bootstrap.sh +./b2 install --with-{headers,context} link=static +cd .. +rm -rf boost_1_84_0 + +# Build Torzu +cd /tmp +mkdir torzu-build +cd torzu-build +cmake /tmp/torzu-src -GNinja -DCMAKE_BUILD_TYPE=Release -DYUZU_TESTS=OFF -DENABLE_QT_TRANSLATION=OFF -DSPIRV_WERROR=OFF -DBUILD_SHARED_LIBS=OFF -DCMAKE_FIND_LIBRARY_SUFFIXES=".a;.so" -DSPIRV-Headers_SOURCE_DIR=/tmp/torzu-src/externals/SPIRV-Headers +ninja + +# Generate AppImage +cp -rv /tmp/torzu-src/AppImageBuilder /tmp/AppImageBuilder +cd /tmp/AppImageBuilder +./build.sh /tmp/torzu-build /tmp/torzu.AppImage || echo "This error is known. Using workaround..." +cp /lib/$(uname -m)-linux-gnu/libICE.so.6 build/ +mv build /tmp/hosttmp/torzu-debian-appimage-rootfs + +# Debug +cd /tmp/hosttmp/torzu-debian-appimage-rootfs +bash diff --git a/AppImage-build-debian.sh b/AppImage-build-debian.sh new file mode 100755 index 000000000..80409d1a8 --- /dev/null +++ b/AppImage-build-debian.sh @@ -0,0 +1,27 @@ +#! /bin/bash +set -e + +# Get torzu source dir +TORZU_SOURCE_DIR="$(realpath "$(dirname "${BASH_SOURCE[0]}")")" +echo "Source dir is $TORZU_SOURCE_DIR" +rm -rf "$TORZU_SOURCE_DIR/AppImageBuilder/build" + +# Generate debian rootfs +cd /tmp +rm -rf rootfs-torzu-appimage-build +debootstrap stable rootfs-torzu-appimage-build http://deb.debian.org/debian/ +bwrap --bind rootfs-torzu-appimage-build / \ + --unshare-pid \ + --dev-bind /dev /dev --proc /proc --tmpfs /tmp --ro-bind /sys /sys --dev-bind /run /run \ + --tmpfs /var/tmp \ + --chmod 1777 /tmp \ + --ro-bind /etc/resolv.conf /etc/resolv.conf \ + --ro-bind "$TORZU_SOURCE_DIR" /tmp/torzu-src \ + --chdir / \ + --tmpfs /home \ + --setenv HOME /home \ + --bind /tmp /tmp/hosttmp \ + /tmp/torzu-src/AppImage-build-debian-inner.sh +appimagetool /tmp/torzu-debian-appimage-rootfs /tmp/torzu.AppImage +echo "AppImage generated at /tmp/torzu.AppImage! Cleaning up..." +exec rm -rf /tmp/torzu-debian-appimage-rootfs /tmp/rootfs-torzu-appimage-build diff --git a/AppImage-build.sh b/AppImage-build-local.sh similarity index 100% rename from AppImage-build.sh rename to AppImage-build-local.sh diff --git a/AppImageBuilder/assets_aarch64/yuzu.sh b/AppImageBuilder/assets_aarch64/yuzu.sh index 74b2669ce..54cf2246e 100755 --- a/AppImageBuilder/assets_aarch64/yuzu.sh +++ b/AppImageBuilder/assets_aarch64/yuzu.sh @@ -1,6 +1,3 @@ #! /bin/sh -# NOTE: the `ld-linux-aarch64.so.1` filename came from a pi debian 11 installation, -# this may be incorrect for a different or more up-to-date system. -# Can find out the correct filename using command "ldd yuzu" on the non-AppImage app -QT_QPA_PLATFORM=xcb QT_PLUGIN_PATH=. exec ./ld-linux-aarch64.so.1 --library-path . ./yuzu "$@" +LD_LIBRARY_PATH=/usr/lib/$(uname -m)-linux-gnu:. QT_QPA_PLATFORM=xcb QT_PLUGIN_PATH=. exec ./yuzu "$@" diff --git a/AppImageBuilder/assets_x86_64/yuzu.sh b/AppImageBuilder/assets_x86_64/yuzu.sh index 43ad5ec41..a90572a75 100755 --- a/AppImageBuilder/assets_x86_64/yuzu.sh +++ b/AppImageBuilder/assets_x86_64/yuzu.sh @@ -1,2 +1,2 @@ #! /bin/sh -QT_QPA_PLATFORM=xcb QT_PLUGIN_PATH=. exec ./ld-linux-x86-64.so.2 --library-path . ./yuzu "$@" +LD_LIBRARY_PATH=/usr/lib/$(uname -m)-linux-gnu:. QT_QPA_PLATFORM=xcb QT_PLUGIN_PATH=. exec ./yuzu "$@" diff --git a/AppImageBuilder/build.sh b/AppImageBuilder/build.sh index 671bfcc7f..86a10ef2d 100755 --- a/AppImageBuilder/build.sh +++ b/AppImageBuilder/build.sh @@ -60,13 +60,36 @@ if [ $QTFOUND == "true" ]; then # - '/lib64/ld-linux-x86-64.so.2' or `/lib/ld-linux-aarch64.so.1` file per architecture # - required files from `/usr/lib/x86_64-linux-gnu` or `/usr/lib/aarch64-linux-gnu` # - different for SteamDeck, but still does it automatically - for lib in $(ldd "$YUZU_BIN_GUI"); do - (cp -v "$lib" ./build/ 2> /dev/null) || true - done + function copy_libs { + for lib in $(ldd "$1"); do + (cp -vn "$lib" ./build/ 2> /dev/null) || true + done + } + echo "Copying main dependencies..." + copy_libs "$YUZU_BIN_GUI" # Copy QT dependency folders, path determined above + echo "Copying Qt dependencies..." cp -rv "$QTDIR"/{imageformats,platforms,platformthemes,xcbglintegrations} ./build/ + # Discover indirect dependencies (mostly from runtime-loaded Qt plugins) + echo "Copying extra dependencies..." + while true; do + LIBS="$(find ./build -name \*.so\*)" + LIB_COUNT=$(echo "$LIBS" | wc -l) + echo "$LIB_COUNT dependency libraries discovered so far..." + if [ $LIB_COUNT == "$PREV_LIB_COUNT" ]; then + break + fi + PREV_LIB_COUNT=$LIB_COUNT + + for plib in $LIBS; do + if [ -f "$plib" ]; then + copy_libs "$plib" + fi + done + done + # Copy executable cp -v "$YUZU_BIN_GUI" ./build/