From 66611b9bc3812c67025378e06a6c4ccdcd8a0205 Mon Sep 17 00:00:00 2001 From: edde746 <86283021+edde746@users.noreply.github.com> Date: Tue, 17 Feb 2026 01:20:10 +0100 Subject: [PATCH] feat: dockerfile-based steam build with layer caching --- .dockerignore | 19 ++++++++ linux/packaging/build-libmpv.sh | 2 +- scripts/build_steam.sh | 82 ++++++--------------------------- scripts/bundle_steam.sh | 66 ++++++++++++++++++++++++++ scripts/steam.Dockerfile | 41 +++++++++++++++++ 5 files changed, 140 insertions(+), 70 deletions(-) create mode 100644 .dockerignore create mode 100644 scripts/bundle_steam.sh create mode 100644 scripts/steam.Dockerfile diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..9a33c5ec --- /dev/null +++ b/.dockerignore @@ -0,0 +1,19 @@ +.git +build/ +.dart_tool/ +.idea/ +*.tar.gz +nul +libmpv-prefix/ +steamfiles/ +pubspec_overrides.yaml + +# Flutter ephemeral / generated plugin symlinks +linux/flutter/ephemeral/ +windows/flutter/ +macos/Flutter/ +ios/Flutter/ +android/.gradle/ +android/app/build/ +.flutter-plugins +.flutter-plugins-dependencies diff --git a/linux/packaging/build-libmpv.sh b/linux/packaging/build-libmpv.sh index ee137c66..88f0054f 100755 --- a/linux/packaging/build-libmpv.sh +++ b/linux/packaging/build-libmpv.sh @@ -131,7 +131,7 @@ meson setup build \ -Dalsa=enabled \ -Dpulse=enabled \ -Dpipewire=enabled \ - -Dwayland=enabled \ + -Dwayland=disabled \ -Dx11=enabled ninja -C build -j"$JOBS" diff --git a/scripts/build_steam.sh b/scripts/build_steam.sh index 5ff66849..12d372ca 100755 --- a/scripts/build_steam.sh +++ b/scripts/build_steam.sh @@ -1,76 +1,20 @@ #!/usr/bin/env bash set -euo pipefail -SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" -PROJECT_ROOT="$SCRIPT_DIR/.." -IMAGE="registry.gitlab.steamos.cloud/steamrt/sniper/sdk:latest" +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -W 2>/dev/null || pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd -W 2>/dev/null || pwd)" -docker run --rm \ +echo "==> Building plezy for Steam (Docker)..." +MSYS_NO_PATHCONV=1 docker build \ --platform linux/amd64 \ - -v "$PROJECT_ROOT":/app \ - -w /app \ - "$IMAGE" \ - bash -c ' -set -euo pipefail + -f "$PROJECT_ROOT/scripts/steam.Dockerfile" \ + -t plezy-steam-build \ + "$PROJECT_ROOT" -echo "==> Installing build dependencies..." -apt-get update -qq -apt-get install -y -qq \ - clang cmake meson ninja-build pkg-config nasm git curl unzip xz-utils \ - libgtk-3-dev liblzma-dev \ - libasound2-dev libass-dev libfreetype-dev libfontconfig-dev libfribidi-dev libharfbuzz-dev \ - libepoxy-dev libegl-dev libgl-dev libgnutls28-dev \ - libpipewire-0.3-dev libva-dev libvdpau-dev \ - libx11-dev libxext-dev libxrandr-dev libxcursor-dev libxi-dev libxss-dev libxpresent-dev \ - libxkbcommon-dev libpulse-dev libdbus-1-dev libdrm-dev libgbm-dev \ - libwayland-dev wayland-protocols liblcms2-dev python3-pip \ +echo "==> Extracting tarball..." +MSYS_NO_PATHCONV=1 docker create --name plezy-steam-extract plezy-steam-build true 2>/dev/null \ + || { docker rm plezy-steam-extract 2>/dev/null; MSYS_NO_PATHCONV=1 docker create --name plezy-steam-extract plezy-steam-build true; } +MSYS_NO_PATHCONV=1 docker cp plezy-steam-extract:/app/plezy-steam-linux-x64.tar.gz "$PROJECT_ROOT/" +docker rm plezy-steam-extract -pip3 install meson --upgrade - -echo "" -echo "==> Building libmpv..." -bash linux/packaging/build-libmpv.sh - -export PKG_CONFIG_PATH="$(pwd)/libmpv-prefix/lib/pkgconfig:$(pwd)/libmpv-prefix/lib/x86_64-linux-gnu/pkgconfig:${PKG_CONFIG_PATH:-}" - -echo "" -echo "==> Installing Flutter..." -git clone --depth 1 --branch stable https://github.com/flutter/flutter.git /opt/flutter -export PATH="/opt/flutter/bin:$PATH" -flutter --disable-analytics -flutter config --no-cli-animations -flutter precache --linux - -echo "" -echo "==> Building Plezy..." -flutter pub get -flutter build linux --release --dart-define=ENABLE_UPDATE_CHECK=true - -echo "" -echo "==> Assembling Steam bundle..." -BUNDLE=build/linux/x64/release/bundle - -# Copy libmpv + shaderc into bundle -BUNDLE_LIB="$BUNDLE/lib" -LIBMPV_DIR=$(dirname "$(find libmpv-prefix -name libmpv.so | head -1)") -cp -a "$LIBMPV_DIR"/libmpv.so* "$BUNDLE_LIB/" -cp -a libmpv-prefix/lib/libshaderc_shared.so* "$BUNDLE_LIB/" - -# For Steam, do NOT run bundle-libs.sh — the runtime provides system libs. -# Only verify the binary can resolve deps against the runtime. -echo "" -echo "==> Checking dependencies..." -MISSING=$(LD_LIBRARY_PATH="$BUNDLE_LIB" ldd "$BUNDLE/plezy" 2>&1 | grep "not found" || true) -if [[ -n "$MISSING" ]]; then - echo "WARNING: Unresolved dependencies (will need Steam runtime):" - echo "$MISSING" -fi - -echo "" -echo "==> Creating tarball..." -cd "$BUNDLE" -tar -czf /app/plezy-steam-linux-x64.tar.gz * - -echo "" -echo "==> Done! Output: plezy-steam-linux-x64.tar.gz" -' +echo "==> Output: plezy-steam-linux-x64.tar.gz" diff --git a/scripts/bundle_steam.sh b/scripts/bundle_steam.sh new file mode 100644 index 00000000..2c39297d --- /dev/null +++ b/scripts/bundle_steam.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash +set -euo pipefail + +echo "==> Assembling Steam bundle..." +BUNDLE=build/linux/x64/release/bundle +BUNDLE_LIB="$BUNDLE/lib" + +# Copy libmpv + shaderc into bundle +LIBMPV_DIR=$(dirname "$(find /build/libmpv-prefix -name libmpv.so | head -1)") +cp -a "$LIBMPV_DIR"/libmpv.so* "$BUNDLE_LIB/" +cp -a /build/libmpv-prefix/lib/libshaderc_shared.so* "$BUNDLE_LIB/" + +# Bundle libmpv's runtime deps that the Steam Runtime doesn't ship. +# /steam-rt-libs.txt was snapshot before we built anything (see Dockerfile). +echo "" +echo "==> Bundling libmpv runtime dependencies..." +RT_LIBS="/steam-rt-libs.txt" +ldd "$LIBMPV_DIR/libmpv.so" 2>/dev/null | grep "=> /" | awk '{print $3}' | while read dep; do + dep_name=$(basename "$dep") + if ! grep -qF "$dep_name" "$RT_LIBS"; then + if [ ! -f "$BUNDLE_LIB/$dep_name" ]; then + echo " Bundling $dep_name" + cp -a "$dep" "$BUNDLE_LIB/" + # Also copy any symlink variants + dep_dir=$(dirname "$dep") + dep_base=$(echo "$dep_name" | sed 's/\.so.*//') + cp -a "$dep_dir"/${dep_base}.so* "$BUNDLE_LIB/" 2>/dev/null || true + fi + fi +done + +# Verify all deps resolve +echo "" +echo "==> Checking dependencies..." +MISSING=$(LD_LIBRARY_PATH="$BUNDLE_LIB" ldd "$BUNDLE/plezy" 2>&1 | grep "not found" || true) +MISSING_MPV=$(LD_LIBRARY_PATH="$BUNDLE_LIB" ldd "$BUNDLE_LIB/libmpv.so" 2>&1 | grep "not found" || true) +MISSING="$MISSING$MISSING_MPV" +if [[ -n "$MISSING" ]]; then + echo "WARNING: Unresolved dependencies (will need Steam runtime):" + echo "$MISSING" +else + echo "All dependencies resolved." +fi + +# Create launcher script that sets LD_LIBRARY_PATH for bundled libs +echo "" +echo "==> Creating launcher script..." +mv "$BUNDLE/plezy" "$BUNDLE/plezy.bin" +cat > "$BUNDLE/plezy" <<'LAUNCHER' +#!/usr/bin/env bash +SCRIPT_PATH="$(readlink -f "$0")" +INSTALL_DIR="$(dirname "$SCRIPT_PATH")" + +export LD_LIBRARY_PATH="$INSTALL_DIR/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" + +exec "$INSTALL_DIR/plezy.bin" "$@" +LAUNCHER +chmod +x "$BUNDLE/plezy" + +echo "" +echo "==> Creating tarball..." +cd "$BUNDLE" +tar -czf /app/plezy-steam-linux-x64.tar.gz * + +echo "" +echo "==> Done! Output: plezy-steam-linux-x64.tar.gz" diff --git a/scripts/steam.Dockerfile b/scripts/steam.Dockerfile new file mode 100644 index 00000000..b6a875bd --- /dev/null +++ b/scripts/steam.Dockerfile @@ -0,0 +1,41 @@ +# Snapshot libs from the runtime (not SDK) — this is what's actually on the Steam Deck. +FROM registry.gitlab.steamos.cloud/steamrt/sniper/platform:latest AS runtime-snapshot +RUN find /lib /usr/lib -name '*.so*' -type f -o -type l 2>/dev/null | xargs -r basename -a | sort -u > /steam-rt-libs.txt + +FROM registry.gitlab.steamos.cloud/steamrt/sniper/sdk:latest +COPY --from=runtime-snapshot /steam-rt-libs.txt /steam-rt-libs.txt + +# ─── Layer 1: apt deps (cached unless this block changes) ───────────────────── +RUN apt-get update -qq && apt-get install -y -qq \ + clang cmake meson ninja-build pkg-config nasm git curl unzip xz-utils \ + libgtk-3-dev liblzma-dev \ + libasound2-dev libass-dev libfreetype-dev libfontconfig-dev libfribidi-dev libharfbuzz-dev \ + libepoxy-dev libegl-dev libgl-dev libgnutls28-dev \ + libpipewire-0.3-dev libva-dev libvdpau-dev \ + libx11-dev libxext-dev libxrandr-dev libxcursor-dev libxi-dev libxss-dev libxpresent-dev \ + libxkbcommon-dev libpulse-dev libdbus-1-dev libdrm-dev libgbm-dev \ + libwayland-dev wayland-protocols liblcms2-dev python3-pip \ + && pip3 install meson --upgrade \ + && rm -rf /var/lib/apt/lists/* + +# ─── Layer 2: libmpv (cached unless build-libmpv.sh changes) ────────────────── +WORKDIR /build +COPY linux/packaging/build-libmpv.sh linux/packaging/ +RUN bash linux/packaging/build-libmpv.sh + +# ─── Layer 3: Flutter SDK (cached unless Flutter channel changes) ────────────── +RUN git clone --depth 1 --branch stable https://github.com/flutter/flutter.git /opt/flutter +ENV PATH="/opt/flutter/bin:$PATH" +RUN flutter --disable-analytics \ + && flutter config --no-cli-animations \ + && flutter precache --linux + +# ─── Layer 4: App build (runs on every source change) ───────────────────────── +COPY . /app +WORKDIR /app +ENV PKG_CONFIG_PATH="/build/libmpv-prefix/lib/pkgconfig:/build/libmpv-prefix/lib/x86_64-linux-gnu/pkgconfig" +RUN flutter pub get \ + && flutter build linux --release + +# ─── Layer 5: Bundle assembly + dep bundling ────────────────────────────────── +RUN bash scripts/bundle_steam.sh