mirror of
https://github.com/flectar/mail.git
synced 2026-11-11 17:57:54 +00:00
157 lines
6.8 KiB
Bash
Executable File
157 lines
6.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
project_dir="$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)"
|
|
build_dir="$project_dir/target/appimage"
|
|
app_dir="$build_dir/flectar-mail.AppDir"
|
|
output_path="$build_dir/flectar-mail.AppImage"
|
|
staged_output="$build_dir/.flectar-mail.AppImage.new"
|
|
tools_dir="$build_dir/tools"
|
|
executable="$project_dir/target/release/flectar-mail"
|
|
|
|
download_tool() {
|
|
local url="$1"
|
|
local destination="$2"
|
|
if [[ -x "$destination" ]]; then
|
|
return
|
|
fi
|
|
mkdir -p "$(dirname "$destination")"
|
|
if command -v curl >/dev/null 2>&1; then
|
|
curl --fail --location --silent --show-error "$url" --output "$destination.new"
|
|
elif command -v wget >/dev/null 2>&1; then
|
|
wget -q "$url" -O "$destination.new"
|
|
else
|
|
printf 'curl or wget is required to obtain the AppImage deployment tools.\n' >&2
|
|
exit 1
|
|
fi
|
|
chmod +x "$destination.new"
|
|
mv -f "$destination.new" "$destination"
|
|
}
|
|
|
|
mkdir -p "$build_dir"
|
|
# Include both renderer choices; CPU remains the initial runtime selection.
|
|
# FLECTAR_APP_FEATURES can enable additional application features.
|
|
app_features="${FLECTAR_APP_FEATURES:-}"
|
|
build_args=(--locked --bin flectar-mail --manifest-path "$project_dir/Cargo.toml" --release --no-default-features --features remote-content,gpu-renderer)
|
|
if [[ -n "$app_features" ]]; then
|
|
build_args+=(--features "$app_features")
|
|
fi
|
|
# The controls are app-owned and the Linux shell uses winit directly.
|
|
if [[ "${FLECTAR_SKIP_BUILD:-0}" == "1" ]]; then
|
|
if [[ ! -x "$executable" ]]; then
|
|
printf 'FLECTAR_SKIP_BUILD=1 requires an existing release executable.\n' >&2
|
|
exit 1
|
|
fi
|
|
else
|
|
cargo build "${build_args[@]}"
|
|
fi
|
|
# Name the package and its tools after the executable's architecture.
|
|
architecture="$(python3 "$project_dir/scripts/linux-elf.py" arch "$executable")"
|
|
read -r machine _ pdfium_target <<<"$architecture"
|
|
|
|
if ldd "$executable" | grep -q 'libQt'; then
|
|
printf 'The release binary unexpectedly links Qt; refusing to package it.\n' >&2
|
|
exit 1
|
|
fi
|
|
|
|
rm -rf "$app_dir"
|
|
mkdir -p \
|
|
"$app_dir/usr/bin" \
|
|
"$app_dir/usr/share/applications" \
|
|
"$app_dir/usr/share/doc/flectar-mail/google-sans-flex" \
|
|
"$app_dir/usr/share/icons/hicolor/512x512/apps" \
|
|
"$app_dir/usr/share/icons/hicolor/scalable/apps" \
|
|
"$app_dir/usr/share/metainfo"
|
|
cp "$executable" "$app_dir/usr/bin/flectar-mail"
|
|
python3 "$project_dir/scripts/stage-pdfium.py" "$pdfium_target" "$app_dir/usr/lib/flectar-mail"
|
|
app_version="$(python3 "$project_dir/scripts/stage-linux-metadata.py" --arch "$machine" "$app_dir")"
|
|
cp "$project_dir/resources/app-icon/flectar-mail-masked-512.png" "$app_dir/usr/share/icons/hicolor/512x512/apps/com.flectar.mail.png"
|
|
cp "$project_dir/resources/app-icon/flectar-mail-masked.svg" "$app_dir/usr/share/icons/hicolor/scalable/apps/com.flectar.mail.svg"
|
|
cp "$project_dir/LICENSE" "$app_dir/usr/share/doc/flectar-mail/LICENSE"
|
|
cp -R "$project_dir/LICENSES" "$app_dir/usr/share/doc/flectar-mail/LICENSES"
|
|
cp "$project_dir/THIRD_PARTY_NOTICES.md" "$app_dir/usr/share/doc/flectar-mail/THIRD_PARTY_NOTICES.md"
|
|
cp "$project_dir/resources/fonts/google-sans-flex/OFL.txt" \
|
|
"$app_dir/usr/share/doc/flectar-mail/google-sans-flex/OFL.txt"
|
|
cp "$project_dir/resources/fonts/google-sans-flex/README.md" \
|
|
"$app_dir/usr/share/doc/flectar-mail/google-sans-flex/README.md"
|
|
cp "$project_dir/resources/AppRun" "$app_dir/AppRun"
|
|
chmod +x "$app_dir/AppRun" "$app_dir/usr/bin/flectar-mail"
|
|
|
|
linuxdeploy="${LINUXDEPLOY:-$tools_dir/linuxdeploy-$machine.AppImage}"
|
|
download_tool \
|
|
"https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-$machine.AppImage" \
|
|
"$linuxdeploy"
|
|
appimagetool="${APPIMAGETOOL:-$tools_dir/appimagetool-$machine.AppImage}"
|
|
download_tool \
|
|
"https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-$machine.AppImage" \
|
|
"$appimagetool"
|
|
|
|
# Winit opens libxkbcommon-x11 with dlopen(), so linuxdeploy cannot discover
|
|
# it from the executable. Hosts without it (Ubuntu without Qt, minimal X11
|
|
# sessions such as the AppImageHub test runner) panic before the first window.
|
|
# It is not on the AppImage excludelist; bundle it with its xkbcommon/xcb-xkb
|
|
# dependencies, like the deb and rpm packages declare it.
|
|
xkbcommon_x11_dir="$(pkg-config --variable=libdir xkbcommon-x11)"
|
|
xkbcommon_x11="$xkbcommon_x11_dir/libxkbcommon-x11.so.0"
|
|
if [[ ! -f "$xkbcommon_x11" ]]; then
|
|
printf 'libxkbcommon-x11.so.0 was not found; install libxkbcommon-x11-dev.\n' >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Deploy ordinary ELF dependencies. Winit uses the host Wayland/X11 client
|
|
# libraries through its normal backend discovery rather than a toolkit plugin.
|
|
VERSION="$app_version" APPIMAGE_EXTRACT_AND_RUN="${APPIMAGE_EXTRACT_AND_RUN:-1}" \
|
|
"$linuxdeploy" \
|
|
--appdir "$app_dir" \
|
|
--executable "$app_dir/usr/bin/flectar-mail" \
|
|
--library "$xkbcommon_x11"
|
|
for library in libxkbcommon-x11.so.0 libxkbcommon.so.0; do
|
|
if [[ ! -e "$app_dir/usr/lib/$library" ]]; then
|
|
printf 'linuxdeploy did not bundle %s.\n' "$library" >&2
|
|
exit 1
|
|
fi
|
|
done
|
|
|
|
# AppRun leaves LD_LIBRARY_PATH to the host, so the executable and bundled
|
|
# libraries must find usr/lib through the RUNPATH linuxdeploy sets.
|
|
require_runpath() {
|
|
local dynamic
|
|
dynamic="$(readelf -d "$1")"
|
|
if [[ "$dynamic" != *"Library runpath: [$2]"* ]]; then
|
|
printf '%s does not have RUNPATH %s.\n' "$1" "$2" >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
require_runpath "$app_dir/usr/bin/flectar-mail" '$ORIGIN/../lib'
|
|
for library in "$app_dir"/usr/lib/*.so*; do
|
|
require_runpath "$library" '$ORIGIN'
|
|
done
|
|
|
|
# Preserve the renderer default and stable process name from our launcher.
|
|
cp "$project_dir/resources/AppRun" "$app_dir/AppRun"
|
|
chmod +x "$app_dir/AppRun"
|
|
|
|
# The pinned PDFium runtime depends only on the ordinary glibc runtime. Keep
|
|
# its private path intact and verify it after deployment has adjusted the ELF files.
|
|
python3 "$project_dir/scripts/test-pdf-preview.py" "$app_dir/usr/bin/flectar-mail"
|
|
# Deployment rewrites ELF files; they must still load on 16 and 64 KiB pages.
|
|
python3 "$project_dir/scripts/linux-elf.py" verify "$app_dir"
|
|
|
|
# AppDir specifies a PNG .DirIcon for file-manager thumbnails. linuxdeploy
|
|
# prefers the scalable icon for the root entry, so restore the PNG thumbnail
|
|
# explicitly while retaining the SVG and themed icon copies for integration.
|
|
cp "$project_dir/resources/app-icon/flectar-mail-masked-512.png" "$app_dir/flectar-mail.png"
|
|
ln -sfn flectar-mail.png "$app_dir/.DirIcon"
|
|
|
|
mkdir -p "$(dirname "$output_path")"
|
|
rm -f "$staged_output"
|
|
VERSION="$app_version" APPIMAGE_EXTRACT_AND_RUN="${APPIMAGE_EXTRACT_AND_RUN:-1}" \
|
|
"$appimagetool" "$app_dir" "$staged_output"
|
|
# The AppImage starts with appimagetool's runtime, which is an ELF executable.
|
|
python3 "$project_dir/scripts/linux-elf.py" verify "$staged_output"
|
|
# Renaming over an executing AppImage is atomic on Linux; the running process
|
|
# keeps its old inode while new launches receive the freshly packaged build.
|
|
mv -f "$staged_output" "$output_path"
|
|
|
|
printf 'Built %s\n' "$output_path"
|