Compare commits

...
1 Commits
Author SHA1 Message Date
dijunkun ac8eff5099 [fix] bundle the matching Slint runtime in Linux packages 2026-11-12 14:05:45 +08:00
2 changed files with 38 additions and 36 deletions

No files matched your search

+28 -34
View File
@@ -47,37 +47,6 @@ normalize_app_version() {
fi
}
find_slint_runtime() {
local needed="$1"
local resolved=""
resolved="$(ldd "$BUILD_BINARY" 2>/dev/null | awk -v needed="$needed" \
'$1 == needed && $2 == "=>" && $3 ~ /^\// { print $3; exit }')"
if [[ -n "$resolved" && -f "$resolved" ]]; then
echo "$resolved"
return 0
fi
local package_roots=()
if [[ -n "${XMAKE_GLOBALDIR:-}" ]]; then
package_roots+=("$XMAKE_GLOBALDIR/.xmake/packages")
fi
package_roots+=("$HOME/.xmake/packages" "/data/.xmake/packages")
local package_root=""
local candidate=""
for package_root in "${package_roots[@]}"; do
[[ -d "$package_root/s/slint" ]] || continue
candidate="$(find "$package_root/s/slint" -path "*/lib/$needed" -print -quit 2>/dev/null || true)"
if [[ -n "$candidate" ]]; then
echo "$candidate"
return 0
fi
done
return 1
}
APP_VERSION="$(normalize_app_version "$INPUT_VERSION")"
DEB_VERSION="${APP_VERSION#v}"
if [[ ! "$DEB_VERSION" =~ ^[0-9][0-9A-Za-z.+:~_-]*$ ]]; then
@@ -127,9 +96,13 @@ fi
SLINT_NEEDED="$(readelf -d "$BUILD_BINARY" | sed -n \
's/.*Shared library: \[\(libslint_cpp[^]]*\)\].*/\1/p' | head -n 1)"
if [[ -n "$SLINT_NEEDED" ]]; then
SLINT_LIBRARY="$(find_slint_runtime "$SLINT_NEEDED" || true)"
if [[ -z "$SLINT_LIBRARY" ]]; then
echo "Unable to locate the required Slint runtime: $SLINT_NEEDED" >&2
# The build rule copies the exact linked package beside the executable.
# Never search global caches or trust the packager's LD_LIBRARY_PATH: an
# unpatched runtime can share both the version and SONAME of the linked one.
SLINT_LIBRARY="$(dirname "$BUILD_BINARY")/$SLINT_NEEDED"
if [[ ! -f "$SLINT_LIBRARY" ]]; then
echo "Missing build-matched Slint runtime: $SLINT_LIBRARY" >&2
echo "Build it first with: xmake b -vy crossdesk" >&2
exit 1
fi
install -m 0755 "$SLINT_LIBRARY" "$PRIVATE_DIR/$SLINT_NEEDED"
@@ -138,6 +111,27 @@ if [[ -n "$SLINT_NEEDED" ]]; then
strip --strip-unneeded "$PRIVATE_DIR/$SLINT_NEEDED"
fi
# Check the staged files with only their private runtime directory available.
# ldd -r can exit successfully even when it reports unresolved symbols, so its
# diagnostics must also be checked. This does not start the GUI or updater.
for executable in crossdesk-bin crossdesk_updater; do
dependency_report="$WORK_DIR/$executable.ldd"
if ! env -u LD_PRELOAD -u LD_AUDIT LD_LIBRARY_PATH="$PRIVATE_DIR" \
ldd -r "$PRIVATE_DIR/$executable" > "$dependency_report" 2>&1 || \
grep -Eq 'not found|undefined symbol:' "$dependency_report"; then
echo "Packaged runtime dependency check failed: $executable" >&2
cat "$dependency_report" >&2
exit 1
fi
done
if [[ -n "$SLINT_NEEDED" ]]; then
if ! grep -Fq "$SLINT_NEEDED => $PRIVATE_DIR/$SLINT_NEEDED (" "$WORK_DIR/crossdesk-bin.ldd"; then
echo "Packaged executable does not load its private Slint runtime" >&2
cat "$WORK_DIR/crossdesk-bin.ldd" >&2
exit 1
fi
fi
cat > "$BIN_DIR/$PKG_NAME" <<'EOF'
#!/bin/sh
private_lib_dir="/usr/lib/crossdesk"
+10 -2
View File
@@ -20,7 +20,7 @@ function setup_targets()
"CROSSDESK_VERSION_NUMERIC=" .. table.concat(version_parts, ","))
local function copy_slint_runtime(target)
if not target:is_plat("windows") then
if not target:is_plat("windows", "linux") then
return
end
@@ -28,8 +28,16 @@ function setup_targets()
if not slint and target:dep("gui") then
slint = target:dep("gui"):pkg("slint")
end
assert(slint, "the Slint package is required to copy its Windows runtime")
assert(slint, "the Slint package is required to copy its runtime")
local runtime_dir = path.join(slint:installdir(), "lib")
if target:is_plat("linux") then
-- Package the runtime selected for this build. Multiple Slint builds
-- with the same version/SONAME can have different patched APIs.
local runtime_so = path.join(runtime_dir, "libslint_cpp.so")
assert(os.isfile(runtime_so), "Slint runtime not found: " .. runtime_so)
os.cp(runtime_so, target:targetdir())
return
end
local runtime_dll = path.join(runtime_dir, "slint_cpp.dll")
assert(os.isfile(runtime_dll), "Slint runtime not found: " .. runtime_dll)
import("utils.binary.deplibs")