Files
OrcaSlicer/src/dev-utils/platform/unix/build_linux_image.sh.in
T
Lam Wei LunandSoftFever 0caefcf4aa Linux: only disable WebKit compositing for WebKitGTK older than 2.42 (#16385)
* Linux: only disable WebKit compositing for WebKitGTK older than 2.42

The default Wayland path set WEBKIT_DISABLE_COMPOSITING_MODE=1 whenever the
session had both DISPLAY and WAYLAND_DISPLAY, i.e. any Wayland session with
XWayland. That forces WebKitGTK accelerated compositing off and also disables
threaded scrolling, so the Device tab web view (Mainsail/Fluidd) lagged unless
the app was launched with GDK_BACKEND=x11, the only path that skipped the
variable. Disabling compositing also turns off threaded scrolling.

The XWayland compositing bug the fallback worked around is fixed in WebKitGTK
>= 2.42, so apply it only for older WebKit. WebView::NeedsCompositingWorkaround()
reads the runtime WebKitGTK version; the X11 opt-in path is unchanged.

Behavior is unchanged on WebKit < 2.42, on pure X11, and on native Wayland
without XWayland. The wxWidgets skill reference is updated to match.

* Linux: use WebKit's shared-memory transport for the NVIDIA DMABUF renderer

The Device tab web view is slow on NVIDIA proprietary drivers even with
accelerated compositing left on: since the DMABUF renderer became the
default in WebKitGTK 2.42, the driver cannot back it, and web views fall
back to a slow path. Gating the old WEBKIT_DISABLE_COMPOSITING_MODE
fallback on WebKit < 2.42 is the wrong axis, because the failure is
version-independent from 2.42 on.

Force the shared-memory transport with WEBKIT_DMABUF_RENDERER_FORCE_SHM=1.
That keeps compositing and threaded scrolling and skips only the hardware
path. Also set WEBKIT_FORCE_DMABUF_RENDERER=1, which clears the isNVIDIA()
early return that Debian/Ubuntu/openSUSE patch into
rendererBufferTransportMode() and which otherwise returns before the
FORCE_SHM check is reached.

Both are set before the X11-vs-Wayland split so the workaround also covers
XWayland, and only when WebKitGTK is new enough to honour FORCE_SHM
(>= 2.44, WebView::SupportsForceSharedMemory()).

The AppImage launcher exported the superseded
WEBKIT_DISABLE_DMABUF_RENDERER=1, which is read first, leaves the transport
set empty and so disables compositing outright; replace it with the same
pair. The wxWidgets skill reference is updated to match.

* Linux: drop the AppImage WebKit DMABUF exports; correct the skill notes

The launcher cannot gate on the runtime WebKitGTK version, so exporting
WEBKIT_DMABUF_RENDERER_FORCE_SHM/WEBKIT_FORCE_DMABUF_RENDERER there would
clear a distro isNVIDIA() guard on hosts older than 2.44, where FORCE_SHM
is ignored, re-exposing the broken hardware path. The binary already sets
both with the correct gate, so remove them and say who owns the workaround.

Also correct two claims in the skill reference. An empty transport set only
means "no accelerated compositing" from 2.44 on; 2.42/2.43 still fall back
to the Wayland/X11 renderers, removed in the same release that added
FORCE_SHM. And threaded scrolling is off by default in 2.44/2.45 (on from
2.46), so FORCE_SHM keeps compositing rather than scrolling. Document the
module-level detection cost and the WEBKIT_DMABUF_RENDERER_FORCE_SHM=0
opt-out.

* Flatpak: force WebKit's shared-memory transport instead of disabling DMABUF

The entrypoint exported WEBKIT_DISABLE_DMABUF_RENDERER=1 for NVIDIA. WebKit
reads that variable first and leaves the transport set empty, which turns
accelerated compositing off, so the Device tab still lagged for NVIDIA
Flatpak users, and the binary could not override it because its setenv is
non-replacing.

The runtime's WebKitGTK is vanilla, so there is no distro isNVIDIA() guard
to clear and WEBKIT_DMABUF_RENDERER_FORCE_SHM=1 alone is the right switch:
compositing stays on and only the hardware DMABUF path is skipped.

* Flatpak: drop the WebKit NVIDIA export; the binary owns the workaround

/proc/driver/nvidia/version is readable inside the Flatpak sandbox, so the
binary's NVIDIA branch already sets WEBKIT_DMABUF_RENDERER_FORCE_SHM with
the correct runtime gate and the entrypoint's own export is redundant.

Verified with:
  flatpak run --command=cat com.orcaslicer.OrcaSlicer /proc/driver/nvidia/version
which prints the NVRM version (driver 615.71.09) from inside the sandbox.

* Linux: say what the XWayland compositing gate actually tests

DISPLAY and WAYLAND_DISPLAY are both set in a native Wayland session as
well, because GNOME and KDE run Xwayland as part of the session and export
DISPLAY for it whether or not this process is an X client. The pair means
XWayland is available in the session, not that GTK picked X11 for this
process, so "(an XWayland session)" reads as more than the condition
establishes.

Say what the pair means, and name the case the fallback actually covers:
the X11 backend inside a Wayland session, which is what the forced
GDK_BACKEND=x11 above produces in a build without EGL.

Comment only; behaviour is unchanged.

* Linux: apply the XWayland compositing fallback only where GTK picks X11

The default path set WEBKIT_DISABLE_COMPOSITING_MODE whenever DISPLAY and
WAYLAND_DISPLAY were both set, but a native Wayland app inherits both, so a
build with EGL disabled accelerated compositing — and with it threaded
scrolling — while running on Wayland, where the XWayland bug does not apply.

The only default-path case that really runs through XWayland is the forced
GDK_BACKEND=x11 used when wx lacks EGL, so set the variable there. The
backend cannot be re-checked later: that branch exports GDK_BACKEND itself,
so the force and a user's GDK_BACKEND=x11 opt-in, which deliberately keeps
compositing, would be indistinguishable.

Behaviour is unchanged for WebKitGTK >= 2.42, where the gate already skipped
the variable, and for builds without EGL. A build with EGL on WebKitGTK <
2.42 in a Wayland session no longer loses compositing and threaded scrolling.

The wxWidgets skill reference is updated to match.

---------

Co-authored-by: SoftFever <103989404+SoftFever@users.noreply.github.com>
2026-10-15 22:35:56 +08:00

468 lines
18 KiB
Bash
Executable File

#!/usr/bin/env bash
# Despite the script name, this doesn't necessarily create an "image";
# it sets up a compatibility script wrapper for the binary and arranges some resources.
set -e
export ROOT=$(echo $ROOT | grep . || pwd)
export NCORES=$(nproc --all)
CONFIG=Release
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd -- "${SCRIPT_DIR}/../.." && pwd)"
POLICY_FILE="${REPO_ROOT}/scripts/appimage_lib_policy.sh"
CHECK_SCRIPT="${REPO_ROOT}/scripts/check_appimage_libs.sh"
if [ ! -f "${POLICY_FILE}" ]; then
echo "Error: missing AppImage helper ${POLICY_FILE}"
exit 1
fi
# shellcheck source=/dev/null
source "${POLICY_FILE}"
while getopts ":ihR:" opt; do
case ${opt} in
i )
export BUILD_IMAGE="1"
;;
h ) echo "Usage: ./build_linux_image.sh [-i][-R config]"
echo " -i: Generate Appimage (optional)"
echo " -R: Specify from which config to obtain the binary: Release, RelWithDebInfo, or Debug"
exit 1
;;
R )
CONFIG=$OPTARG
;;
esac
done
copy_directory_if_present() {
local src_dir="$1"
local dst_dir="$2"
if [ -n "$src_dir" ] && [ -d "$src_dir" ]; then
mkdir -p "$dst_dir"
cp -a "$src_dir"/. "$dst_dir"/
fi
}
find_pkg_config_dir() {
local variable="$1"
shift
local module
for module in "$@"; do
if pkg-config --exists "$module" 2>/dev/null; then
pkg-config --variable="$variable" "$module" 2>/dev/null || true
return 0
fi
done
return 1
}
find_first_existing_file() {
local path
for path in "$@"; do
if [ -f "$path" ]; then
printf '%s\n' "$path"
return 0
fi
done
return 1
}
copy_shared_object_to_dir() {
local src="$1"
local dst_dir="$2"
local src_real dst_name soname
src_real="$(readlink -f "$src")"
dst_name="$(basename "$src_real")"
mkdir -p "$dst_dir"
if [ "$src_real" = "$dst_dir/$dst_name" ]; then
# Already bundled; the dependency resolved from the bundle directory.
return 0
fi
cp -fL "$src_real" "$dst_dir/$dst_name"
if [ -L "$src" ]; then
ln -snf "$dst_name" "$dst_dir/$(basename "$src")"
fi
soname="$(objdump -p "$src_real" 2>/dev/null | awk '$1 == "SONAME" { print $2; exit }')"
if [ -n "$soname" ] && [ "$soname" != "$dst_name" ]; then
ln -snf "$dst_name" "$dst_dir/$soname"
fi
}
bundle_dependency_closure() {
local dst_dir
dst_dir="$(cd -- "$1" && pwd)"
shift
local -a queue=("$@")
local target dep dep_real dep_key copied_path
declare -A seen=()
# Dependencies are resolved with ldd, which only searches the default
# loader path. Deps-built shared libraries (e.g. the FFmpeg stack) are not
# installed there and carry no RUNPATH of their own, so once copied into
# the bundle ldd can no longer resolve one sibling from another
# (libavcodec -> libavutil) and reports it as missing. Extend the loader
# path with the bundle directory plus the source directories of files
# already bundled, so every library that was resolved once keeps resolving
# for its own dependencies. The audit script does the same
# (scripts/check_appimage_libs.sh).
local -a search_dirs=("$dst_dir")
# Walked with a read index rather than by reslicing the array: "${queue[@]:1}" rebuilds the whole
# queue on every pop, so draining it costs O(n^2). At the ~5k entries this bundle reaches that was
# ~22 s of the image build spent copying an array around.
local head=0
while [ "$head" -lt ${#queue[@]} ]; do
target="${queue[$head]}"
head=$((head + 1))
if [ ! -e "$target" ] || ! appimage_is_elf_file "$target"; then
continue
fi
while IFS= read -r dep; do
if [[ "$dep" == MISSING:* ]]; then
echo "Error: missing runtime dependency ${dep#MISSING:} while bundling $target"
exit 1
fi
dep_real="$(readlink -f "$dep" 2>/dev/null || printf '%s' "$dep")"
if appimage_is_host_library "$dep_real"; then
continue
fi
# Key dedup on the bundled file rather than the source path: once
# ldd resolves a library from the bundle directory (via the
# LD_LIBRARY_PATH above) its path is a dst_dir path, which differs
# from the source path the first resolution returned. Keying on
# the source path would re-copy the file onto itself.
dep_key="$dst_dir/$(basename "$dep_real")"
if [ -n "${seen[$dep_key]}" ]; then
continue
fi
seen[$dep_key]=1
copy_shared_object_to_dir "$dep" "$dst_dir"
search_dirs+=("$(dirname "$dep_real")")
copied_path="$dst_dir/$(basename "$dep_real")"
if [ -e "$copied_path" ]; then
queue+=("$copied_path")
fi
done < <(LD_LIBRARY_PATH="$(IFS=:; printf '%s' "${search_dirs[*]}")${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" appimage_list_direct_dependencies "$target")
done
}
echo -n "[9/9] Generating Linux app..."
# {
if [ -d "package" ]; then
rm -rf package
fi
APPDIR="package"
BIN_DIR="$APPDIR/bin"
LIB_DIR="$APPDIR/lib"
PRIVATE_LIB_DIR="$LIB_DIR/orca-runtime"
SHARE_DIR="$APPDIR/share"
LIBEXEC_DIR="$APPDIR/libexec"
BUNDLE_DESKTOP_STACK="${ORCA_BUNDLE_DESKTOP_STACK:-0}"
GST_PLUGIN_DIR="$LIB_DIR/gstreamer-1.0"
GIO_MODULE_DIR="$LIB_DIR/gio/modules"
GDK_PIXBUF_DIR="$LIB_DIR/gdk-pixbuf-2.0/2.10.0/loaders"
mkdir -p "$BIN_DIR" "$LIB_DIR" "$PRIVATE_LIB_DIR" "$SHARE_DIR" "$LIBEXEC_DIR"
if [ "$BUNDLE_DESKTOP_STACK" = "1" ]; then
mkdir -p "$GST_PLUGIN_DIR" "$GIO_MODULE_DIR" "$GDK_PIXBUF_DIR"
fi
cp -Rf ../resources "$APPDIR/resources"
ORIGINAL_BINARY_LOCATION=""
if [ -f "src/${CONFIG}/@SLIC3R_APP_CMD@" ]; then
ORIGINAL_BINARY_LOCATION="$(realpath "src/${CONFIG}/@SLIC3R_APP_CMD@")"
elif [ -f "src/@SLIC3R_APP_CMD@" ]; then
ORIGINAL_BINARY_LOCATION="$(realpath "src/@SLIC3R_APP_CMD@")"
else
echo "Error: @SLIC3R_APP_CMD@ binary not found in any configuration directory"
exit 1
fi
cp -fl "${ORIGINAL_BINARY_LOCATION}" "$BIN_DIR/@SLIC3R_APP_CMD@"
# Bundle the embedded Python runtime (interpreter + stdlib) that CMake staged
# next to the binary. OrcaSlicer resolves PYTHONHOME at <resources_dir>/../lib/python,
# which is $APPDIR/lib/python (resources_dir is $APPDIR/resources). Staging it here,
# before the dependency-closure pass below, lets that pass also bundle the extension
# modules' shared libraries; libpython itself is found via rpath ($ORIGIN entries set
# in src/CMakeLists.txt and by the dep recipe). Without this the plugin system cannot start.
PYTHON_RUNTIME_SRC="$(dirname "${ORIGINAL_BINARY_LOCATION}")/python"
if [ -d "$PYTHON_RUNTIME_SRC" ]; then
echo "Bundling Python runtime from ${PYTHON_RUNTIME_SRC} ..."
copy_directory_if_present "$PYTHON_RUNTIME_SRC" "$LIB_DIR/python"
else
echo "Warning: bundled Python runtime not found at ${PYTHON_RUNTIME_SRC}; plugin support will be disabled in this AppImage."
fi
# Bundle the uv executable (CMake staged it next to the binary) so the plugin
# system can install Python package dependencies. bundled_uv_path() looks under
# <resources_dir>/tools/uv == $APPDIR/resources/tools/uv -- the same layout the
# install()-based packagers (Windows/Flatpak/FHS) use. Unlike the AppImage, those
# run `make install`; this build copies artifacts, so stage uv explicitly.
UV_RUNTIME_SRC="$(dirname "${ORIGINAL_BINARY_LOCATION}")/tools/uv"
if [ -d "$UV_RUNTIME_SRC" ]; then
echo "Bundling uv from ${UV_RUNTIME_SRC} ..."
copy_directory_if_present "$UV_RUNTIME_SRC" "$APPDIR/resources/tools/uv"
else
echo "Warning: bundled uv not found at ${UV_RUNTIME_SRC}; Python package installation will be unavailable in this AppImage."
fi
if [ "$BUNDLE_DESKTOP_STACK" = "1" ]; then
GSTREAMER_PLUGIN_SOURCE_DIR="$(find_pkg_config_dir pluginsdir gstreamer-1.0 || true)"
if [ -z "$GSTREAMER_PLUGIN_SOURCE_DIR" ]; then
GSTREAMER_PLUGIN_SOURCE_DIR="$(find /usr/lib /usr/lib64 -maxdepth 4 -type d -name gstreamer-1.0 2>/dev/null | head -n1)"
fi
copy_directory_if_present "$GSTREAMER_PLUGIN_SOURCE_DIR" "$GST_PLUGIN_DIR"
GIO_MODULE_SOURCE_DIR="$(find_pkg_config_dir giomoduledir gio-2.0 || true)"
if [ -z "$GIO_MODULE_SOURCE_DIR" ]; then
GIO_MODULE_SOURCE_DIR="$(find /usr/lib /usr/lib64 -maxdepth 5 -type d -path '*/gio/modules' 2>/dev/null | head -n1)"
fi
copy_directory_if_present "$GIO_MODULE_SOURCE_DIR" "$GIO_MODULE_DIR"
GDK_PIXBUF_SOURCE_DIR="$(find_pkg_config_dir gdk_pixbuf_moduledir gdk-pixbuf-2.0 || true)"
if [ -z "$GDK_PIXBUF_SOURCE_DIR" ]; then
GDK_PIXBUF_SOURCE_DIR="$(find /usr/lib /usr/lib64 -maxdepth 6 -type d -path '*/gdk-pixbuf-2.0/*/loaders' 2>/dev/null | head -n1)"
fi
copy_directory_if_present "$GDK_PIXBUF_SOURCE_DIR" "$GDK_PIXBUF_DIR"
GLIB_SCHEMAS_SOURCE_DIR="$(find_pkg_config_dir schemasdir gio-2.0 || true)"
if [ -z "$GLIB_SCHEMAS_SOURCE_DIR" ]; then
GLIB_SCHEMAS_SOURCE_DIR="/usr/share/glib-2.0/schemas"
fi
copy_directory_if_present "$GLIB_SCHEMAS_SOURCE_DIR" "$SHARE_DIR/glib-2.0/schemas"
if [ -d "$SHARE_DIR/glib-2.0/schemas" ] && command -v glib-compile-schemas >/dev/null 2>&1; then
glib-compile-schemas "$SHARE_DIR/glib-2.0/schemas"
fi
# Distros disagree on where helper executables live: pkg-config may point to libexec,
# Debian/Ubuntu often ship the scanner under a multiarch libdir, and RPM distros may use lib64.
GST_PLUGIN_SCANNER_SOURCE="$(find_first_existing_file \
"$(find_pkg_config_dir pluginscannerdir gstreamer-1.0 || true)/gst-plugin-scanner" \
/usr/libexec/gstreamer-1.0/gst-plugin-scanner \
/usr/lib/gstreamer1.0/gstreamer-1.0/gst-plugin-scanner \
/usr/lib/*/gstreamer1.0/gstreamer-1.0/gst-plugin-scanner \
/usr/lib64/gstreamer1.0/gstreamer-1.0/gst-plugin-scanner)" || true
if [ -n "$GST_PLUGIN_SCANNER_SOURCE" ]; then
mkdir -p "$LIBEXEC_DIR/gstreamer-1.0"
cp -fL "$GST_PLUGIN_SCANNER_SOURCE" "$LIBEXEC_DIR/gstreamer-1.0/gst-plugin-scanner"
fi
# Prefer the canonical pkg-config-reported helper path, but keep PATH-based fallbacks
# for distros exposing gdk-pixbuf-query-loaders or gdk-pixbuf-query-loaders-64 directly.
GDK_PIXBUF_QUERY_LOADERS_SOURCE="$(find_first_existing_file \
"$(pkg-config --variable=gdk_pixbuf_query_loaders gdk-pixbuf-2.0 2>/dev/null || true)" \
"$(command -v gdk-pixbuf-query-loaders 2>/dev/null || true)" \
"$(command -v gdk-pixbuf-query-loaders-64 2>/dev/null || true)")" || true
if [ -n "$GDK_PIXBUF_QUERY_LOADERS_SOURCE" ]; then
cp -fL "$GDK_PIXBUF_QUERY_LOADERS_SOURCE" "$LIBEXEC_DIR/gdk-pixbuf-query-loaders"
fi
fi
# WebKitGTK helper binaries are resolved from distro-specific absolute paths
# baked into libwebkit2gtk. Bundling Ubuntu's WebKitGTK inside an AppImage
# built with -g makes those helper paths unusable on Fedora and vice versa,
# so rely on the host WebKitGTK runtime instead of copying the helper stack.
mapfile -d '' BUNDLE_TARGETS < <(find "$BIN_DIR" "$LIB_DIR" "$LIBEXEC_DIR" -type f -print0 2>/dev/null)
bundle_dependency_closure "$PRIVATE_LIB_DIR" "${BUNDLE_TARGETS[@]}"
cat << EOF >"$LIBEXEC_DIR/@SLIC3R_APP_CMD@-env"
#!/bin/sh
set -e
SELF_DIR=\$(CDPATH= cd -- "\$(dirname -- "\$0")" && pwd)
APPDIR="\${APPDIR:-\$(CDPATH= cd -- "\$SELF_DIR/.." && pwd)}"
USE_BUNDLED_WEBKITGTK_STACK=0
if [ -e "\$APPDIR/lib/libwebkit2gtk-4.1.so.0" ] || [ -e "\$APPDIR/lib/libwebkit2gtk-4.0.so.0" ]; then
USE_BUNDLED_WEBKITGTK_STACK=1
fi
export APPDIR
PRIVATE_LIB_DIR="\$APPDIR/lib/orca-runtime"
if [ -d "\$PRIVATE_LIB_DIR" ]; then
export LD_LIBRARY_PATH="\$PRIVATE_LIB_DIR:\$APPDIR/bin\${LD_LIBRARY_PATH:+:\$LD_LIBRARY_PATH}"
else
export LD_LIBRARY_PATH="\$APPDIR/bin\${LD_LIBRARY_PATH:+:\$LD_LIBRARY_PATH}"
fi
has_host_runtime_library() {
local lib_name="\$1"
local path
if command -v ldconfig >/dev/null 2>&1; then
if ldconfig -p 2>/dev/null | grep -Fq "\$lib_name ("; then
return 0
fi
fi
for path in \
/lib /lib64 /usr/lib /usr/lib64 \
/usr/lib/* /usr/lib64/* /lib/* /lib64/*; do
if [ -e "\$path/\$lib_name" ]; then
return 0
fi
done
return 1
}
target_missing_runtime_library() {
local target_bin="\$1"
local lib_name="\$2"
if [ -z "\$target_bin" ] || [ ! -e "\$target_bin" ]; then
return 1
fi
if command -v ldd >/dev/null 2>&1; then
if ldd "\$target_bin" 2>/dev/null | grep -Fq "\$lib_name => not found"; then
return 0
fi
fi
return 1
}
TARGET_BIN="\$1"
if target_missing_runtime_library "\$TARGET_BIN" "libOpenGL.so.0" || ! has_host_runtime_library "libOpenGL.so.0"; then
echo "Error: missing host OpenGL runtime library libOpenGL.so.0." >&2
echo "On Ubuntu/Pop!_OS/Debian, install: libopengl0" >&2
echo "On Arch/CachyOS, install: libglvnd" >&2
exit 1
fi
if [ "\$USE_BUNDLED_WEBKITGTK_STACK" = "1" ]; then
export LD_LIBRARY_PATH="\$APPDIR/lib\${LD_LIBRARY_PATH:+:\$LD_LIBRARY_PATH}"
export GST_PLUGIN_SYSTEM_PATH=""
export GST_PLUGIN_PATH="\$APPDIR/lib/gstreamer-1.0\${GST_PLUGIN_PATH:+:\$GST_PLUGIN_PATH}"
export GIO_EXTRA_MODULES="\$APPDIR/lib/gio/modules\${GIO_EXTRA_MODULES:+:\$GIO_EXTRA_MODULES}"
export XDG_DATA_DIRS="\$APPDIR/share\${XDG_DATA_DIRS:+:\$XDG_DATA_DIRS}"
if [ -d "\$APPDIR/share/glib-2.0/schemas" ]; then
export GSETTINGS_SCHEMA_DIR="\$APPDIR/share/glib-2.0/schemas"
fi
if [ -x "\$APPDIR/libexec/gstreamer-1.0/gst-plugin-scanner" ]; then
export GST_PLUGIN_SCANNER="\$APPDIR/libexec/gstreamer-1.0/gst-plugin-scanner"
fi
if [ -d "\$APPDIR/lib/gdk-pixbuf-2.0/2.10.0/loaders" ]; then
export GDK_PIXBUF_MODULEDIR="\$APPDIR/lib/gdk-pixbuf-2.0/2.10.0/loaders"
if [ -x "\$APPDIR/libexec/gdk-pixbuf-query-loaders" ]; then
PIXBUF_CACHE_DIR="\${XDG_CACHE_HOME:-\$HOME/.cache}/@SLIC3R_APP_KEY@"
PIXBUF_CACHE_FILE="\$PIXBUF_CACHE_DIR/gdk-pixbuf-loaders.cache"
mkdir -p "\$PIXBUF_CACHE_DIR"
if [ ! -s "\$PIXBUF_CACHE_FILE" ] || find "\$APPDIR/lib/gdk-pixbuf-2.0/2.10.0/loaders" -type f -newer "\$PIXBUF_CACHE_FILE" | grep -q .; then
"\$APPDIR/libexec/gdk-pixbuf-query-loaders" "\$APPDIR/lib/gdk-pixbuf-2.0/2.10.0/loaders"/*.so > "\$PIXBUF_CACHE_FILE" 2>/dev/null || true
fi
if [ -s "\$PIXBUF_CACHE_FILE" ]; then
export GDK_PIXBUF_MODULE_FILE="\$PIXBUF_CACHE_FILE"
fi
fi
fi
if [ -d "\$APPDIR/lib/webkit2gtk-4.1" ]; then
export WEBKIT_EXEC_PATH="\$APPDIR/lib/webkit2gtk-4.1"
elif [ -d "\$APPDIR/lib/webkit2gtk-4.0" ]; then
export WEBKIT_EXEC_PATH="\$APPDIR/lib/webkit2gtk-4.0"
fi
if [ -d "\$APPDIR/lib/webkit2gtk-4.1/injected-bundle" ]; then
export WEBKIT_INJECTED_BUNDLE_PATH="\$APPDIR/lib/webkit2gtk-4.1/injected-bundle"
elif [ -d "\$APPDIR/lib/webkit2gtk-4.0/injected-bundle" ]; then
export WEBKIT_INJECTED_BUNDLE_PATH="\$APPDIR/lib/webkit2gtk-4.0/injected-bundle"
fi
else
if target_missing_runtime_library "\$TARGET_BIN" "libwebkit2gtk-4.1.so.0" || \
target_missing_runtime_library "\$TARGET_BIN" "libjavascriptcoregtk-4.1.so.0" || \
! has_host_runtime_library "libwebkit2gtk-4.1.so.0" || \
! has_host_runtime_library "libjavascriptcoregtk-4.1.so.0"; then
echo "Error: missing host WebKitGTK 4.1 runtime libraries." >&2
echo "Install the distro package providing libwebkit2gtk-4.1.so.0 and libjavascriptcoregtk-4.1.so.0." >&2
echo "On Arch/CachyOS, install: webkit2gtk-4.1" >&2
exit 1
fi
fi
exec "\$@"
EOF
chmod a+x "$LIBEXEC_DIR/@SLIC3R_APP_CMD@-env"
cat << EOF >@SLIC3R_APP_CMD@
#!/bin/bash
DIR=\$(dirname "\$(readlink -f "\$0")")
export APPDIR="\${APPDIR:-\$DIR}"
# FIXME: OrcaSlicer segfault workarounds
# 1) OrcaSlicer will segfault on systems where locale info is not as expected (i.e. Holo-ISO arch-based distro)
export LC_ALL=C
if [ "\$XDG_SESSION_TYPE" = "wayland" ] && [ "\$ZINK_DISABLE_OVERRIDE" != "1" ]; then
if command -v glxinfo >/dev/null 2>&1; then
RENDERER=\$(glxinfo | grep "OpenGL renderer string:" | sed 's/.*: //')
if echo "\$RENDERER" | grep -qi "NVIDIA"; then
if command -v nvidia-smi >/dev/null 2>&1; then
DRIVER_VERSION=\$(nvidia-smi --query-gpu=driver_version --format=csv,noheader | head -n1)
DRIVER_MAJOR=\$(echo "\$DRIVER_VERSION" | cut -d. -f1)
[ "\$DRIVER_MAJOR" -gt 555 ] && ZINK_FORCE_OVERRIDE=1
fi
if [ "\$ZINK_FORCE_OVERRIDE" = "1" ]; then
export __GLX_VENDOR_LIBRARY_NAME=mesa
export __EGL_VENDOR_LIBRARY_FILENAMES=/usr/share/glvnd/egl_vendor.d/50_mesa.json
export MESA_LOADER_DRIVER_OVERRIDE=zink
export GALLIUM_DRIVER=zink
# WebKit's NVIDIA DMABUF workaround is applied by the binary itself,
# gated on the runtime WebKitGTK version (src/OrcaSlicer.cpp).
fi
fi
fi
fi
exec "\$DIR/libexec/@SLIC3R_APP_CMD@-env" "\$DIR/bin/@SLIC3R_APP_CMD@" "\$@"
EOF
chmod ug+x @SLIC3R_APP_CMD@
cp -fl @SLIC3R_APP_CMD@ "$APPDIR/@SLIC3R_APP_CMD@"
if [ -x "${CHECK_SCRIPT}" ] && [ -z "${ORCA_SKIP_APPIMAGE_AUDIT}" ]; then
"${CHECK_SCRIPT}" "$APPDIR" "$BIN_DIR/@SLIC3R_APP_CMD@"
fi
# } &> $ROOT/Build.log # Capture all command output
echo "done"
if [[ -n "$BUILD_IMAGE" ]]
then
echo -n "Creating Appimage for distribution..."
# {
rm -rf package_appimage
cp -Rf package package_appimage
pushd package_appimage > /dev/null
chmod +x ../build_appimage.sh
if ../build_appimage.sh; then
popd > /dev/null
mv package_appimage/"@SLIC3R_APP_KEY@_Linux_V@SoftFever_VERSION@.AppImage" "@SLIC3R_APP_KEY@_Linux_V@SoftFever_VERSION@.AppImage"
rm -fR package_appimage
else
popd > /dev/null
fi
# } &> $ROOT/Build.log # Capture all command output
echo "done"
fi