75 lines
3.3 KiB
Bash
Executable File
75 lines
3.3 KiB
Bash
Executable File
#!/bin/bash
|
|
# Builds Korin-Timer.AppImage as a FULLY self-contained
|
|
# bundle: its own Python interpreter + stdlib, GTK4, gtk4-layer-shell,
|
|
# PyGObject, pycairo, evdev, python-xlib, and every transitive shared
|
|
# library they need (~75 .so files) including ld.so + libc themselves.
|
|
#
|
|
# Why: this targets NixOS, which has no FHS /usr/bin/python3 or system
|
|
# GTK4 on PATH at all - "the host probably already has this" (the usual
|
|
# AppImage assumption) doesn't hold there. Bundling everything, including
|
|
# the dynamic linker, means it doesn't depend on the host's glibc version
|
|
# either.
|
|
set -euo pipefail
|
|
|
|
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
BUILD_DIR="${ROOT}/build"
|
|
APPDIR="${BUILD_DIR}/AppDir"
|
|
|
|
rm -rf "${APPDIR}"
|
|
mkdir -p "${APPDIR}/usr/lib/titletimer/src"
|
|
mkdir -p "${APPDIR}/usr/share/applications"
|
|
mkdir -p "${APPDIR}/usr/share/icons/hicolor/64x64/apps"
|
|
mkdir -p "${APPDIR}/usr/share/icons/hicolor/128x128/apps"
|
|
mkdir -p "${APPDIR}/usr/share/icons/hicolor/256x256/apps"
|
|
|
|
cp -r "${ROOT}/src/titletimer" "${APPDIR}/usr/lib/titletimer/src/"
|
|
cp "${ROOT}/packaging/AppRun" "${APPDIR}/AppRun"
|
|
chmod +x "${APPDIR}/AppRun"
|
|
cp "${ROOT}/packaging/korin-timer.desktop" "${APPDIR}/"
|
|
cp "${ROOT}/packaging/korin-timer.desktop" "${APPDIR}/usr/share/applications/"
|
|
# Pre-sized on the dev host (packaging/icon-*.png) rather than resized here at
|
|
# build time - keeps this script's dependencies to what it already needs
|
|
# (no ImageMagick/GdkPixbuf-CLI requirement inside the build container).
|
|
cp "${ROOT}/packaging/icon-256.png" "${APPDIR}/titletimer.png"
|
|
cp "${ROOT}/packaging/icon-64.png" "${APPDIR}/usr/share/icons/hicolor/64x64/apps/titletimer.png"
|
|
cp "${ROOT}/packaging/icon-128.png" "${APPDIR}/usr/share/icons/hicolor/128x128/apps/titletimer.png"
|
|
cp "${ROOT}/packaging/icon-256.png" "${APPDIR}/usr/share/icons/hicolor/256x256/apps/titletimer.png"
|
|
|
|
bash "${ROOT}/packaging/bundle-runtime.sh" "${APPDIR}/usr/lib/titletimer/rt"
|
|
|
|
OUT="${BUILD_DIR}/Korin-Timer.AppImage"
|
|
APPIMAGETOOL="${BUILD_DIR}/appimagetool-x86_64.AppImage"
|
|
if [ ! -x "${APPIMAGETOOL}" ]; then
|
|
echo "Downloading appimagetool..."
|
|
curl -L -o "${APPIMAGETOOL}" \
|
|
https://github.com/AppImage/appimagetool/releases/latest/download/appimagetool-x86_64.AppImage
|
|
chmod +x "${APPIMAGETOOL}"
|
|
fi
|
|
|
|
if ARCH=x86_64 "${APPIMAGETOOL}" "${APPDIR}" "${OUT}" 2>/tmp/appimagetool.err; then
|
|
echo "Built ${OUT}"
|
|
else
|
|
# appimagetool's AppImage is itself a static-PIE ELF (no PT_INTERP). Some
|
|
# restricted/sandboxed environments can't exec that binary format at all
|
|
# (execve fails outright, unrelated to FUSE) - if so, fall back to
|
|
# assembling the AppImage by hand: a type-2 runtime stub concatenated with
|
|
# a plain squashfs of the AppDir is exactly what appimagetool does
|
|
# internally anyway.
|
|
echo "appimagetool failed to run directly (see /tmp/appimagetool.err)." >&2
|
|
echo "Falling back to manual runtime+squashfs assembly..." >&2
|
|
|
|
RUNTIME="${BUILD_DIR}/runtime-x86_64"
|
|
if [ ! -f "${RUNTIME}" ]; then
|
|
curl -L -o "${RUNTIME}" \
|
|
https://github.com/AppImage/type2-runtime/releases/download/continuous/runtime-x86_64
|
|
fi
|
|
|
|
SQUASHFS="${BUILD_DIR}/AppDir.squashfs"
|
|
rm -f "${SQUASHFS}"
|
|
mksquashfs "${APPDIR}" "${SQUASHFS}" -root-owned -noappend -quiet
|
|
|
|
cat "${RUNTIME}" "${SQUASHFS}" > "${OUT}"
|
|
chmod +x "${OUT}"
|
|
echo "Built ${OUT} (manual assembly)"
|
|
fi
|