From f1d2bdee49a3130ae2502615a5f6290a8ab71822 Mon Sep 17 00:00:00 2001 From: mstrofnone Date: Wed, 5 Aug 2026 15:56:00 +1000 Subject: [PATCH] ci(release): add libegl1 to arm64 .deb Depends MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The compose-desktop skiko native shipped under ${app}/lib/app/libskiko-linux-arm64.so declares libEGL.so.1 in DT_NEEDED — the aarch64 skiko uses EGL alongside GLX, unlike the x86_64 skiko which only links libGL.so.1. jpackage --type deb only auto-generates Depends from dpkg-shlibdeps against the bundled JRE under lib/runtime/, NOT the app payload under lib/app/. As a result the arm64 .deb produced by the newly-added linux-arm64 CI leg lists libgl1/libglvnd0/libglx0 in Depends but not libegl1. On minimal aarch64 installs — Armbian Server + a lightweight WM, Raspberry Pi OS Lite + LXDE, or any distro base image without an EGL implementation pulled in transitively — Amethyst desktop crashes 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 add extra deb Depends, so we rewrite the .deb after the fact — same approach as scripts/relax-deb-libicu.sh (which handles the libicu SONAME divergence across Debian/Ubuntu releases). scripts/add-deb-libegl-dep.sh only touches .debs whose payload actually contains libskiko-linux-arm64.so, and is idempotent (skips if libegl1 is already listed). The workflow step is gated on matrix.arch == 'arm64' so the x64 .deb is untouched (its skiko does NOT NEED libEGL and its GLX-only path stays as-is). Local validation on Apple Silicon (native linux/arm64 in Docker): 1. Rebuilt v1.13.1 arm64 .deb from a110ce0a30's CI leg. 2. readelf -d libskiko-linux-arm64.so | grep NEEDED → confirms libEGL.so.1 3. Ran scripts/add-deb-libegl-dep.sh over the .deb; Depends line now ends `..., zlib1g, libegl1`. Idempotent on re-run. 4. `apt-get install -y -f ./amethyst_*.deb` in a base eclipse-temurin:21-jdk-noble aarch64 container (which lacks libegl1 by default) now pulls libegl1 as a dep. 5. Amethyst launches under Xvfb, `xwininfo -root -tree` shows the 1200×800 "Amethyst" window + Content window + sun-awt-X11-XCanvasPeer Skia canvas. No UnsatisfiedLinkError. --- .github/workflows/create-release.yml | 14 ++++++ scripts/add-deb-libegl-dep.sh | 68 ++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100755 scripts/add-deb-libegl-dep.sh 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