From 414a0e6877f9963cdbe1035045687ae782791214 Mon Sep 17 00:00:00 2001 From: Matias Galarza Date: Thu, 19 Feb 2026 13:51:40 -0300 Subject: [PATCH 1/5] feat: bundle libwebkit2gtk-4.1 and runtime deps in AppImages Use linuxdeploy to automatically bundle all ldd-detected shared libraries into AppImages. Additionally bundle WebKit helper processes, GLib schemas, GIO modules, and GDK pixbuf loaders which are not detected by ldd but required at runtime. AppImages grow from ~9 MB to ~100-150 MB but now work on systems without webkit2gtk installed (e.g. SteamOS/Steam Deck). Closes #194 --- .github/workflows/release.yml | 148 ++++++++++++++++++++++++++-------- build_all.sh | 93 +++++++++++++++++++++ 2 files changed, 208 insertions(+), 33 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c7b6a03c..f61da36c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -94,12 +94,115 @@ jobs: name: agent-linux-amd64 path: artifacts/agent - - name: Download appimagetool + - name: Install system dependencies + run: | + sudo apt-get update + sudo apt-get install -y libwebkit2gtk-4.1-dev libgtk-3-dev + + - name: Download tools run: | curl -L -o appimagetool https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage - chmod +x appimagetool + curl -L -o linuxdeploy https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage + chmod +x appimagetool linuxdeploy + + - name: Prepare AppDirs + run: | + generate_desktop() { + local binary_name="$1" + local display_name="$2" + local output="$3" + cat > "$output" << DESKTOP_EOF + [Desktop Entry] + Name=${display_name} + Comment=Deploy games to Steam Deck and Linux devices + Exec=${binary_name} + Icon=${binary_name} + Type=Application + Categories=Game;Development; + Terminal=false + DESKTOP_EOF + } + + # Hub AppDir + mkdir -p hub.AppDir/usr/bin + cp artifacts/hub/capydeploy-hub-tauri hub.AppDir/usr/bin/ + chmod +x hub.AppDir/usr/bin/capydeploy-hub-tauri + cp apps/hub-tauri/src-tauri/icons/icon.png hub.AppDir/capydeploy-hub.png + generate_desktop "capydeploy-hub" "CapyDeploy Hub" "hub.AppDir/capydeploy-hub.desktop" + + # Agent AppDir + mkdir -p agent.AppDir/usr/bin + cp artifacts/agent/capydeploy-agent-tauri agent.AppDir/usr/bin/ + chmod +x agent.AppDir/usr/bin/capydeploy-agent-tauri + cp apps/agents/agent-tauri/src-tauri/icons/icon.png agent.AppDir/capydeploy-agent.png + generate_desktop "capydeploy-agent" "CapyDeploy Agent" "agent.AppDir/capydeploy-agent.desktop" + + - name: Bundle libraries + env: + APPIMAGE_EXTRACT_AND_RUN: "1" + run: | + # Bundle shared libraries with linuxdeploy + ./linuxdeploy --appdir hub.AppDir \ + --executable hub.AppDir/usr/bin/capydeploy-hub-tauri \ + --desktop-file hub.AppDir/capydeploy-hub.desktop \ + --icon-file hub.AppDir/capydeploy-hub.png + + ./linuxdeploy --appdir agent.AppDir \ + --executable agent.AppDir/usr/bin/capydeploy-agent-tauri \ + --desktop-file agent.AppDir/capydeploy-agent.desktop \ + --icon-file agent.AppDir/capydeploy-agent.png + + # Bundle WebKit helper processes (not detected by ldd) + WEBKIT_DIR="" + for candidate in /usr/libexec/webkit2gtk-4.1 /usr/lib/x86_64-linux-gnu/webkit2gtk-4.1; do + if [ -d "$candidate" ]; then + WEBKIT_DIR="$candidate" + break + fi + done + if [ -n "$WEBKIT_DIR" ]; then + echo "Bundling WebKit helpers from $WEBKIT_DIR..." + for appdir in hub.AppDir agent.AppDir; do + mkdir -p "$appdir/usr/libexec/webkit2gtk-4.1" + cp "$WEBKIT_DIR/WebKitWebProcess" "$appdir/usr/libexec/webkit2gtk-4.1/" + cp "$WEBKIT_DIR/WebKitNetworkProcess" "$appdir/usr/libexec/webkit2gtk-4.1/" + done + else + echo "::warning::WebKit helpers not found" + fi + + # Bundle GLib compiled schemas + if [ -f "/usr/share/glib-2.0/schemas/gschemas.compiled" ]; then + echo "Bundling GLib schemas..." + for appdir in hub.AppDir agent.AppDir; do + mkdir -p "$appdir/usr/share/glib-2.0/schemas" + cp /usr/share/glib-2.0/schemas/gschemas.compiled "$appdir/usr/share/glib-2.0/schemas/" + done + fi + + # Bundle GIO modules (TLS support) + GIO_DIR=$(pkg-config --variable=giomoduledir gio-2.0 2>/dev/null || echo "/usr/lib/x86_64-linux-gnu/gio/modules") + if [ -d "$GIO_DIR" ]; then + echo "Bundling GIO modules from $GIO_DIR..." + for appdir in hub.AppDir agent.AppDir; do + mkdir -p "$appdir/usr/lib/gio/modules" + cp "$GIO_DIR"/*.so "$appdir/usr/lib/gio/modules/" + done + fi + + # Bundle GDK pixbuf loaders + PIXBUF_DIR="/usr/lib/x86_64-linux-gnu/gdk-pixbuf-2.0/2.10.0" + if compgen -G "$PIXBUF_DIR/loaders/*.so" > /dev/null 2>&1; then + echo "Bundling GDK pixbuf loaders..." + for appdir in hub.AppDir agent.AppDir; do + mkdir -p "$appdir/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders" + cp "$PIXBUF_DIR/loaders"/*.so "$appdir/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders/" + GDK_PIXBUF_MODULEDIR="$appdir/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders" \ + gdk-pixbuf-query-loaders > "$appdir/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache" + done + fi - - name: Generate AppRun script + - name: Generate AppRun scripts run: | generate_apprun() { local binary_name="$1" @@ -112,12 +215,20 @@ jobs: SELF=\$(readlink -f "\$0") HERE=\${SELF%/*} APPIMAGE="\${APPIMAGE:-\$SELF}" - APP_NAME="${binary_name}" + APP_NAME="${display_name}" + BINARY_NAME="${binary_name}" DESKTOP_NAME="${desktop_name}" INSTALL_DIR="\$HOME/.local/bin" DESKTOP_DIR="\$HOME/.local/share/applications" ICON_DIR="\$HOME/.local/share/icons" + # Bundled library paths + export LD_LIBRARY_PATH="\${HERE}/usr/lib:\${LD_LIBRARY_PATH}" + export WEBKIT_EXEC_PATH="\${HERE}/usr/libexec/webkit2gtk-4.1" + export GIO_MODULE_DIR="\${HERE}/usr/lib/gio/modules" + export GDK_PIXBUF_MODULE_FILE="\${HERE}/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache" + export GSETTINGS_SCHEMA_DIR="\${HERE}/usr/share/glib-2.0/schemas" + install_app() { echo "Installing \$APP_NAME..." mkdir -p "\$INSTALL_DIR" "\$DESKTOP_DIR" "\$ICON_DIR" @@ -205,36 +316,7 @@ jobs: chmod +x "$output" } - generate_desktop() { - local binary_name="$1" - local display_name="$2" - local output="$3" - cat > "$output" << DESKTOP_EOF - [Desktop Entry] - Name=${display_name} - Comment=Deploy games to Steam Deck and Linux devices - Exec=${binary_name} - Icon=${binary_name} - Type=Application - Categories=Game;Development; - Terminal=false - DESKTOP_EOF - } - - # Hub AppDir - mkdir -p hub.AppDir/usr/bin - cp artifacts/hub/capydeploy-hub-tauri hub.AppDir/usr/bin/ - chmod +x hub.AppDir/usr/bin/capydeploy-hub-tauri - cp apps/hub-tauri/src-tauri/icons/icon.png hub.AppDir/capydeploy-hub.png - generate_desktop "capydeploy-hub" "CapyDeploy Hub" "hub.AppDir/capydeploy-hub.desktop" generate_apprun "capydeploy-hub-tauri" "capydeploy-hub" "CapyDeploy Hub" "*capydeploy*hub*.AppImage" "hub.AppDir/AppRun" - - # Agent AppDir - mkdir -p agent.AppDir/usr/bin - cp artifacts/agent/capydeploy-agent-tauri agent.AppDir/usr/bin/ - chmod +x agent.AppDir/usr/bin/capydeploy-agent-tauri - cp apps/agents/agent-tauri/src-tauri/icons/icon.png agent.AppDir/capydeploy-agent.png - generate_desktop "capydeploy-agent" "CapyDeploy Agent" "agent.AppDir/capydeploy-agent.desktop" generate_apprun "capydeploy-agent-tauri" "capydeploy-agent" "CapyDeploy Agent" "*capydeploy*agent*.AppImage" "agent.AppDir/AppRun" - name: Build AppImages diff --git a/build_all.sh b/build_all.sh index 519c4d90..240a6150 100644 --- a/build_all.sh +++ b/build_all.sh @@ -98,6 +98,17 @@ generate_appimage() { echo -e " ${GREEN}Downloaded${NC}" fi + # Download linuxdeploy if needed (for bundling shared libraries) + local linuxdeploy="$TOOLS_DIR/linuxdeploy-$appimage_arch.AppImage" + if [ ! -f "$linuxdeploy" ]; then + echo " Downloading linuxdeploy..." + mkdir -p "$TOOLS_DIR" + curl -L -o "$linuxdeploy" \ + "https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-$appimage_arch.AppImage" + chmod +x "$linuxdeploy" + echo -e " ${GREEN}Downloaded${NC}" + fi + # Create AppDir rm -rf "$appdir" mkdir -p "$appdir/usr/bin" @@ -124,6 +135,81 @@ Categories=Game;Development; Terminal=false DESKTOP + # Bundle shared libraries with linuxdeploy + echo " Bundling shared libraries..." + APPIMAGE_EXTRACT_AND_RUN=1 "$linuxdeploy" \ + --appdir "$appdir" \ + --executable "$appdir/usr/bin/$binary_name" \ + --desktop-file "$appdir/$desktop_id.desktop" \ + --icon-file "$appdir/$desktop_id.png" + + # Bundle WebKit helper processes (not detected by ldd) + local webkit_dir="" + for candidate in /usr/libexec/webkit2gtk-4.1 /usr/lib/x86_64-linux-gnu/webkit2gtk-4.1 /usr/lib64/webkit2gtk-4.1; do + if [ -d "$candidate" ]; then + webkit_dir="$candidate" + break + fi + done + if [ -n "$webkit_dir" ]; then + echo " Bundling WebKit helpers from $webkit_dir..." + mkdir -p "$appdir/usr/libexec/webkit2gtk-4.1" + cp "$webkit_dir/WebKitWebProcess" "$appdir/usr/libexec/webkit2gtk-4.1/" + cp "$webkit_dir/WebKitNetworkProcess" "$appdir/usr/libexec/webkit2gtk-4.1/" + else + echo -e " ${YELLOW}[WARN]${NC} WebKit helpers not found" + fi + + # Bundle GLib compiled schemas + if [ -f "/usr/share/glib-2.0/schemas/gschemas.compiled" ]; then + echo " Bundling GLib schemas..." + mkdir -p "$appdir/usr/share/glib-2.0/schemas" + cp /usr/share/glib-2.0/schemas/gschemas.compiled "$appdir/usr/share/glib-2.0/schemas/" + fi + + # Bundle GIO modules (TLS support) + local gio_dir + gio_dir=$(pkg-config --variable=giomoduledir gio-2.0 2>/dev/null) + if [ -z "$gio_dir" ] || [ ! -d "$gio_dir" ]; then + for candidate in /usr/lib/x86_64-linux-gnu/gio/modules /usr/lib64/gio/modules; do + if [ -d "$candidate" ]; then + gio_dir="$candidate" + break + fi + done + fi + if [ -n "$gio_dir" ] && [ -d "$gio_dir" ]; then + echo " Bundling GIO modules from $gio_dir..." + mkdir -p "$appdir/usr/lib/gio/modules" + cp "$gio_dir"/*.so "$appdir/usr/lib/gio/modules/" + fi + + # Bundle GDK pixbuf loaders + local pixbuf_module_dir + pixbuf_module_dir=$(pkg-config --variable=gdk_pixbuf_moduledir gdk-pixbuf-2.0 2>/dev/null) + local pixbuf_dir="" + if [ -n "$pixbuf_module_dir" ] && [ -d "$pixbuf_module_dir" ]; then + pixbuf_dir=$(dirname "$pixbuf_module_dir") + else + for candidate in /usr/lib/x86_64-linux-gnu/gdk-pixbuf-2.0/2.10.0 /usr/lib64/gdk-pixbuf-2.0/2.10.0; do + if [ -d "$candidate" ]; then + pixbuf_dir="$candidate" + break + fi + done + fi + if [ -n "$pixbuf_dir" ] && compgen -G "$pixbuf_dir/loaders/*.so" > /dev/null 2>&1; then + echo " Bundling GDK pixbuf loaders..." + mkdir -p "$appdir/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders" + cp "$pixbuf_dir/loaders"/*.so "$appdir/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders/" + if command -v gdk-pixbuf-query-loaders &>/dev/null; then + GDK_PIXBUF_MODULEDIR="$appdir/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders" \ + gdk-pixbuf-query-loaders > "$appdir/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache" + fi + fi + + echo -e " ${GREEN}Libraries bundled${NC}" + # Create AppRun with install/uninstall support cat > "$appdir/AppRun" << 'APPRUN' #!/bin/bash @@ -137,6 +223,13 @@ INSTALL_DIR="$HOME/.local/bin" DESKTOP_DIR="$HOME/.local/share/applications" ICON_DIR="$HOME/.local/share/icons" +# Bundled library paths +export LD_LIBRARY_PATH="${HERE}/usr/lib:${LD_LIBRARY_PATH}" +export WEBKIT_EXEC_PATH="${HERE}/usr/libexec/webkit2gtk-4.1" +export GIO_MODULE_DIR="${HERE}/usr/lib/gio/modules" +export GDK_PIXBUF_MODULE_FILE="${HERE}/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache" +export GSETTINGS_SCHEMA_DIR="${HERE}/usr/share/glib-2.0/schemas" + install_app() { echo "Installing $APP_NAME..." From 3d752ea467648e461d84eca151c639fbe31e5a3a Mon Sep 17 00:00:00 2001 From: Matias Galarza Date: Thu, 19 Feb 2026 14:06:56 -0300 Subject: [PATCH 2/5] fix: correct desktop Exec field and WebKit helper detection - generate_desktop in release.yml now uses actual binary name for Exec and desktop ID for Icon (linuxdeploy validates Exec against AppDir) - Add find-based fallback for WebKit helper detection on Ubuntu --- .github/workflows/release.yml | 16 ++++++++++++---- build_all.sh | 8 ++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f61da36c..c18f49b3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -110,13 +110,14 @@ jobs: generate_desktop() { local binary_name="$1" local display_name="$2" - local output="$3" + local desktop_id="$3" + local output="$4" cat > "$output" << DESKTOP_EOF [Desktop Entry] Name=${display_name} Comment=Deploy games to Steam Deck and Linux devices Exec=${binary_name} - Icon=${binary_name} + Icon=${desktop_id} Type=Application Categories=Game;Development; Terminal=false @@ -128,14 +129,14 @@ jobs: cp artifacts/hub/capydeploy-hub-tauri hub.AppDir/usr/bin/ chmod +x hub.AppDir/usr/bin/capydeploy-hub-tauri cp apps/hub-tauri/src-tauri/icons/icon.png hub.AppDir/capydeploy-hub.png - generate_desktop "capydeploy-hub" "CapyDeploy Hub" "hub.AppDir/capydeploy-hub.desktop" + generate_desktop "capydeploy-hub-tauri" "CapyDeploy Hub" "capydeploy-hub" "hub.AppDir/capydeploy-hub.desktop" # Agent AppDir mkdir -p agent.AppDir/usr/bin cp artifacts/agent/capydeploy-agent-tauri agent.AppDir/usr/bin/ chmod +x agent.AppDir/usr/bin/capydeploy-agent-tauri cp apps/agents/agent-tauri/src-tauri/icons/icon.png agent.AppDir/capydeploy-agent.png - generate_desktop "capydeploy-agent" "CapyDeploy Agent" "agent.AppDir/capydeploy-agent.desktop" + generate_desktop "capydeploy-agent-tauri" "CapyDeploy Agent" "capydeploy-agent" "agent.AppDir/capydeploy-agent.desktop" - name: Bundle libraries env: @@ -160,6 +161,13 @@ jobs: break fi done + # Fallback: find by binary location + if [ -z "$WEBKIT_DIR" ]; then + WKP=$(find /usr -name "WebKitWebProcess" -path "*webkit2gtk*" 2>/dev/null | head -1) + if [ -n "$WKP" ]; then + WEBKIT_DIR=$(dirname "$WKP") + fi + fi if [ -n "$WEBKIT_DIR" ]; then echo "Bundling WebKit helpers from $WEBKIT_DIR..." for appdir in hub.AppDir agent.AppDir; do diff --git a/build_all.sh b/build_all.sh index 240a6150..8ccfaf3b 100644 --- a/build_all.sh +++ b/build_all.sh @@ -151,6 +151,14 @@ DESKTOP break fi done + # Fallback: find by binary location + if [ -z "$webkit_dir" ]; then + local wkp + wkp=$(find /usr -name "WebKitWebProcess" -path "*webkit2gtk*" 2>/dev/null | head -1) + if [ -n "$wkp" ]; then + webkit_dir=$(dirname "$wkp") + fi + fi if [ -n "$webkit_dir" ]; then echo " Bundling WebKit helpers from $webkit_dir..." mkdir -p "$appdir/usr/libexec/webkit2gtk-4.1" From aa362094b9e8abb509b26b3c7eb94dd5ebe4126d Mon Sep 17 00:00:00 2001 From: Matias Galarza Date: Thu, 19 Feb 2026 14:14:33 -0300 Subject: [PATCH 3/5] fix: guard gdk-pixbuf-query-loaders and add missing CI dep - Add command -v check before gdk-pixbuf-query-loaders in release.yml - Install libgdk-pixbuf2.0-bin in appimage CI job --- .github/workflows/release.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c18f49b3..c4b9bc3d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -97,7 +97,7 @@ jobs: - name: Install system dependencies run: | sudo apt-get update - sudo apt-get install -y libwebkit2gtk-4.1-dev libgtk-3-dev + sudo apt-get install -y libwebkit2gtk-4.1-dev libgtk-3-dev libgdk-pixbuf2.0-bin - name: Download tools run: | @@ -205,8 +205,10 @@ jobs: for appdir in hub.AppDir agent.AppDir; do mkdir -p "$appdir/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders" cp "$PIXBUF_DIR/loaders"/*.so "$appdir/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders/" - GDK_PIXBUF_MODULEDIR="$appdir/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders" \ - gdk-pixbuf-query-loaders > "$appdir/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache" + if command -v gdk-pixbuf-query-loaders &>/dev/null; then + GDK_PIXBUF_MODULEDIR="$appdir/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders" \ + gdk-pixbuf-query-loaders > "$appdir/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache" + fi done fi From b668a881e67d6fc7cefe8010c266c0644b605294 Mon Sep 17 00:00:00 2001 From: Matias Galarza Date: Thu, 19 Feb 2026 14:39:30 -0300 Subject: [PATCH 4/5] fix: remove linuxdeploy AppRun symlink before writing custom AppRun linuxdeploy creates AppRun as a symlink to the binary. Writing to it via cat > follows the symlink and overwrites the actual binary with the shell script, corrupting the AppImage. --- .github/workflows/release.yml | 2 ++ build_all.sh | 2 ++ 2 files changed, 4 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c4b9bc3d..3d4791bc 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -220,6 +220,8 @@ jobs: local display_name="$3" local find_pattern="$4" local output="$5" + # Remove linuxdeploy's AppRun (symlink to binary) to avoid overwriting the binary + rm -f "$output" cat > "$output" << APPRUN_EOF #!/bin/bash SELF=\$(readlink -f "\$0") diff --git a/build_all.sh b/build_all.sh index 8ccfaf3b..77764b29 100644 --- a/build_all.sh +++ b/build_all.sh @@ -219,6 +219,8 @@ DESKTOP echo -e " ${GREEN}Libraries bundled${NC}" # Create AppRun with install/uninstall support + # Remove linuxdeploy's AppRun (symlink to binary) to avoid overwriting the binary + rm -f "$appdir/AppRun" cat > "$appdir/AppRun" << 'APPRUN' #!/bin/bash SELF=$(readlink -f "$0") From 04d7fb09d68c6b0669e6f8983dd309baf9daf275 Mon Sep 17 00:00:00 2001 From: Matias Galarza Date: Thu, 19 Feb 2026 15:35:04 -0300 Subject: [PATCH 5/5] fix: binary-patch webkit2gtk hardcoded helper paths WEBKIT_EXEC_PATH only works in developer builds of webkit2gtk. Production builds hardcode the helper path at compile time. Patch libwebkit2gtk-4.1.so.0 to replace /usr with ././ (same byte length), making paths relative. AppRun now cd's to the AppDir root so the relative paths resolve correctly. This is the same approach used by Tauri's AppImage bundler. --- .github/workflows/release.yml | 39 +++++++++++++++++++++++------------ build_all.sh | 34 ++++++++++++++++++++++-------- 2 files changed, 51 insertions(+), 22 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3d4791bc..cfcadc01 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -153,7 +153,9 @@ jobs: --desktop-file agent.AppDir/capydeploy-agent.desktop \ --icon-file agent.AppDir/capydeploy-agent.png - # Bundle WebKit helper processes (not detected by ldd) + # Bundle WebKit helpers and patch hardcoded paths in the .so + # WEBKIT_EXEC_PATH only works in developer builds, so we binary-patch + # the .so to use relative paths (././ instead of /usr). WEBKIT_DIR="" for candidate in /usr/libexec/webkit2gtk-4.1 /usr/lib/x86_64-linux-gnu/webkit2gtk-4.1; do if [ -d "$candidate" ]; then @@ -161,23 +163,31 @@ jobs: break fi done - # Fallback: find by binary location if [ -z "$WEBKIT_DIR" ]; then WKP=$(find /usr -name "WebKitWebProcess" -path "*webkit2gtk*" 2>/dev/null | head -1) if [ -n "$WKP" ]; then WEBKIT_DIR=$(dirname "$WKP") fi fi - if [ -n "$WEBKIT_DIR" ]; then - echo "Bundling WebKit helpers from $WEBKIT_DIR..." - for appdir in hub.AppDir agent.AppDir; do - mkdir -p "$appdir/usr/libexec/webkit2gtk-4.1" - cp "$WEBKIT_DIR/WebKitWebProcess" "$appdir/usr/libexec/webkit2gtk-4.1/" - cp "$WEBKIT_DIR/WebKitNetworkProcess" "$appdir/usr/libexec/webkit2gtk-4.1/" - done - else - echo "::warning::WebKit helpers not found" - fi + + for appdir in hub.AppDir agent.AppDir; do + WEBKIT_HARDCODED=$(strings "$appdir/usr/lib/libwebkit2gtk-4.1.so.0" 2>/dev/null | grep -m1 '/webkit2gtk-4.1$') + if [ -n "$WEBKIT_DIR" ] && [ -n "$WEBKIT_HARDCODED" ]; then + WEBKIT_RELATIVE="././${WEBKIT_HARDCODED#/usr}" + echo "Patching $appdir WebKit path: $WEBKIT_HARDCODED -> $WEBKIT_RELATIVE" + LC_ALL=C sed -i "s|$WEBKIT_HARDCODED|$WEBKIT_RELATIVE|g" "$appdir/usr/lib/libwebkit2gtk-4.1.so.0" + # Copy helpers to the relative path the patched .so expects + HELPERS_DEST="$appdir${WEBKIT_HARDCODED#/usr}" + mkdir -p "$HELPERS_DEST" + cp "$WEBKIT_DIR/WebKitWebProcess" "$HELPERS_DEST/" + cp "$WEBKIT_DIR/WebKitNetworkProcess" "$HELPERS_DEST/" + if [ -d "$WEBKIT_DIR/injected-bundle" ]; then + cp -r "$WEBKIT_DIR/injected-bundle" "$HELPERS_DEST/" + fi + else + echo "::warning::WebKit helpers or library not found for $appdir" + fi + done # Bundle GLib compiled schemas if [ -f "/usr/share/glib-2.0/schemas/gschemas.compiled" ]; then @@ -236,11 +246,14 @@ jobs: # Bundled library paths export LD_LIBRARY_PATH="\${HERE}/usr/lib:\${LD_LIBRARY_PATH}" - export WEBKIT_EXEC_PATH="\${HERE}/usr/libexec/webkit2gtk-4.1" export GIO_MODULE_DIR="\${HERE}/usr/lib/gio/modules" export GDK_PIXBUF_MODULE_FILE="\${HERE}/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache" export GSETTINGS_SCHEMA_DIR="\${HERE}/usr/share/glib-2.0/schemas" + # WebKit helpers use paths patched to be relative (././ prefix), + # so we must cd to the AppDir root for them to resolve correctly. + cd "\${HERE}" + install_app() { echo "Installing \$APP_NAME..." mkdir -p "\$INSTALL_DIR" "\$DESKTOP_DIR" "\$ICON_DIR" diff --git a/build_all.sh b/build_all.sh index 77764b29..836e9aeb 100644 --- a/build_all.sh +++ b/build_all.sh @@ -143,7 +143,12 @@ DESKTOP --desktop-file "$appdir/$desktop_id.desktop" \ --icon-file "$appdir/$desktop_id.png" - # Bundle WebKit helper processes (not detected by ldd) + # Bundle WebKit helper processes and patch hardcoded paths + # WebKit hardcodes the helper path at compile time and WEBKIT_EXEC_PATH + # only works in developer builds. We must binary-patch the .so to use + # relative paths (././ instead of /usr) and cd to AppDir before exec. + local webkit_hardcoded + webkit_hardcoded=$(strings "$appdir/usr/lib/libwebkit2gtk-4.1.so.0" 2>/dev/null | grep -m1 '/webkit2gtk-4.1$') local webkit_dir="" for candidate in /usr/libexec/webkit2gtk-4.1 /usr/lib/x86_64-linux-gnu/webkit2gtk-4.1 /usr/lib64/webkit2gtk-4.1; do if [ -d "$candidate" ]; then @@ -151,7 +156,6 @@ DESKTOP break fi done - # Fallback: find by binary location if [ -z "$webkit_dir" ]; then local wkp wkp=$(find /usr -name "WebKitWebProcess" -path "*webkit2gtk*" 2>/dev/null | head -1) @@ -159,13 +163,22 @@ DESKTOP webkit_dir=$(dirname "$wkp") fi fi - if [ -n "$webkit_dir" ]; then - echo " Bundling WebKit helpers from $webkit_dir..." - mkdir -p "$appdir/usr/libexec/webkit2gtk-4.1" - cp "$webkit_dir/WebKitWebProcess" "$appdir/usr/libexec/webkit2gtk-4.1/" - cp "$webkit_dir/WebKitNetworkProcess" "$appdir/usr/libexec/webkit2gtk-4.1/" + if [ -n "$webkit_dir" ] && [ -n "$webkit_hardcoded" ]; then + local webkit_relative="././${webkit_hardcoded#/usr}" + echo " Patching WebKit path: $webkit_hardcoded -> $webkit_relative" + LC_ALL=C sed -i "s|$webkit_hardcoded|$webkit_relative|g" "$appdir/usr/lib/libwebkit2gtk-4.1.so.0" + # Copy helpers to the relative path that the patched .so expects + local helpers_dest="$appdir${webkit_hardcoded#/usr}" + mkdir -p "$helpers_dest" + cp "$webkit_dir/WebKitWebProcess" "$helpers_dest/" + cp "$webkit_dir/WebKitNetworkProcess" "$helpers_dest/" + # Copy injected bundle if present + if [ -d "$webkit_dir/injected-bundle" ]; then + cp -r "$webkit_dir/injected-bundle" "$helpers_dest/" + fi + echo " Bundling WebKit helpers from $webkit_dir" else - echo -e " ${YELLOW}[WARN]${NC} WebKit helpers not found" + echo -e " ${YELLOW}[WARN]${NC} WebKit helpers or library not found" fi # Bundle GLib compiled schemas @@ -235,11 +248,14 @@ ICON_DIR="$HOME/.local/share/icons" # Bundled library paths export LD_LIBRARY_PATH="${HERE}/usr/lib:${LD_LIBRARY_PATH}" -export WEBKIT_EXEC_PATH="${HERE}/usr/libexec/webkit2gtk-4.1" export GIO_MODULE_DIR="${HERE}/usr/lib/gio/modules" export GDK_PIXBUF_MODULE_FILE="${HERE}/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache" export GSETTINGS_SCHEMA_DIR="${HERE}/usr/share/glib-2.0/schemas" +# WebKit helpers use paths patched to be relative (././ prefix), +# so we must cd to the AppDir root for them to resolve correctly. +cd "${HERE}" + install_app() { echo "Installing $APP_NAME..."