diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml index f87c0556f4..0dfea9bfcd 100644 --- a/.github/workflows/create-release.yml +++ b/.github/workflows/create-release.yml @@ -221,6 +221,20 @@ jobs: chmod +x scripts/relax-deb-libicu.sh scripts/relax-deb-libicu.sh desktopApp/build/compose/binaries/main-release/deb/*.deb + # jpackage --type deb only auto-generates Depends from dpkg-shlibdeps + # against the bundled JRE under lib/runtime/, NOT the app payload under + # lib/app/. libskiko-linux-arm64.so has libEGL.so.1 in DT_NEEDED (unlike + # the x64 skiko which only links libGL.so.1), so a minimal aarch64 + # install without EGL crashes at startup with: + # UnsatisfiedLinkError: libEGL.so.1: cannot open shared object file + # Rewrite the arm64 .deb to add libegl1 to Depends. x64 .deb is untouched. + - name: Add libegl1 dep to arm64 .deb + if: matrix.family == 'linux' && matrix.arch == 'arm64' + run: | + set -euo pipefail + chmod +x scripts/add-deb-libegl-dep.sh + scripts/add-deb-libegl-dep.sh desktopApp/build/compose/binaries/main-release/deb/*.deb + - name: Build portable archives (windows + linux-portable) if: matrix.family == 'windows' || matrix.family == 'linux-portable' run: | diff --git a/scripts/add-deb-libegl-dep.sh b/scripts/add-deb-libegl-dep.sh new file mode 100755 index 0000000000..09b778052c --- /dev/null +++ b/scripts/add-deb-libegl-dep.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash +# Ensure a jpackage-built desktop .deb declares libegl1 as a runtime dep on +# arm64. +# +# Why this is needed: the compose-desktop skiko native shipped in +# ${app}/lib/app/libskiko-linux-arm64.so has libEGL.so.1 in DT_NEEDED (the +# aarch64 build uses EGL alongside GLX, unlike the x86_64 skiko which only +# links libGL.so.1). jpackage's --type deb only auto-generates Depends from +# dpkg-shlibdeps against the bundled JRE under ${app}/lib/runtime/, NOT the +# ${app}/lib/app/ tree — so libegl1 never makes it into the arm64 .deb. +# +# On most desktop Linux systems libegl1 is already installed as a transitive +# of the desktop environment. But minimal aarch64 installs (Armbian Server + +# a lightweight WM, Raspberry Pi OS Lite + LXDE, etc.) can miss it. Without +# libegl1 the app dies at startup with: +# +# Exception in thread "main" org.jetbrains.skiko.LibraryLoadException: +# Failed to loade library …/libskiko-linux-arm64.so +# Caused by: java.lang.UnsatisfiedLinkError: +# libEGL.so.1: cannot open shared object file: No such file or directory +# +# Neither jpackage nor the Compose Multiplatform 1.11 DSL exposes a way to +# override the auto-generated Depends, so we rewrite the .deb after the fact +# (same approach as scripts/relax-deb-libicu.sh). +# +# Usage: add-deb-libegl-dep.sh [ ...] +set -euo pipefail + +for deb in "$@"; do + if [[ ! -f "$deb" ]]; then + echo "skip: not a file: $deb" >&2 + continue + fi + + work="$(mktemp -d)" + trap 'rm -rf "$work"' EXIT + dpkg-deb -R "$deb" "$work/pkg" + control="$work/pkg/DEBIAN/control" + + # Only touch .debs whose payload actually contains the arm64 skiko native. + # Applying this to x64 .debs is harmless but the whole point is to be + # surgical. + if ! find "$work/pkg" -type f -name 'libskiko-linux-arm64.so' | grep -q .; then + echo "No arm64 skiko in payload, leaving as-is: $deb" + rm -rf "$work" + trap - EXIT + continue + fi + + if grep -qE '(^| )libegl1( |,|$)' "$control"; then + echo "libegl1 already in Depends, leaving as-is: $deb" + rm -rf "$work" + trap - EXIT + continue + fi + + # Append libegl1 to the Depends line. jpackage-generated lines are single + # physical lines, e.g. + # Depends: libasound2t64, ..., zlib1g + # We insert `, libegl1` before the trailing newline. + sed -i -E 's/^(Depends: .*[^,[:space:]])[[:space:]]*$/\1, libegl1/' "$control" + + dpkg-deb --root-owner-group -Zxz -b "$work/pkg" "$deb" >/dev/null + echo "Added libegl1 dep: $deb" + + rm -rf "$work" + trap - EXIT +done