diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..5ace460 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" diff --git a/.github/workflows/containers.yml b/.github/workflows/containers.yml index 8cabdd1..c1c883e 100644 --- a/.github/workflows/containers.yml +++ b/.github/workflows/containers.yml @@ -1,4 +1,4 @@ -name: Containers +name: GTK Widget Factory from containers on: [push, pull_request] @@ -8,31 +8,50 @@ jobs: matrix: gtk-version: [gtk3, gtk4] linux-distro: [debian, fedora, opensuse, ubuntu] + arch: [amd64] + include: + - gtk-version: gtk3 + linux-distro: debian + arch: 386 + - gtk-version: gtk4 + linux-distro: debian + arch: 386 - name: ${{ matrix.linux-distro }} ${{ matrix.gtk-version }} + name: ${{ matrix.linux-distro }} ${{ matrix.arch }} ${{ matrix.gtk-version }} runs-on: ubuntu-latest env: GTK_VERSION: ${{ matrix.gtk-version }} LINUX_DISTRO: ${{ matrix.linux-distro }} - ARTIFACT_DIR: "${{ github.workspace }}/AppImages" + ARCHITECTURE: ${{ matrix.arch }} + IMAGE_NAME: "linuxdeploy-plugin-${{ matrix.gtk-version }}:${{ matrix.linux-distro }}" + CONTAINER_NAME: "${{ matrix.linux-distro }}-${{ matrix.gtk-version }}" + ARTIFACT_DIR: "${{ github.workspace }}/AppImage" steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v7 + + - name: Set extra environment variables + run: | + case "${ARCHITECTURE}" in + 386) echo MACHINE="i386" >> "$GITHUB_ENV";; + amd64) echo MACHINE="x86_64" >> "$GITHUB_ENV";; + esac - name: Build container run: | - mkdir -pv "${ARTIFACT_DIR}" - buildah bud \ - --squash \ - -v "${ARTIFACT_DIR}:/AppImage:rw,z,shared" \ - -t "linuxdeploy-plugin-${GTK_VERSION}:${LINUX_DISTRO}" \ - -f "containers/${GTK_VERSION}/Dockerfile.${LINUX_DISTRO}" \ - . - - - uses: actions/upload-artifact@v2 + buildah bud --arch="${ARCHITECTURE}" --build-arg MACHINE="${MACHINE}" --tag "${IMAGE_NAME}" --file "containers/${GTK_VERSION}/Dockerfile.${LINUX_DISTRO}" . + + - name: Extract AppImage from container + run: | + mkdir --verbose --parents "${ARTIFACT_DIR}" + podman run --arch="${ARCHITECTURE}" --name "${CONTAINER_NAME}" --interactive --detach --rm --entrypoint /bin/bash "${IMAGE_NAME}" + podman cp "${CONTAINER_NAME}:/AppImage/Widget_Factory.AppImage" "${ARTIFACT_DIR}" + podman stop "${CONTAINER_NAME}" --time 0 + + - uses: actions/upload-artifact@v7 with: - name: ${{ matrix.linux-distro }} with ${{ matrix.gtk-version }} + name: ${{ matrix.gtk-version }}_${{ matrix.linux-distro }}_${{ env.MACHINE }} path: ${{ env.ARTIFACT_DIR }}/ retention-days: 30 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 122cdbd..fee292b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,4 +1,4 @@ -name: CI +name: Test plugin on: [push, pull_request] @@ -13,12 +13,12 @@ jobs: DEPLOY_GTK_VERSION: 3 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v7 - name: Setup dependencies run: | sudo apt-get update -y -qq - sudo apt-get install -y -qq libgtk-3-0 libgtk-3-dev wget tree + sudo apt-get install -y -qq dpkg-dev libgtk-3-0 libgtk-3-dev gir1.2-gtk-3.0 wget tree libgirepository1.0-dev libfuse2 - name: Download external binairies run: | diff --git a/README.md b/README.md index f7aaa8c..11de2cd 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ This plugin requires the following dependencies in order to work properly: - `pkg-config` or `pkgconf` command - librsvg2 development files - GTK development files +- GObject Introspection development files ## Usage @@ -18,6 +19,8 @@ This plugin requires the following dependencies in order to work properly: # get linuxdeploy and linuxdeploy-plugin-gtk > wget -c "https://raw.githubusercontent.com/linuxdeploy/linuxdeploy-plugin-gtk/master/linuxdeploy-plugin-gtk.sh" > wget -c "https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage" +# make them executable so that we can call them (and also, plugins called from linuxdeploy are called like binaries) +> chmod +x linuxdeploy-x86_64.AppImage linuxdeploy-plugin-gtk.sh # get list of variables > ./linuxdeploy-plugin-gtk.sh --help @@ -30,3 +33,24 @@ This plugin requires the following dependencies in order to work properly: # call through linuxdeploy > ./linuxdeploy-x86_64.AppImage --appdir AppDir --plugin gtk --output appimage --icon-file mypackage.png --desktop-file mypackage.desktop ``` + + +## How it Works + +This plugin is written in bash and goes through a series of steps to make sure +that all the libraries and other files are pulled in for GTK apps to work +properly once in the AppImage. The steps include: + +1. Detects the GTK version to use +1. Installs itself as a hook in `$APPDIR/apprun-hooks` +1. Uses `gsettings` to set a light or dark adwaita theme +1. Installs the GLib schemas and then runs `glib-compile-schemas` on them +1. Installs the GIRepository typelibs for gobject-introspection +1. Copies the GTK libs and sets GTK path related environmental variables to +1 locations in the APPDIR +1. Updates the input method module registration (immodules) cache +1. Installs the GDK Pixbuf libraries and cache, and then updates the cache +1 using gdk-pixbuf-query-loaders +1. Installs additional libraries including Gdk, GObject, Gio, librsvg, Pango, +1 PangoCairo, and PangoFT2 +1. Manually sets the RPATH for the GTK modules diff --git a/containers/gtk3/Dockerfile.debian b/containers/gtk3/Dockerfile.debian index 64b5e09..66ea9f4 100644 --- a/containers/gtk3/Dockerfile.debian +++ b/containers/gtk3/Dockerfile.debian @@ -2,15 +2,17 @@ FROM docker.io/debian:buster AS build-stage WORKDIR /linuxdeploy ENV APPIMAGE_EXTRACT_AND_RUN=1 ENV DEBIAN_FRONTEND=noninteractive +ARG MACHINE=x86_64 ARG APPDIR=/AppDir ARG TZ=UTC RUN ln -snf "/usr/share/zoneinfo/$TZ" "/etc/localtime" && echo "$TZ" > /etc/timezone RUN apt-get update && \ - apt-get install -y wget librsvg2-dev file findutils pkg-config libgtk-3-0 libgtk-3-dev gtk-3-examples + apt-get install -y dpkg-dev wget librsvg2-dev file findutils pkg-config libgtk-3-0 \ + libgtk-3-dev gtk-3-examples gir1.2-gtk-3.0 libgirepository1.0-dev COPY . . -ADD "https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage" . -RUN chmod +x *.sh *.AppImage -RUN ./linuxdeploy-x86_64.AppImage \ +ADD "https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-${MACHINE}.AppImage" "linuxdeploy-${MACHINE}.AppImage" +RUN chmod --verbose +x *.sh *.AppImage +RUN ./linuxdeploy-${MACHINE}.AppImage \ --appdir ${APPDIR} \ --plugin gtk \ --output appimage \ @@ -22,5 +24,6 @@ FROM docker.io/debian:buster VOLUME ["/AppImage"] WORKDIR /AppImage ENV APPIMAGE_EXTRACT_AND_RUN=1 -COPY --from=build-stage "/linuxdeploy/Widget_Factory-x86_64.AppImage" . -ENTRYPOINT ["./Widget_Factory-x86_64.AppImage"] +ARG MACHINE=x86_64 +COPY --from=build-stage "/linuxdeploy/Widget_Factory-${MACHINE}.AppImage" "./Widget_Factory.AppImage" +ENTRYPOINT ["./Widget_Factory.AppImage"] diff --git a/containers/gtk3/Dockerfile.fedora b/containers/gtk3/Dockerfile.fedora index d15f4b0..0bc849a 100644 --- a/containers/gtk3/Dockerfile.fedora +++ b/containers/gtk3/Dockerfile.fedora @@ -1,13 +1,15 @@ FROM docker.io/fedora:latest AS build-stage WORKDIR /linuxdeploy ENV APPIMAGE_EXTRACT_AND_RUN=1 +ARG MACHINE=x86_64 ARG APPDIR=/AppDir -RUN dnf install -y wget librsvg2-devel file findutils pkgconfig gtk3 gtk3-devel +RUN dnf install -y wget librsvg2-devel file findutils pkgconfig gtk3 gtk3-devel \ + gobject-introspection-devel COPY . . -ADD "https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage" . -RUN chmod +x *.sh *.AppImage +ADD "https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-${MACHINE}.AppImage" . +RUN chmod --verbose +x *.sh *.AppImage RUN gtk-query-immodules-3.0-64 --update-cache -RUN ./linuxdeploy-x86_64.AppImage \ +RUN ./linuxdeploy-${MACHINE}.AppImage \ --appdir ${APPDIR} \ --plugin gtk \ --output appimage \ @@ -19,5 +21,6 @@ FROM docker.io/fedora:latest VOLUME ["/AppImage"] WORKDIR /AppImage ENV APPIMAGE_EXTRACT_AND_RUN=1 -COPY --from=build-stage "/linuxdeploy/Widget_Factory-x86_64.AppImage" . -ENTRYPOINT ["./Widget_Factory-x86_64.AppImage"] +ARG MACHINE=x86_64 +COPY --from=build-stage "/linuxdeploy/Widget_Factory-${MACHINE}.AppImage" "./Widget_Factory.AppImage" +ENTRYPOINT ["./Widget_Factory.AppImage"] diff --git a/containers/gtk3/Dockerfile.opensuse b/containers/gtk3/Dockerfile.opensuse index fdb1f43..e34157e 100644 --- a/containers/gtk3/Dockerfile.opensuse +++ b/containers/gtk3/Dockerfile.opensuse @@ -1,12 +1,14 @@ FROM docker.io/opensuse/leap:15 AS build-stage WORKDIR /linuxdeploy ENV APPIMAGE_EXTRACT_AND_RUN=1 +ARG MACHINE=x86_64 ARG APPDIR=/AppDir -RUN zypper install -y wget librsvg2-devel file findutils pkg-config gtk3 gtk3-devel +RUN zypper install -y wget librsvg2-devel file findutils pkg-config gtk3 gtk3-devel \ + typelib-1_0-Gtk-3_0 gobject-introspection-devel COPY . . -ADD "https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage" . -RUN chmod +x *.sh *.AppImage -RUN ./linuxdeploy-x86_64.AppImage \ +ADD "https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-${MACHINE}.AppImage" . +RUN chmod --verbose +x *.sh *.AppImage +RUN ./linuxdeploy-${MACHINE}.AppImage \ --appdir ${APPDIR} \ --plugin gtk \ --output appimage \ @@ -18,5 +20,6 @@ FROM docker.io/opensuse/leap:15 VOLUME ["/AppImage"] WORKDIR /AppImage ENV APPIMAGE_EXTRACT_AND_RUN=1 -COPY --from=build-stage "/linuxdeploy/Widget_Factory-x86_64.AppImage" . -ENTRYPOINT ["./Widget_Factory-x86_64.AppImage"] +ARG MACHINE=x86_64 +COPY --from=build-stage "/linuxdeploy/Widget_Factory-${MACHINE}.AppImage" "./Widget_Factory.AppImage" +ENTRYPOINT ["./Widget_Factory.AppImage"] diff --git a/containers/gtk3/Dockerfile.ubuntu b/containers/gtk3/Dockerfile.ubuntu index 1fd145a..aba4fbf 100644 --- a/containers/gtk3/Dockerfile.ubuntu +++ b/containers/gtk3/Dockerfile.ubuntu @@ -2,15 +2,17 @@ FROM docker.io/ubuntu:focal AS build-stage WORKDIR /linuxdeploy ENV APPIMAGE_EXTRACT_AND_RUN=1 ENV DEBIAN_FRONTEND=noninteractive +ARG MACHINE=x86_64 ARG APPDIR=/AppDir ARG TZ=UTC RUN ln -snf "/usr/share/zoneinfo/$TZ" "/etc/localtime" && echo "$TZ" > /etc/timezone RUN apt-get update && \ - apt-get install -y wget librsvg2-dev file findutils pkg-config libgtk-3-0 libgtk-3-dev gtk-3-examples + apt-get install -y dpkg-dev wget librsvg2-dev file findutils pkg-config libgtk-3-0 \ + libgtk-3-dev gtk-3-examples gir1.2-gtk-3.0 libgirepository1.0-dev libfuse2 COPY . . -ADD "https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage" . -RUN chmod +x *.sh *.AppImage -RUN ./linuxdeploy-x86_64.AppImage \ +ADD "https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-${MACHINE}.AppImage" . +RUN chmod --verbose +x *.sh *.AppImage +RUN ./linuxdeploy-${MACHINE}.AppImage \ --appdir ${APPDIR} \ --plugin gtk \ --output appimage \ @@ -22,5 +24,6 @@ FROM docker.io/ubuntu:focal VOLUME ["/AppImage"] WORKDIR /AppImage ENV APPIMAGE_EXTRACT_AND_RUN=1 -COPY --from=build-stage "/linuxdeploy/Widget_Factory-x86_64.AppImage" . -ENTRYPOINT ["./Widget_Factory-x86_64.AppImage"] +ARG MACHINE=x86_64 +COPY --from=build-stage "/linuxdeploy/Widget_Factory-${MACHINE}.AppImage" "./Widget_Factory.AppImage" +ENTRYPOINT ["./Widget_Factory.AppImage"] diff --git a/containers/gtk4/Dockerfile.debian b/containers/gtk4/Dockerfile.debian index 47e1dd9..b2d981e 100644 --- a/containers/gtk4/Dockerfile.debian +++ b/containers/gtk4/Dockerfile.debian @@ -1,18 +1,18 @@ -# GTK4 is not yet supported on Debian Stable -FROM docker.io/debian:experimental AS build-stage +FROM docker.io/debian:bookworm AS build-stage WORKDIR /linuxdeploy ENV APPIMAGE_EXTRACT_AND_RUN=1 ENV DEBIAN_FRONTEND=noninteractive +ARG MACHINE=x86_64 ARG APPDIR=/AppDir ARG TZ=UTC RUN ln -snf "/usr/share/zoneinfo/$TZ" "/etc/localtime" && echo "$TZ" > /etc/timezone RUN apt-get update && \ - apt-get install -y wget librsvg2-dev file findutils pkg-config && \ - apt-get install -y -t experimental libgtk-4-1 libgtk-4-dev gtk-4-examples + apt-get install -y dpkg-dev wget librsvg2-dev file findutils pkg-config && \ + apt-get install -y libgtk-4-1 libgtk-4-dev gtk-4-examples gir1.2-gtk-4.0 libgirepository1.0-dev COPY . . -ADD "https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage" . -RUN chmod +x *.sh *.AppImage -RUN ./linuxdeploy-x86_64.AppImage \ +ADD "https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-${MACHINE}.AppImage" . +RUN chmod --verbose +x *.sh *.AppImage +RUN ./linuxdeploy-${MACHINE}.AppImage \ --appdir ${APPDIR} \ --plugin gtk \ --output appimage \ @@ -20,9 +20,10 @@ RUN ./linuxdeploy-x86_64.AppImage \ --desktop-file /usr/share/applications/org.gtk.WidgetFactory4.desktop \ --icon-file /usr/share/icons/hicolor/scalable/apps/org.gtk.WidgetFactory4.svg -FROM docker.io/debian:experimental +FROM docker.io/debian:bookworm VOLUME ["/AppImage"] WORKDIR /AppImage ENV APPIMAGE_EXTRACT_AND_RUN=1 -COPY --from=build-stage "/linuxdeploy/Widget_Factory-x86_64.AppImage" . -ENTRYPOINT ["./Widget_Factory-x86_64.AppImage"] +ARG MACHINE=x86_64 +COPY --from=build-stage "/linuxdeploy/Widget_Factory-${MACHINE}.AppImage" "./Widget_Factory.AppImage" +ENTRYPOINT ["./Widget_Factory.AppImage"] diff --git a/containers/gtk4/Dockerfile.fedora b/containers/gtk4/Dockerfile.fedora index 7f5d506..ddb148e 100644 --- a/containers/gtk4/Dockerfile.fedora +++ b/containers/gtk4/Dockerfile.fedora @@ -1,12 +1,14 @@ FROM docker.io/fedora:latest AS build-stage WORKDIR /linuxdeploy ENV APPIMAGE_EXTRACT_AND_RUN=1 +ARG MACHINE=x86_64 ARG APPDIR=/AppDir -RUN dnf install -y wget librsvg2-devel file findutils pkgconfig gtk4 gtk4-devel gtk4-devel-tools +RUN dnf install -y wget librsvg2-devel file findutils pkgconfig gtk4 gtk4-devel gtk4-devel-tools \ + gobject-introspection-devel COPY . . -ADD "https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage" . -RUN chmod +x *.sh *.AppImage -RUN ./linuxdeploy-x86_64.AppImage \ +ADD "https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-${MACHINE}.AppImage" . +RUN chmod --verbose +x *.sh *.AppImage +RUN ./linuxdeploy-${MACHINE}.AppImage \ --appdir ${APPDIR} \ --plugin gtk \ --output appimage \ @@ -18,5 +20,6 @@ FROM docker.io/fedora:latest VOLUME ["/AppImage"] WORKDIR /AppImage ENV APPIMAGE_EXTRACT_AND_RUN=1 -COPY --from=build-stage "/linuxdeploy/Widget_Factory-x86_64.AppImage" . -ENTRYPOINT ["./Widget_Factory-x86_64.AppImage"] +ARG MACHINE=x86_64 +COPY --from=build-stage "/linuxdeploy/Widget_Factory-${MACHINE}.AppImage" "./Widget_Factory.AppImage" +ENTRYPOINT ["./Widget_Factory.AppImage"] diff --git a/containers/gtk4/Dockerfile.opensuse b/containers/gtk4/Dockerfile.opensuse index c49a890..f80af23 100644 --- a/containers/gtk4/Dockerfile.opensuse +++ b/containers/gtk4/Dockerfile.opensuse @@ -2,12 +2,14 @@ FROM docker.io/opensuse/tumbleweed:latest AS build-stage WORKDIR /linuxdeploy ENV APPIMAGE_EXTRACT_AND_RUN=1 +ARG MACHINE=x86_64 ARG APPDIR=/AppDir -RUN zypper install -y wget librsvg2-devel file findutils pkg-config gtk4 gtk4-devel +RUN zypper install -y wget librsvg2-devel file findutils pkg-config gtk4 gtk4-devel \ + typelib-1_0-Gtk-4_0 gobject-introspection-devel COPY . . -ADD "https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage" . -RUN chmod +x *.sh *.AppImage -RUN ./linuxdeploy-x86_64.AppImage \ +ADD "https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-${MACHINE}.AppImage" . +RUN chmod --verbose +x *.sh *.AppImage +RUN ./linuxdeploy-${MACHINE}.AppImage \ --appdir ${APPDIR} \ --plugin gtk \ --output appimage \ @@ -19,5 +21,6 @@ FROM docker.io/opensuse/tumbleweed:latest VOLUME ["/AppImage"] WORKDIR /AppImage ENV APPIMAGE_EXTRACT_AND_RUN=1 -COPY --from=build-stage "/linuxdeploy/Widget_Factory-x86_64.AppImage" . -ENTRYPOINT ["./Widget_Factory-x86_64.AppImage"] +ARG MACHINE=x86_64 +COPY --from=build-stage "/linuxdeploy/Widget_Factory-${MACHINE}.AppImage" "./Widget_Factory.AppImage" +ENTRYPOINT ["./Widget_Factory.AppImage"] diff --git a/containers/gtk4/Dockerfile.ubuntu b/containers/gtk4/Dockerfile.ubuntu index abac85a..a6debd1 100644 --- a/containers/gtk4/Dockerfile.ubuntu +++ b/containers/gtk4/Dockerfile.ubuntu @@ -1,16 +1,18 @@ -FROM docker.io/ubuntu:hirsute AS build-stage +FROM docker.io/ubuntu:jammy AS build-stage WORKDIR /linuxdeploy ENV APPIMAGE_EXTRACT_AND_RUN=1 ENV DEBIAN_FRONTEND=noninteractive +ARG MACHINE=x86_64 ARG APPDIR=/AppDir ARG TZ=UTC RUN ln -snf "/usr/share/zoneinfo/$TZ" "/etc/localtime" && echo "$TZ" > /etc/timezone RUN apt-get update && \ - apt-get install -y wget librsvg2-dev file findutils pkg-config libgtk-4-1 libgtk-4-dev gtk-4-examples + apt-get install -y dpkg-dev wget librsvg2-dev file findutils pkg-config libgtk-4-1 \ + libgtk-4-dev gtk-4-examples gir1.2-gtk-4.0 libgirepository1.0-dev libfuse2 COPY . . -ADD "https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage" . -RUN chmod +x *.sh *.AppImage -RUN ./linuxdeploy-x86_64.AppImage \ +ADD "https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-${MACHINE}.AppImage" . +RUN chmod --verbose +x *.sh *.AppImage +RUN ./linuxdeploy-${MACHINE}.AppImage \ --appdir ${APPDIR} \ --plugin gtk \ --output appimage \ @@ -18,9 +20,10 @@ RUN ./linuxdeploy-x86_64.AppImage \ --desktop-file /usr/share/applications/org.gtk.WidgetFactory4.desktop \ --icon-file /usr/share/icons/hicolor/scalable/apps/org.gtk.WidgetFactory4.svg -FROM docker.io/ubuntu:hirsute +FROM docker.io/ubuntu:jammy VOLUME ["/AppImage"] WORKDIR /AppImage ENV APPIMAGE_EXTRACT_AND_RUN=1 -COPY --from=build-stage "/linuxdeploy/Widget_Factory-x86_64.AppImage" . -ENTRYPOINT ["./Widget_Factory-x86_64.AppImage"] +ARG MACHINE=x86_64 +COPY --from=build-stage "/linuxdeploy/Widget_Factory-${MACHINE}.AppImage" "./Widget_Factory.AppImage" +ENTRYPOINT ["./Widget_Factory.AppImage"] diff --git a/linuxdeploy-plugin-gtk.sh b/linuxdeploy-plugin-gtk.sh index e274632..7735e3a 100755 --- a/linuxdeploy-plugin-gtk.sh +++ b/linuxdeploy-plugin-gtk.sh @@ -11,10 +11,10 @@ if [ "$DEBUG" != "" ]; then verbose="--verbose" fi -script=$(readlink -f "$0") +SCRIPT="$(basename "$(readlink -f "$0")")" show_usage() { - echo "Usage: $script --appdir " + echo "Usage: $SCRIPT --appdir " echo echo "Bundles resources for applications that use GTK into an AppDir" echo @@ -38,13 +38,13 @@ variable_is_true() { get_pkgconf_variable() { local variable="$1" local library="$2" - local default_path="$3" + local default_value="$3" - path="$("$PKG_CONFIG" --variable="$variable" "$library")" - if [ -n "$path" ]; then - echo "$path" - elif [ -n "$default_path" ]; then - echo "$default_path" + pkgconfig_ret="$("$PKG_CONFIG" --variable="$variable" "$library")" + if [ -n "$pkgconfig_ret" ]; then + echo "$pkgconfig_ret" + elif [ -n "$default_value" ]; then + echo "$default_value" else echo "$0: there is no '$variable' variable for '$library' library." > /dev/stderr echo "Please check the '$library.pc' file is present in \$PKG_CONFIG_PATH (you may need to install the appropriate -dev/-devel package)." > /dev/stderr @@ -62,6 +62,44 @@ copy_tree() { done } +copy_lib_tree() { + # The source lib directory could be /usr/lib, /usr/lib64, or /usr/lib/x86_64-linux-gnu + # Therefore, when copying lib directories, we need to transform that target path + # to a consistent /usr/lib + local src=("${@:1:$#-1}") + local dst="${*:$#}" + + for elem in "${src[@]}"; do + mkdir -p "${dst::-1}${elem/$LD_GTK_LIBRARY_PATH//usr/lib}" + pushd "$LD_GTK_LIBRARY_PATH" + cp "$(realpath --relative-to="$LD_GTK_LIBRARY_PATH" "$elem")" --archive --parents --target-directory="$dst/usr/lib" $verbose + popd + done +} + +get_triplet_path() { + if command -v dpkg-architecture > /dev/null; then + echo "/usr/lib/$(dpkg-architecture -qDEB_HOST_MULTIARCH)" + fi +} + + + +search_library_path() { + PATH_ARRAY=( + "$(get_triplet_path)" + "/usr/lib64" + "/usr/lib" + ) + + for path in "${PATH_ARRAY[@]}"; do + if [ -d "$path" ]; then + echo "$path" + return 0 + fi + done +} + search_tool() { local tool="$1" local directory="$2" @@ -71,7 +109,8 @@ search_tool() { fi PATH_ARRAY=( - "/usr/lib/$(uname -m)-linux-gnu/$directory/$tool" + "$(get_triplet_path)/$directory/$tool" + "/usr/lib64/$directory/$tool" "/usr/lib/$directory/$tool" "/usr/bin/$tool" "/usr/bin/$tool-64" @@ -119,10 +158,19 @@ if [ "$APPDIR" == "" ]; then exit 1 fi +APPDIR="$(realpath "$APPDIR")" mkdir -p "$APPDIR" # make lib64 writable again. chmod +w "$APPDIR"/usr/lib64 || true +. /etc/os-release +if [ "$ID" = "debian" ] || [ "$ID" = "ubuntu" ]; then + if ! command -v dpkg-architecture &>/dev/null; then + echo -e "$0: dpkg-architecture not found.\nInstall dpkg-dev then re-run the plugin." + exit 1 + fi +fi + if command -v pkgconf > /dev/null; then PKG_CONFIG="pkgconf" elif command -v pkg-config > /dev/null; then @@ -132,6 +180,9 @@ else exit 1 fi +# GTK's library path *must not* have a trailing slash for later parameter substitution to work properly +LD_GTK_LIBRARY_PATH="$(realpath "${LD_GTK_LIBRARY_PATH:-$(search_library_path)}")" + if ! command -v find &>/dev/null && ! type find &>/dev/null; then echo -e "$0: find not found.\nInstall findutils then re-run the plugin." exit 1 @@ -178,7 +229,15 @@ mkdir -p "$HOOKSDIR" cat > "$HOOKFILE" <<\EOF #! /usr/bin/env bash -gsettings get org.gnome.desktop.interface gtk-theme 2> /dev/null | grep -qi "dark" && GTK_THEME_VARIANT="dark" || GTK_THEME_VARIANT="light" +COLOR_SCHEME="$(dbus-send --session --dest=org.freedesktop.portal.Desktop --type=method_call --print-reply --reply-timeout=1000 /org/freedesktop/portal/desktop org.freedesktop.portal.Settings.Read 'string:org.freedesktop.appearance' 'string:color-scheme' 2> /dev/null | tail -n1 | cut -b35- | cut -d' ' -f2 || printf '')" +if [ -z "$COLOR_SCHEME" ]; then + COLOR_SCHEME="$(gsettings get org.gnome.desktop.interface color-scheme 2> /dev/null || printf '')" +fi +case "$COLOR_SCHEME" in + "1"|"'prefer-dark'") GTK_THEME_VARIANT="dark";; + "2"|"'prefer-light'") GTK_THEME_VARIANT="light";; + *) GTK_THEME_VARIANT="light";; +esac APPIMAGE_GTK_THEME="${APPIMAGE_GTK_THEME:-"Adwaita:$GTK_THEME_VARIANT"}" # Allow user to override theme (discouraged) export APPDIR="${APPDIR:-"$(dirname "$(realpath "$0")")"}" # Workaround to run extracted AppImage @@ -197,6 +256,13 @@ cat >> "$HOOKFILE" <> "$HOOKFILE" <> "$HOOKFILE" < "$APPDIR/$gtk3_immodules_cache_file" + echo "Updating immodules cache in $APPDIR/${gtk3_immodules_cache_file/$LD_GTK_LIBRARY_PATH//usr/lib}" + "$gtk3_immodules_query" > "$APPDIR/${gtk3_immodules_cache_file/$LD_GTK_LIBRARY_PATH//usr/lib}" else echo "WARNING: gtk-query-immodules-3.0 not found" fi - if [ ! -f "$APPDIR/$gtk3_immodules_cache_file" ]; then + if [ ! -f "$APPDIR/${gtk3_immodules_cache_file/$LD_GTK_LIBRARY_PATH//usr/lib}" ]; then echo "WARNING: immodules.cache file is missing" fi - sed -i "s|$gtk3_libdir/3.0.0/immodules/||g" "$APPDIR/$gtk3_immodules_cache_file" + sed -i "s|$gtk3_libdir/3.0.0/immodules/||g" "$APPDIR/${gtk3_immodules_cache_file/$LD_GTK_LIBRARY_PATH//usr/lib}" ;; 4) echo "Installing GTK 4.0 modules" gtk4_exec_prefix="$(get_pkgconf_variable "exec_prefix" "gtk4" "/usr")" gtk4_libdir="$(get_pkgconf_variable "libdir" "gtk4")/gtk-4.0" - gtk4_path="$gtk4_libdir/modules" - copy_tree "$gtk4_libdir" "$APPDIR/" + gtk4_path="$gtk4_libdir" + copy_lib_tree "$gtk4_libdir" "$APPDIR/" cat >> "$HOOKFILE" <> "$HOOKFILE" < "$APPDIR/$gdk_pixbuf_cache_file" + echo "Updating pixbuf cache in $APPDIR/${gdk_pixbuf_cache_file/$LD_GTK_LIBRARY_PATH//usr/lib}" + "$gdk_pixbuf_query" > "$APPDIR/${gdk_pixbuf_cache_file/$LD_GTK_LIBRARY_PATH//usr/lib}" else echo "WARNING: gdk-pixbuf-query-loaders not found" fi -if [ ! -f "$APPDIR/$gdk_pixbuf_cache_file" ]; then +if [ ! -f "$APPDIR/${gdk_pixbuf_cache_file/$LD_GTK_LIBRARY_PATH//usr/lib}" ]; then echo "WARNING: loaders.cache file is missing" fi -sed -i "s|$gdk_pixbuf_moduledir/||g" "$APPDIR/$gdk_pixbuf_cache_file" +sed -i "s|$gdk_pixbuf_moduledir/||g" "$APPDIR/${gdk_pixbuf_cache_file/$LD_GTK_LIBRARY_PATH//usr/lib}" echo "Copying more libraries" -gobject_libdir="$(get_pkgconf_variable "libdir" "gobject-2.0")" -gio_libdir="$(get_pkgconf_variable "libdir" "gio-2.0")" -librsvg_libdir="$(get_pkgconf_variable "libdir" "librsvg-2.0")" -pango_libdir="$(get_pkgconf_variable "libdir" "pango")" -pangocairo_libdir="$(get_pkgconf_variable "libdir" "pangocairo")" -pangoft2_libdir="$(get_pkgconf_variable "libdir" "pangoft2")" +gobject_libdir="$(get_pkgconf_variable "libdir" "gobject-2.0" "$LD_GTK_LIBRARY_PATH")" +gio_libdir="$(get_pkgconf_variable "libdir" "gio-2.0" "$LD_GTK_LIBRARY_PATH")" +librsvg_libdir="$(get_pkgconf_variable "libdir" "librsvg-2.0" "$LD_GTK_LIBRARY_PATH")" +pango_libdir="$(get_pkgconf_variable "libdir" "pango" "$LD_GTK_LIBRARY_PATH")" +pangocairo_libdir="$(get_pkgconf_variable "libdir" "pangocairo" "$LD_GTK_LIBRARY_PATH")" +pangoft2_libdir="$(get_pkgconf_variable "libdir" "pangoft2" "$LD_GTK_LIBRARY_PATH")" FIND_ARRAY=( - "$gdk_libdir" "libgdk_pixbuf-*.so*" - "$gobject_libdir" "libgobject-*.so*" - "$gio_libdir" "libgio-*.so*" - "$librsvg_libdir" "librsvg-*.so*" + "$gdk_libdir" "libgdk_pixbuf-*.so*" + "$gobject_libdir" "libgobject-*.so*" + "$gio_libdir" "libgio-*.so*" + "$librsvg_libdir" "librsvg-*.so*" "$pango_libdir" "libpango-*.so*" "$pangocairo_libdir" "libpangocairo-*.so*" "$pangoft2_libdir" "libpangoft2-*.so*" @@ -305,7 +371,7 @@ PATCH_ARRAY=( ) for directory in "${PATCH_ARRAY[@]}"; do while IFS= read -r -d '' file; do - ln $verbose -s "${file/\/usr\/lib\//}" "$APPDIR/usr/lib" + ln $verbose -sf "${file/$LD_GTK_LIBRARY_PATH\//}" "$APPDIR/usr/lib" done < <(find "$directory" -name '*.so' -print0) done