From 5af66cf8fcafdc016affc989fee9c5c526ec2468 Mon Sep 17 00:00:00 2001 From: komaruworld Date: Mon, 24 Aug 2026 16:01:18 +0300 Subject: [PATCH] Add AnyLinux build Close #31 --- .github/workflows/packages.yml | 77 +++++++++++++++++------- Makefile | 15 ++--- packaging/AppRun | 14 ++++- packaging/mocktail-launcher.sh | 62 +++++++++++++------ scripts/package_portable.sh | 105 +++++++++++++++++++++++++++++++-- tests/appimage_apprun_test.sh | 17 ++++++ tests/native_packaging_test.sh | 4 +- 7 files changed, 239 insertions(+), 55 deletions(-) diff --git a/.github/workflows/packages.yml b/.github/workflows/packages.yml index dff3bc4..a0c705e 100644 --- a/.github/workflows/packages.yml +++ b/.github/workflows/packages.yml @@ -33,7 +33,7 @@ concurrency: jobs: appimage: - name: AppImage (Ubuntu 26.04) + name: AppImage (AnyLinux) runs-on: ubuntu-24.04 timeout-minutes: 90 steps: @@ -49,29 +49,57 @@ jobs: docker run --rm \ --volume "$GITHUB_WORKSPACE:/workspace" \ --workdir /workspace \ - ubuntu:26.04 bash -Eeuo pipefail -c ' - export DEBIAN_FRONTEND=noninteractive - apt-get update - apt-get install --yes --no-install-recommends \ - build-essential cmake git ninja-build pkg-config lld \ - libsdl3-dev libsdl3-ttf-dev libcurl4-openssl-dev \ - libssl-dev nlohmann-json3-dev libyaml-dev libelf-dev \ - libminizip-dev libcapstone-dev libgtk-4-dev \ - libadwaita-1-dev libwebkitgtk-6.0-dev libutf8proc-dev \ - libfontconfig1-dev libegl-dev libvulkan-dev zlib1g-dev \ - libplacebo-dev \ - bubblewrap xdg-dbus-proxy patchelf jq unzip file curl \ - ca-certificates default-jdk-headless libgif7 python3 \ - python3-capstone python3-yaml python3-requests \ - python3-urllib3 python3-certifi python3-charset-normalizer \ - python3-idna squashfs-tools + archlinux:base-devel bash -Eeuo pipefail -c ' + pacman -Syu --noconfirm --needed \ + cmake git ninja pkgconf lld sdl3 sdl3_ttf curl openssl \ + nlohmann-json libyaml libelf minizip-ng capstone gtk4 \ + libadwaita webkitgtk-6.0 libutf8proc fontconfig libglvnd \ + vulkan-headers zlib libplacebo bubblewrap xdg-dbus-proxy \ + patchelf jq unzip file ca-certificates jdk-openjdk giflib \ + python python-capstone python-yaml python-requests \ + python-urllib3 python-certifi python-charset-normalizer \ + python-idna dbus + + curl --fail --location --retry 3 \ + --output /tmp/quick-sharun \ + https://raw.githubusercontent.com/pkgforge-dev/Anylinux-AppImages/2a025cef14483c5bc2a75b479071f4d5c58a906f/useful-tools/quick-sharun.sh + echo "fa66d0189e1e87df781c049dfb23cbb1e753786056f693a4483d6d3af61e7ee1 /tmp/quick-sharun" | \ + sha256sum --check --strict + chmod 0755 /tmp/quick-sharun + + curl --fail --location --retry 3 \ + --output /tmp/sharun \ + https://github.com/pkgforge-dev/Anylinux-sharun/releases/download/2.2.6/sharun-x86_64 + echo "a4d51752f9861b4870ca529fea04087310b28f8943cc55b99a95b777d4db92ec /tmp/sharun" | \ + sha256sum --check --strict + chmod 0755 /tmp/sharun + + curl --fail --location --retry 3 \ + --output /tmp/anylinux.c \ + https://raw.githubusercontent.com/pkgforge-dev/Anylinux-AppImages/2a025cef14483c5bc2a75b479071f4d5c58a906f/useful-tools/lib/anylinux.c + echo "f50650ad96d177559bdd0737df509fa20bd4af08887631c738fc1f31bfac185f /tmp/anylinux.c" | \ + sha256sum --check --strict curl --fail --location --retry 3 \ --output /tmp/appimagetool \ - https://github.com/AppImage/appimagetool/releases/download/1.9.1/appimagetool-x86_64.AppImage - echo "ed4ce84f0d9caff66f50bcca6ff6f35aae54ce8135408b3fa33abfc3cb384eb0 /tmp/appimagetool" | \ + https://github.com/pkgforge-dev/appimagetool/releases/download/0.3.3/appimagetool-x86_64-linux + echo "0d01a4e2628efc897be9663f0faeed6a171e1851270b4e1ce4c22434a36ecebd /tmp/appimagetool" | \ sha256sum --check --strict - install -m 0755 /tmp/appimagetool /usr/local/bin/appimagetool + chmod 0755 /tmp/appimagetool + + curl --fail --location --retry 3 \ + --output /tmp/uruntime \ + https://github.com/VHSgunzo/uruntime/releases/download/v0.5.9/uruntime-appimage-dwarfs-lite-x86_64 + echo "cef962c299f2fa19b2b3cdf2fa1565ee8541796cc89b9a97a591f94041e8b083 /tmp/uruntime" | \ + sha256sum --check --strict + chmod 0755 /tmp/uruntime + + curl --fail --location --retry 3 \ + --output /tmp/mkdwarfs \ + https://github.com/mhx/dwarfs/releases/download/v0.15.6/dwarfs-universal-0.15.6-Linux-x86_64 + echo "50891c38ba359db8271819a6cbf6aaa8068681523f0c4f2b8242007a45edaa28 /tmp/mkdwarfs" | \ + sha256sum --check --strict + chmod 0755 /tmp/mkdwarfs curl --fail --location --retry 3 \ --output /tmp/android-build-tools.zip \ @@ -85,11 +113,16 @@ jobs: git config --global --add safe.directory /workspace git config --global --add safe.directory /workspace/third_party/Vulkan-Headers git config --global --add safe.directory /workspace/third_party/libjnivm - export APPIMAGE_EXTRACT_AND_RUN=1 export MOCKTAIL_ANDROID_BUILD_TOOLS_ROOT="$android_tools_root" + export MOCKTAIL_ANYLINUX_SHARUN=/tmp/sharun + export MOCKTAIL_ANYLINUX_C_SOURCE=/tmp/anylinux.c + export RUNTIME=/tmp/uruntime + export DWARFS_CMD=/tmp/mkdwarfs make appimage BUILD_DIR=build-appimage JOBS=4 \ APPIMAGE=dist/Mocktail-x86_64.AppImage \ - PORTABLE_MODE=standalone + PORTABLE_MODE=standalone APPIMAGE_FORMAT=anylinux \ + ANYLINUX_PACKAGER=/tmp/quick-sharun \ + ANYLINUX_APPIMAGETOOL=/tmp/appimagetool test -x dist/Mocktail-x86_64.AppImage ' diff --git a/Makefile b/Makefile index e70f861..92f07bc 100644 --- a/Makefile +++ b/Makefile @@ -14,6 +14,9 @@ PORTABLE_MODE ?= standalone PORTABLE_CANONICAL_MODE := $(if $(filter dynamic minimal,$(PORTABLE_MODE)),thin,$(if $(filter full static,$(PORTABLE_MODE)),standalone,$(PORTABLE_MODE))) PORTABLE_DIR ?= dist/mocktail-linux-x86_64-glibc-$(PORTABLE_CANONICAL_MODE) APPIMAGE ?= dist/Mocktail-x86_64.AppImage +APPIMAGE_FORMAT ?= classic +ANYLINUX_PACKAGER ?= quick-sharun +ANYLINUX_APPIMAGETOOL ?= appimagetool PREFIX ?= /usr FLATPAK_BUILD_DIR ?= build-flatpak FLATPAK_MANIFEST ?= packaging/flatpak/space.bigrat.mocktail.json @@ -73,13 +76,11 @@ portable-test: release-runtime ## Verify portable packaging and relocation standalone: appimage ## Build the standalone x86-64 AppImage -appimage: release-runtime ## Build AppImage (requires appimagetool) - @command -v appimagetool >/dev/null 2>&1 || { \ - echo "appimagetool is required for make appimage" >&2; \ - echo "Install it, then rerun make appimage." >&2; \ - exit 1; \ - } - @./scripts/package_portable.sh --build-dir "$(BUILD_DIR)" \ +appimage: release-runtime ## Build AppImage (APPIMAGE_FORMAT=classic|anylinux) + @MOCKTAIL_APPIMAGE_FORMAT="$(APPIMAGE_FORMAT)" \ + MOCKTAIL_ANYLINUX_PACKAGER="$(ANYLINUX_PACKAGER)" \ + MOCKTAIL_ANYLINUX_APPIMAGETOOL="$(ANYLINUX_APPIMAGETOOL)" \ + ./scripts/package_portable.sh --build-dir "$(BUILD_DIR)" \ --libc glibc --output "$(PORTABLE_DIR)" --mode "$(PORTABLE_MODE)" \ --appimage "$(APPIMAGE)" diff --git a/packaging/AppRun b/packaging/AppRun index 71ec299..774a9bb 100755 --- a/packaging/AppRun +++ b/packaging/AppRun @@ -1,8 +1,16 @@ -#!/usr/bin/env bash +#!/bin/sh # Copyright 2026 Mocktail Project Authors # SPDX-License-Identifier: Apache-2.0 -set -euo pipefail +set -eu + +APPDIR="${APPDIR:-$(CDPATH= cd -P "$(dirname -- "$0")" && pwd)}" + +if [ -n "${SHARUN_DIR:-}" ] && [ -x "${APPDIR}/bin/bash" ]; then + export MOCKTAIL_ANYLINUX_BIN_DIR="${APPDIR}/bin" + export MOCKTAIL_BUNDLE_ROOT="${APPDIR}/usr/share/mocktail-bundle" + exec "${APPDIR}/bin/bash" \ + "${MOCKTAIL_BUNDLE_ROOT}/mocktail/scripts/portable_launcher.sh" "$@" +fi -APPDIR="${APPDIR:-$(cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)}" exec "${APPDIR}/usr/share/mocktail-bundle/run.sh" "$@" diff --git a/packaging/mocktail-launcher.sh b/packaging/mocktail-launcher.sh index abeb09b..3f437ed 100755 --- a/packaging/mocktail-launcher.sh +++ b/packaging/mocktail-launcher.sh @@ -27,20 +27,36 @@ else BUNDLE_ROOT="$(cd -P -- "${LAUNCHER_DIR}/../.." && pwd)" fi RUNTIME_ROOT="${BUNDLE_ROOT}/mocktail" -BIN_DIR="${RUNTIME_ROOT}/bin" +BUNDLED_BIN_DIR="${RUNTIME_ROOT}/bin" +ANYLINUX_BIN_DIR="${MOCKTAIL_ANYLINUX_BIN_DIR:-}" +if [[ -n "${ANYLINUX_BIN_DIR}" ]]; then + [[ "${ANYLINUX_BIN_DIR}" == /* && -d "${ANYLINUX_BIN_DIR}" ]] || { + printf 'mocktail: invalid AnyLinux binary directory: %s\n' \ + "${ANYLINUX_BIN_DIR}" >&2 + exit 1 + } + BIN_DIR="${ANYLINUX_BIN_DIR}" +else + BIN_DIR="${BUNDLED_BIN_DIR}" +fi MAIN_BINARY="${BIN_DIR}/mocktail" UPDATE_HELPER="${BIN_DIR}/mocktail_updater" FAILURE_DIALOG_HELPER="${BIN_DIR}/mocktail_failure_dialog" WEBVIEW_HELPER="${BIN_DIR}/mocktail_webview_helper" -FREEBSD_SOCKET_HELPER="${BIN_DIR}/mocktail_freebsd_socket_helper" +FREEBSD_SOCKET_HELPER="${BUNDLED_BIN_DIR}/mocktail_freebsd_socket_helper" ANDROID_BUILD_TOOLS="${RUNTIME_ROOT}/runtime/android-tools/bin" +ANDROID_TOOL_EXEC_DIR="${ANYLINUX_BIN_DIR:-${ANDROID_BUILD_TOOLS}}" METADATA_DIR="${RUNTIME_ROOT}/metadata" ABI_MANIFEST="${METADATA_DIR}/ABI.txt" DEPENDENCY_MANIFEST="${METADATA_DIR}/DEPENDENCIES.txt" CHECKSUM_MANIFEST="${METADATA_DIR}/SHA256SUMS.txt" SUPPORT_ROOT="${RUNTIME_ROOT}/runtime" -SUPPORT_BIN="${SUPPORT_ROOT}/bin" -export PATH="${SUPPORT_BIN}:${ANDROID_BUILD_TOOLS}:${PATH}" +if [[ -n "${ANYLINUX_BIN_DIR}" ]]; then + SUPPORT_BIN="${ANYLINUX_BIN_DIR}" +else + SUPPORT_BIN="${SUPPORT_ROOT}/bin" +fi +export PATH="${BIN_DIR}:${SUPPORT_BIN}:${ANDROID_BUILD_TOOLS}:${PATH}" export LD_LIBRARY_PATH="${RUNTIME_ROOT}/lib${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}" export MOCKTAIL_FREEBSD_SOCKET_HELPER="${FREEBSD_SOCKET_HELPER}" @@ -209,11 +225,16 @@ ConfigureStandaloneEnvironment() { export JAVA_HOME="${SUPPORT_ROOT}/jre" export SSL_CERT_FILE="${SUPPORT_ROOT}/share/ca-certificates/ca-bundle.crt" export REQUESTS_CA_BUNDLE="${SSL_CERT_FILE}" - export WEBKIT_EXEC_PATH="${RUNTIME_ROOT}/${webkit6_exec}" + if [[ -n "${ANYLINUX_BIN_DIR}" ]]; then + export WEBKIT_EXEC_PATH="${ANYLINUX_BIN_DIR}" + export GST_PLUGIN_SCANNER="${ANYLINUX_BIN_DIR}/gst-plugin-scanner" + else + export WEBKIT_EXEC_PATH="${RUNTIME_ROOT}/${webkit6_exec}" + export GST_PLUGIN_SCANNER="${RUNTIME_ROOT}/${gst_scanner}" + fi export WEBKIT_INJECTED_BUNDLE_PATH="$(dirname -- \ "${RUNTIME_ROOT}/${webkit6_bundle}")" export GST_PLUGIN_PATH_1_0="${RUNTIME_ROOT}/${gst_plugins}" - export GST_PLUGIN_SCANNER="${RUNTIME_ROOT}/${gst_scanner}" export GIO_EXTRA_MODULES="${RUNTIME_ROOT}/${gio_modules}" export GIO_USE_TLS="${gio_tls}" export GDK_PIXBUF_MODULE_FILE="${RUNTIME_ROOT}/${pixbuf_cache}" @@ -227,6 +248,7 @@ ConfigureStandaloneEnvironment() { EnterStandaloneNamespace() { [[ "${ABI_MODE}" == standalone && + -z "${ANYLINUX_BIN_DIR}" && "${MOCKTAIL_STANDALONE_NAMESPACE:-0}" != 1 && "${MOCKTAIL_SKIP_NAMESPACE_CHECK:-0}" != 1 ]] || return 0 local namespace_usr="${RUNTIME_ROOT}/namespace/usr" @@ -345,12 +367,14 @@ CheckBundleAbi() { [[ "$(uname -m)" == "${ABI_ARCHITECTURE}" ]] || Die "bundle requires ${ABI_ARCHITECTURE}, host is $(uname -m)" local main_interpreter host_libc - main_interpreter="$(ReadElfInterpreter "${MAIN_BINARY}")" + main_interpreter="$(ReadElfInterpreter "${BUNDLED_BIN_DIR}/mocktail")" [[ "${main_interpreter}" == "${ABI_INTERPRETER}" ]] || Die "mocktail ELF interpreter does not match ABI.txt (expected ${ABI_INTERPRETER}, found ${main_interpreter:-none})" - ValidateBundledElfAbi "${MAIN_BINARY}" "mocktail" - ValidateBundledElfAbi "${UPDATE_HELPER}" "Mocktail updater" - ValidateBundledElfAbi "${WEBVIEW_HELPER}" "WebView helper" + ValidateBundledElfAbi "${BUNDLED_BIN_DIR}/mocktail" "mocktail" + ValidateBundledElfAbi "${BUNDLED_BIN_DIR}/mocktail_updater" \ + "Mocktail updater" + ValidateBundledElfAbi "${BUNDLED_BIN_DIR}/mocktail_webview_helper" \ + "WebView helper" [[ -x "${ANDROID_BUILD_TOOLS}/aapt" ]] || Die "Android APK metadata tool is unavailable" if [[ "${ABI_ANDROID_TOOLS_LIBC}" == java ]]; then @@ -361,11 +385,13 @@ CheckBundleAbi() { "Android aapt" glibc fi - host_libc="$(DetectHostLibc)" - [[ "${host_libc}" != unknown ]] || - Die "cannot determine host libc ABI; install working getconf or ldd" - [[ "${host_libc}" == "${ABI_LIBC}" ]] || - Die "bundle targets ${ABI_LIBC}, but host libc is ${host_libc}; use a Mocktail x86-64 ${host_libc} AppImage" + if [[ -z "${ANYLINUX_BIN_DIR}" ]]; then + host_libc="$(DetectHostLibc)" + [[ "${host_libc}" != unknown ]] || + Die "cannot determine host libc ABI; install working getconf or ldd" + [[ "${host_libc}" == "${ABI_LIBC}" ]] || + Die "bundle targets ${ABI_LIBC}, but host libc is ${host_libc}; use a Mocktail x86-64 ${host_libc} AppImage" + fi } CheckCommand() { @@ -428,16 +454,16 @@ CheckSystem() { status=1 fi fi - if ! "${ANDROID_BUILD_TOOLS}/aapt" version >/dev/null 2>&1; then + if ! "${ANDROID_TOOL_EXEC_DIR}/aapt" version >/dev/null 2>&1; then printf ' bundled Android APK analyzer cannot execute\n' >&2 status=1 fi if [[ "${ABI_ANDROID_TOOLS_LIBC}" == java ]] && - ! "${ANDROID_BUILD_TOOLS}/apkanalyzer" --help >/dev/null 2>&1; then + ! "${ANDROID_TOOL_EXEC_DIR}/apkanalyzer" --help >/dev/null 2>&1; then printf ' bundled Android apkanalyzer cannot execute with Java\n' >&2 status=1 fi - if ! "${ANDROID_BUILD_TOOLS}/apksigner" version >/dev/null 2>&1; then + if ! "${ANDROID_TOOL_EXEC_DIR}/apksigner" version >/dev/null 2>&1; then printf ' bundled Android apksigner cannot execute with host Java\n' >&2 status=1 fi diff --git a/scripts/package_portable.sh b/scripts/package_portable.sh index e3e0780..5cf080f 100755 --- a/scripts/package_portable.sh +++ b/scripts/package_portable.sh @@ -28,6 +28,11 @@ STAGING="" APPDIR="" PACKAGING_LIBRARY_PATH="" ANDROID_TOOLS_ABI="" +APPIMAGE_FORMAT="${MOCKTAIL_APPIMAGE_FORMAT:-classic}" +ANYLINUX_PACKAGER="${MOCKTAIL_ANYLINUX_PACKAGER:-quick-sharun}" +ANYLINUX_APPIMAGETOOL="${MOCKTAIL_ANYLINUX_APPIMAGETOOL:-appimagetool}" +ANYLINUX_SHARUN="${MOCKTAIL_ANYLINUX_SHARUN:-}" +ANYLINUX_C_SOURCE="${MOCKTAIL_ANYLINUX_C_SOURCE:-}" readonly -a PROJECT_ARTIFACTS=( mocktail @@ -86,7 +91,8 @@ Options: --mode MODE standalone (default) or thin; aliases: full, static, dynamic, and legacy minimal. --dry-run Audit artifacts and dependency policy without writing. - --appimage FILE Also build FILE with appimagetool. + --appimage FILE Also build FILE. Set MOCKTAIL_APPIMAGE_FORMAT to + classic (default) or anylinux. -h, --help Show this help. standalone bundles the application userspace and support tools. thin omits @@ -165,6 +171,12 @@ ParseArguments() { Die "--mode must be standalone or thin" [[ "${TARGET_LIBC}" == glibc || "${TARGET_LIBC}" == musl ]] || Die "--libc must be glibc or musl" + [[ "${APPIMAGE_FORMAT}" == classic || + "${APPIMAGE_FORMAT}" == anylinux ]] || + Die "MOCKTAIL_APPIMAGE_FORMAT must be classic or anylinux" + if [[ "${APPIMAGE_FORMAT}" == anylinux && "${TARGET_LIBC}" != glibc ]]; then + Die "AnyLinux packaging requires a glibc build" + fi if [[ "${TARGET_LIBC}" == musl && "${MODE}" == standalone ]]; then ANDROID_TOOLS_ABI=java @@ -920,7 +932,6 @@ PublishBundle() { BuildAppImage() { local icon_path icon_relative_path [[ -n "${APPIMAGE_OUTPUT}" ]] || return 0 - RequireCommand appimagetool APPDIR="$(mktemp -d "${OUTPUT%/*}/.Mocktail.AppDir.XXXXXX")" mkdir -p "${APPDIR}/usr/share/mocktail-bundle" \ "${APPDIR}/usr/share/applications" \ @@ -949,12 +960,84 @@ BuildAppImage() { done ln -s space.bigrat.mocktail.svg "${APPDIR}/.DirIcon" mkdir -p -- "$(dirname -- "${APPIMAGE_OUTPUT}")" - ARCH=x86_64 appimagetool "${APPDIR}" "${APPIMAGE_OUTPUT}" + if [[ "${APPIMAGE_FORMAT}" == anylinux ]]; then + BuildAnyLinuxAppImage + else + ARCH=x86_64 appimagetool "${APPDIR}" "${APPIMAGE_OUTPUT}" + fi rm -rf -- "${APPDIR}" APPDIR="" Log "AppImage ready: ${APPIMAGE_OUTPUT}" } +BuildAnyLinuxAppImage() { + local apkanalyzer path + local -a inputs=( + "${APPDIR}/usr/share/mocktail-bundle/mocktail/bin/mocktail" + ) + mv -- "${APPDIR}/AppRun" "${APPDIR}/AppRun.sh" + while IFS= read -r -d '' path; do + [[ "${path}" != "${inputs[0]}" ]] || continue + [[ "${path##*/}" != "${FREEBSD_SOCKET_HELPER}" ]] || continue + IsElfFile "${path}" || continue + [[ -n "$(ReadElfInterpreter "${path}")" ]] || continue + inputs+=("${path}") + done < <(find "${APPDIR}/usr/share/mocktail-bundle" \ + \( -type f -o -type l \) -print0 | + LC_ALL=C sort -z) + + if [[ -n "${ANYLINUX_SHARUN}" ]]; then + install -m 0755 -- "${ANYLINUX_SHARUN}" "${APPDIR}/sharun" + fi + if [[ -n "${ANYLINUX_C_SOURCE}" ]]; then + mkdir -p -- "${APPDIR}/lib" + cc -shared -fPIC -O2 "${ANYLINUX_C_SOURCE}" \ + -o "${APPDIR}/lib/anylinux.so" + fi + + Log "deploying AnyLinux runtime" + APPDIR="${APPDIR}" MAIN_BIN=mocktail STRACE_MODE=0 NO_STRIP=1 \ + DEPLOY_DATADIR=0 DEPLOY_LOCALE=0 \ + "${ANYLINUX_PACKAGER}" "${inputs[@]}" + + WriteAnyLinuxScriptWrapper apksigner + apkanalyzer="${APPDIR}/usr/share/mocktail-bundle/mocktail/runtime/android-tools/bin/apkanalyzer" + if [[ -x "${apkanalyzer}" ]]; then + WriteAnyLinuxScriptWrapper apkanalyzer + fi + RefreshAnyLinuxBundleChecksums + + APPDIR="${APPDIR}" APPIMAGE_ARCH=x86_64 \ + "${ANYLINUX_APPIMAGETOOL}" "${APPDIR}" \ + --output "$(dirname -- "${APPIMAGE_OUTPUT}")" \ + --name "$(basename -- "${APPIMAGE_OUTPUT}")" +} + +WriteAnyLinuxScriptWrapper() { + local name="$1" + local wrapper="${APPDIR}/bin/${name}" + rm -f -- "${wrapper}" + cat >"${wrapper}" <"${bundle}/mocktail/metadata/SHA256SUMS.txt" +} + DryRun() { STAGING="$(mktemp -d "${TMPDIR:-/tmp}/mocktail-portable-dry-run.XXXXXX")" CollectDependencies @@ -982,7 +1065,21 @@ Main() { RequireCommand paste RequireCommand unzip if [[ -n "${APPIMAGE_OUTPUT}" ]]; then - RequireCommand appimagetool + if [[ "${APPIMAGE_FORMAT}" == anylinux ]]; then + RequireCommand "${ANYLINUX_PACKAGER}" + RequireCommand "${ANYLINUX_APPIMAGETOOL}" + if [[ -n "${ANYLINUX_SHARUN}" ]]; then + [[ -x "${ANYLINUX_SHARUN}" ]] || + Die "AnyLinux sharun is not executable: ${ANYLINUX_SHARUN}" + fi + if [[ -n "${ANYLINUX_C_SOURCE}" ]]; then + [[ -r "${ANYLINUX_C_SOURCE}" ]] || + Die "AnyLinux C source is not readable: ${ANYLINUX_C_SOURCE}" + RequireCommand cc + fi + else + RequireCommand appimagetool + fi fi BUILD_DIR="$(CanonicalDirectory "${BUILD_DIR}")" ValidateArtifacts diff --git a/tests/appimage_apprun_test.sh b/tests/appimage_apprun_test.sh index eb61511..1d852da 100644 --- a/tests/appimage_apprun_test.sh +++ b/tests/appimage_apprun_test.sh @@ -23,4 +23,21 @@ grep -Fq 'argc=2' <<<"${output}" grep -Fq 'first=--launch-uri' <<<"${output}" grep -Fq "second=${launch_uri}" <<<"${output}" +mkdir -p -- "${app_dir}/bin" \ + "${app_dir}/usr/share/mocktail-bundle/mocktail/scripts" +printf '%s\n' '#!/bin/sh' 'exec /usr/bin/bash "$@"' \ + >"${app_dir}/bin/bash" +printf '%s\n' \ + '#!/usr/bin/env bash' \ + 'printf "anylinux=%s bundle=%s first=%s\n" "${MOCKTAIL_ANYLINUX_BIN_DIR}" "${MOCKTAIL_BUNDLE_ROOT}" "$1"' \ + >"${app_dir}/usr/share/mocktail-bundle/mocktail/scripts/portable_launcher.sh" +chmod 0755 "${app_dir}/bin/bash" \ + "${app_dir}/usr/share/mocktail-bundle/mocktail/scripts/portable_launcher.sh" + +output="$(APPDIR="${app_dir}" SHARUN_DIR="${app_dir}" \ + "${app_run}" --launch-uri "${launch_uri}")" +grep -Fq "anylinux=${app_dir}/bin" <<<"${output}" +grep -Fq "bundle=${app_dir}/usr/share/mocktail-bundle" <<<"${output}" +grep -Fq 'first=--launch-uri' <<<"${output}" + printf 'AppImage AppRun test passed\n' diff --git a/tests/native_packaging_test.sh b/tests/native_packaging_test.sh index 72e2acd..ce85862 100755 --- a/tests/native_packaging_test.sh +++ b/tests/native_packaging_test.sh @@ -93,10 +93,12 @@ for expected in \ 'fedora:44' \ 'archlinux:base-devel' \ 'minizip-ng-compat-devel' \ - 'libgif7' \ + 'giflib' \ '-G DEB' \ '-G RPM' \ 'makepkg --dir' \ + 'APPIMAGE_FORMAT=anylinux' \ + 'quick-sharun' \ 'Mocktail-x86_64.AppImage' \ 'gh release upload continuous'; do grep -Fq -- "${expected}" "${WORKFLOW}" ||