mirror of
https://gitlab.com/gabmus/envision.git
synced 2025-04-19 19:14:53 +00:00
feat: appimage build script
This commit is contained in:
parent
b5ad5e0e80
commit
803fc87442
4 changed files with 384 additions and 0 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -2,6 +2,9 @@
|
|||
build/
|
||||
_build/
|
||||
builddir/
|
||||
appimage_build/
|
||||
AppDir/
|
||||
*.AppImage
|
||||
build-aux/app
|
||||
build-aux/.flatpak-builder/
|
||||
src/constants.rs
|
||||
|
|
|
@ -14,3 +14,11 @@ ninja -C build
|
|||
ninja -C build install
|
||||
./build/localprefix/bin/rex2
|
||||
```
|
||||
|
||||
## Build AppImage
|
||||
|
||||
```bash
|
||||
git clone https://gitlab.com/gabmus/rex2
|
||||
cd rex2
|
||||
./dist/appimage/build_appimage.sh
|
||||
```
|
||||
|
|
22
dist/appimage/build_appimage.sh
vendored
Executable file
22
dist/appimage/build_appimage.sh
vendored
Executable file
|
@ -0,0 +1,22 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
if [[ ! -f Cargo.toml ]]; then
|
||||
echo "Please run this script from the repo root"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
meson setup appimage_build -Dprefix=/usr -Dprofile=development
|
||||
DESTDIR="$PWD/AppDir" ninja -C appimage_build install
|
||||
curl -SsLO https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
|
||||
cp dist/appimage/linuxdeploy-plugin-gtk.sh ./
|
||||
|
||||
./linuxdeploy-x86_64.AppImage \
|
||||
--appdir AppDir \
|
||||
--plugin gtk \
|
||||
--output appimage \
|
||||
--icon-file AppDir/usr/share/icons/hicolor/scalable/apps/org.gabmus.rex2.Devel.svg \
|
||||
--desktop-file AppDir/usr/share/applications/org.gabmus.rex2.Devel.desktop
|
||||
|
||||
rm ./linuxdeploy-plugin-gtk.sh
|
351
dist/appimage/linuxdeploy-plugin-gtk.sh
vendored
Executable file
351
dist/appimage/linuxdeploy-plugin-gtk.sh
vendored
Executable file
|
@ -0,0 +1,351 @@
|
|||
#! /usr/bin/env bash
|
||||
|
||||
# GTK3 environment variables: https://developer.gnome.org/gtk3/stable/gtk-running.html
|
||||
# GTK4 environment variables: https://developer.gnome.org/gtk4/stable/gtk-running.html
|
||||
|
||||
# abort on all errors
|
||||
set -e
|
||||
|
||||
if [ "$DEBUG" != "" ]; then
|
||||
set -x
|
||||
verbose="--verbose"
|
||||
fi
|
||||
|
||||
SCRIPT="$(basename "$(readlink -f "$0")")"
|
||||
|
||||
show_usage() {
|
||||
echo "Usage: $SCRIPT --appdir <path to AppDir>"
|
||||
echo
|
||||
echo "Bundles resources for applications that use GTK into an AppDir"
|
||||
echo
|
||||
echo "Required variables:"
|
||||
echo " LINUXDEPLOY=\".../linuxdeploy\" path to linuxdeploy (e.g., AppImage); set automatically when plugin is run directly by linuxdeploy"
|
||||
echo
|
||||
echo "Optional variables:"
|
||||
echo " DEPLOY_GTK_VERSION (major version of GTK to deploy, e.g. '2', '3' or '4'; auto-detect by default)"
|
||||
}
|
||||
|
||||
variable_is_true() {
|
||||
local var="$1"
|
||||
|
||||
if [ -n "$var" ] && { [ "$var" == "true" ] || [ "$var" -gt 0 ]; } 2> /dev/null; then
|
||||
return 0 # true
|
||||
else
|
||||
return 1 # false
|
||||
fi
|
||||
}
|
||||
|
||||
get_pkgconf_variable() {
|
||||
local variable="$1"
|
||||
local library="$2"
|
||||
local default_value="$3"
|
||||
|
||||
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
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
copy_tree() {
|
||||
local src=("${@:1:$#-1}")
|
||||
local dst="${*:$#}"
|
||||
|
||||
for elem in "${src[@]}"; do
|
||||
mkdir -p "${dst::-1}$elem"
|
||||
cp "$elem" --archive --parents --target-directory="$dst" $verbose
|
||||
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
|
||||
}
|
||||
|
||||
search_library_path() {
|
||||
PATH_ARRAY=(
|
||||
"/usr/lib/$(uname -m)-linux-gnu"
|
||||
"/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"
|
||||
|
||||
if command -v "$tool"; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
PATH_ARRAY=(
|
||||
"/usr/lib/$(uname -m)-linux-gnu/$directory/$tool"
|
||||
"/usr/lib64/$directory/$tool"
|
||||
"/usr/lib/$directory/$tool"
|
||||
"/usr/bin/$tool"
|
||||
"/usr/bin/$tool-64"
|
||||
"/usr/bin/$tool-32"
|
||||
)
|
||||
|
||||
for path in "${PATH_ARRAY[@]}"; do
|
||||
if [ -x "$path" ]; then
|
||||
echo "$path"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
DEPLOY_GTK_VERSION="${DEPLOY_GTK_VERSION:-0}" # When not set by user, this variable use the integer '0' as a sentinel value
|
||||
APPDIR=
|
||||
|
||||
while [ "$1" != "" ]; do
|
||||
case "$1" in
|
||||
--plugin-api-version)
|
||||
echo "0"
|
||||
exit 0
|
||||
;;
|
||||
--appdir)
|
||||
APPDIR="$2"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
--help)
|
||||
show_usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Invalid argument: $1"
|
||||
echo
|
||||
show_usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ "$APPDIR" == "" ]; then
|
||||
show_usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
APPDIR="$(realpath "$APPDIR")"
|
||||
mkdir -p "$APPDIR"
|
||||
|
||||
if command -v pkgconf > /dev/null; then
|
||||
PKG_CONFIG="pkgconf"
|
||||
elif command -v pkg-config > /dev/null; then
|
||||
PKG_CONFIG="pkg-config"
|
||||
else
|
||||
echo "$0: pkg-config/pkgconf not found in PATH, aborting"
|
||||
exit 1
|
||||
fi
|
||||
LD_GTK_LIBRARY_PATH="${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
|
||||
fi
|
||||
|
||||
if [ -z "$LINUXDEPLOY" ]; then
|
||||
echo -e "$0: LINUXDEPLOY environment variable is not set.\nDownload a suitable linuxdeploy AppImage, set the environment variable and re-run the plugin."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
gtk_versions=0 # Count major versions of GTK when auto-detect GTK version
|
||||
if [ "$DEPLOY_GTK_VERSION" -eq 0 ]; then
|
||||
echo "Determining which GTK version to deploy"
|
||||
while IFS= read -r -d '' file; do
|
||||
if [ "$DEPLOY_GTK_VERSION" -ne 2 ] && ldd "$file" | grep -q "libgtk-x11-2.0.so"; then
|
||||
DEPLOY_GTK_VERSION=2
|
||||
gtk_versions="$((gtk_versions+1))"
|
||||
fi
|
||||
if [ "$DEPLOY_GTK_VERSION" -ne 3 ] && ldd "$file" | grep -q "libgtk-3.so"; then
|
||||
DEPLOY_GTK_VERSION=3
|
||||
gtk_versions="$((gtk_versions+1))"
|
||||
fi
|
||||
if [ "$DEPLOY_GTK_VERSION" -ne 4 ] && ldd "$file" | grep -q "libgtk-4.so"; then
|
||||
DEPLOY_GTK_VERSION=4
|
||||
gtk_versions="$((gtk_versions+1))"
|
||||
fi
|
||||
done < <(find "$APPDIR/usr/bin" -executable -type f -print0)
|
||||
fi
|
||||
|
||||
if [ "$gtk_versions" -gt 1 ]; then
|
||||
echo "$0: can not deploy multiple GTK versions at the same time."
|
||||
echo "Please set DEPLOY_GTK_VERSION to {2, 3, 4}."
|
||||
exit 1
|
||||
elif [ "$DEPLOY_GTK_VERSION" -eq 0 ]; then
|
||||
echo "$0: failed to auto-detect GTK version."
|
||||
echo "Please set DEPLOY_GTK_VERSION to {2, 3, 4}."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Installing AppRun hook"
|
||||
HOOKSDIR="$APPDIR/apprun-hooks"
|
||||
HOOKFILE="$HOOKSDIR/linuxdeploy-plugin-gtk.sh"
|
||||
mkdir -p "$HOOKSDIR"
|
||||
cat > "$HOOKFILE" <<\EOF
|
||||
#! /usr/bin/env bash
|
||||
|
||||
# case "$(gsettings get org.gnome.desktop.interface color-scheme 2> /dev/null)" in
|
||||
# "'prefer-dark'") GTK_THEME_VARIANT="dark";;
|
||||
# "'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
|
||||
export GTK_DATA_PREFIX="$APPDIR"
|
||||
# export GTK_THEME="$APPIMAGE_GTK_THEME" # Custom themes are broken
|
||||
export GDK_BACKEND=x11 # Crash with Wayland backend on Wayland
|
||||
export XDG_DATA_DIRS="$APPDIR/usr/share:/usr/share:$XDG_DATA_DIRS" # g_get_system_data_dirs() from GLib
|
||||
EOF
|
||||
|
||||
echo "Installing GLib schemas"
|
||||
# Note: schemasdir is undefined on Ubuntu 16.04
|
||||
glib_schemasdir="$(get_pkgconf_variable "schemasdir" "gio-2.0" "/usr/share/glib-2.0/schemas")"
|
||||
copy_tree "$glib_schemasdir" "$APPDIR/"
|
||||
glib-compile-schemas "$APPDIR/$glib_schemasdir"
|
||||
cat >> "$HOOKFILE" <<EOF
|
||||
export GSETTINGS_SCHEMA_DIR="\$APPDIR/$glib_schemasdir"
|
||||
EOF
|
||||
|
||||
echo "Installing GIRepository Typelibs"
|
||||
gi_typelibsdir="$(get_pkgconf_variable "typelibdir" "gobject-introspection-1.0" "$LD_GTK_LIBRARY_PATH/girepository-1.0")"
|
||||
copy_lib_tree "$gi_typelibsdir" "$APPDIR/"
|
||||
cat >> "$HOOKFILE" <<EOF
|
||||
export GI_TYPELIB_PATH="\$APPDIR/${gi_typelibsdir/$LD_GTK_LIBRARY_PATH//usr/lib}"
|
||||
EOF
|
||||
|
||||
case "$DEPLOY_GTK_VERSION" in
|
||||
2)
|
||||
# https://github.com/linuxdeploy/linuxdeploy-plugin-gtk/pull/20#issuecomment-826354261
|
||||
echo "WARNING: Gtk+2 applications are not fully supported by this plugin"
|
||||
;;
|
||||
3)
|
||||
echo "Installing GTK 3.0 modules"
|
||||
gtk3_exec_prefix="$(get_pkgconf_variable "exec_prefix" "gtk+-3.0" "/usr")"
|
||||
gtk3_libdir="$(get_pkgconf_variable "libdir" "gtk+-3.0" "$LD_GTK_LIBRARY_PATH")/gtk-3.0"
|
||||
gtk3_path="$gtk3_libdir"
|
||||
gtk3_immodulesdir="$gtk3_libdir/$(get_pkgconf_variable "gtk_binary_version" "gtk+-3.0" "3.0.0")/immodules"
|
||||
gtk3_printbackendsdir="$gtk3_libdir/$(get_pkgconf_variable "gtk_binary_version" "gtk+-3.0" "3.0.0")/printbackends"
|
||||
gtk3_immodules_cache_file="$(dirname "$gtk3_immodulesdir")/immodules.cache"
|
||||
gtk3_immodules_query="$(search_tool "gtk-query-immodules-3.0" "libgtk-3-0")"
|
||||
copy_lib_tree "$gtk3_libdir" "$APPDIR/"
|
||||
cat >> "$HOOKFILE" <<EOF
|
||||
export GTK_EXE_PREFIX="\$APPDIR/$gtk3_exec_prefix"
|
||||
export GTK_PATH="\$APPDIR/${gtk3_path/$LD_GTK_LIBRARY_PATH//usr/lib}"
|
||||
export GTK_IM_MODULE_FILE="\$APPDIR/${gtk3_immodules_cache_file/$LD_GTK_LIBRARY_PATH//usr/lib}"
|
||||
EOF
|
||||
|
||||
if [ -x "$gtk3_immodules_query" ]; then
|
||||
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/$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/$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"
|
||||
copy_lib_tree "$gtk4_libdir" "$APPDIR/"
|
||||
cat >> "$HOOKFILE" <<EOF
|
||||
export GTK_EXE_PREFIX="\$APPDIR/$gtk4_exec_prefix"
|
||||
export GTK_PATH="\$APPDIR/${gtk4_path/$LD_GTK_LIBRARY_PATH//usr/lib}"
|
||||
EOF
|
||||
;;
|
||||
*)
|
||||
echo "$0: '$DEPLOY_GTK_VERSION' is not a valid GTK major version."
|
||||
echo "Please set DEPLOY_GTK_VERSION to {2, 3, 4}."
|
||||
exit 1
|
||||
esac
|
||||
|
||||
echo "Installing GDK PixBufs"
|
||||
gdk_libdir="$(get_pkgconf_variable "libdir" "gdk-pixbuf-2.0" "$LD_GTK_LIBRARY_PATH")"
|
||||
gdk_pixbuf_binarydir="$(get_pkgconf_variable "gdk_pixbuf_binarydir" "gdk-pixbuf-2.0" "$gdk_libdir/gdk-pixbuf-2.0/2.10.0")"
|
||||
gdk_pixbuf_cache_file="$(get_pkgconf_variable "gdk_pixbuf_cache_file" "gdk-pixbuf-2.0" "$gdk_pixbuf_binarydir/loaders.cache")"
|
||||
gdk_pixbuf_moduledir="$(get_pkgconf_variable "gdk_pixbuf_moduledir" "gdk-pixbuf-2.0" "$gdk_pixbuf_binarydir/loaders")"
|
||||
# Note: gdk_pixbuf_query_loaders variable is not defined on some systems
|
||||
gdk_pixbuf_query="$(search_tool "gdk-pixbuf-query-loaders" "gdk-pixbuf-2.0")"
|
||||
copy_lib_tree "$gdk_pixbuf_binarydir" "$APPDIR/"
|
||||
cat >> "$HOOKFILE" <<EOF
|
||||
export GDK_PIXBUF_MODULE_FILE="\$APPDIR/${gdk_pixbuf_cache_file/$LD_GTK_LIBRARY_PATH//usr/lib}"
|
||||
EOF
|
||||
if [ -x "$gdk_pixbuf_query" ]; then
|
||||
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/$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/$LD_GTK_LIBRARY_PATH//usr/lib}"
|
||||
|
||||
echo "Copying more libraries"
|
||||
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*"
|
||||
"$pango_libdir" "libpango-*.so*"
|
||||
"$pangocairo_libdir" "libpangocairo-*.so*"
|
||||
"$pangoft2_libdir" "libpangoft2-*.so*"
|
||||
)
|
||||
LIBRARIES=()
|
||||
for (( i=0; i<${#FIND_ARRAY[@]}; i+=2 )); do
|
||||
directory=${FIND_ARRAY[i]}
|
||||
library=${FIND_ARRAY[i+1]}
|
||||
while IFS= read -r -d '' file; do
|
||||
LIBRARIES+=( "--library=$file" )
|
||||
done < <(find "$directory" \( -type l -o -type f \) -name "$library" -print0)
|
||||
done
|
||||
|
||||
env LINUXDEPLOY_PLUGIN_MODE=1 "$LINUXDEPLOY" --appdir="$APPDIR" "${LIBRARIES[@]}"
|
||||
|
||||
# Create symbolic links as a workaround
|
||||
# Details: https://github.com/linuxdeploy/linuxdeploy-plugin-gtk/issues/24#issuecomment-1030026529
|
||||
echo "Manually setting rpath for GTK modules"
|
||||
PATCH_ARRAY=(
|
||||
"$gtk3_immodulesdir"
|
||||
"$gtk3_printbackendsdir"
|
||||
"$gdk_pixbuf_moduledir"
|
||||
)
|
||||
for directory in "${PATCH_ARRAY[@]}"; do
|
||||
while IFS= read -r -d '' file; do
|
||||
ln $verbose -sf "${file/$LD_GTK_LIBRARY_PATH\//}" "$APPDIR/usr/lib"
|
||||
done < <(find "$directory" -name '*.so' -print0)
|
||||
done
|
Loading…
Add table
Reference in a new issue