package-release.sh refuses a package whose ELF files need newer glibc or OpenSSL symbol versions than the Frame has (D35); only the version needs section counts. The Qt bundler resolved libmosquitto's dependencies and shipped Debian's OpenSSL 3.5; libssl/libcrypto are now excluded, since SteamOS provides OpenSSL 3. Phase 3 of iteration 2 is done; PROGRESS.md has the manual checklist for phase 4. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
134 lines
5.8 KiB
Bash
Executable File
134 lines
5.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Builds the dashboard for the Steam Frame (aarch64) and packages it for release:
|
|
#
|
|
# dist/<executable>-<version>-linux-arm64/ uses SteamOS's Qt (default, ~3 MB)
|
|
# dist/<executable>-<version>-linux-arm64-bundled/ Qt bundled (--bundle-qt, ~46 MB)
|
|
# (each also as .tar.gz)
|
|
#
|
|
# The package contains only the dashboard itself plus install.sh,
|
|
# uninstall.sh and a README. Installing again over an existing installation updates it.
|
|
#
|
|
# scripts/package-release.sh [--bundle-qt] [--no-build]
|
|
set -euo pipefail
|
|
|
|
root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
build=1 bundle_qt=0
|
|
for arg in "$@"; do
|
|
case "$arg" in
|
|
--no-build) build=0 ;;
|
|
--bundle-qt) bundle_qt=1 ;;
|
|
*) echo "usage: $0 [--bundle-qt] [--no-build]" >&2; exit 2 ;;
|
|
esac
|
|
done
|
|
if [[ "$(uname -m)" == aarch64 ]]; then mode=native; else mode=cross; fi
|
|
if (( bundle_qt )); then
|
|
mode+=-bundle
|
|
[[ "$mode" == native-bundle ]] && preset=native-bundle || preset=cross-arm64-bundle
|
|
else
|
|
[[ "$mode" == native ]] && preset=native-systemqt || preset=cross-arm64
|
|
fi
|
|
|
|
(( build )) && "$root/scripts/container-build.sh" "$mode"
|
|
|
|
cache="$root/build/$preset/CMakeCache.txt"
|
|
setting() { sed -n "s/^$1:[A-Z]*=//p" "$cache"; }
|
|
exe="$(setting VRDASH_EXECUTABLE_NAME)"
|
|
name="$(setting VRDASH_DISPLAY_NAME)"
|
|
key="$(setting VRDASH_APP_KEY)"
|
|
version="$(setting CMAKE_PROJECT_VERSION)"
|
|
project="$(setting CMAKE_PROJECT_NAME)"
|
|
stage="$root/build/$preset/stage"
|
|
[[ "$(file -b "$stage/bin/$exe")" == *aarch64* ]] || { echo "$stage/bin/$exe is not an aarch64 build" >&2; exit 1; }
|
|
|
|
package="$exe-$version-linux-arm64"
|
|
(( bundle_qt )) && package+=-bundled
|
|
out="$root/dist/$package"
|
|
rm -rf "$out" "$out.tar.gz"
|
|
mkdir -p "$out"
|
|
cp -a "$stage/." "$out/"
|
|
# Only the dashboard: drop any other executables.
|
|
find "$out/bin" -maxdepth 1 -type f -perm -u+x ! -name "$exe" -delete
|
|
cp "$root/LICENSE" "$out/"
|
|
|
|
# Nothing shipped may need newer glibc or OpenSSL symbol versions than the Frame has
|
|
# (docs/DESIGN.md, D35; checked on the Frame 2026-10-05: glibc 2.39, OpenSSL 3.2.1). Catches a
|
|
# Debian update of a shipped library (libmosquitto, bundled Qt) that SteamOS can't run.
|
|
frame_max=(GLIBC_2.39 OPENSSL_3.2.0)
|
|
too_new=0
|
|
while IFS= read -r -d '' file; do
|
|
[[ "$(file -b "$file")" == ELF* ]] || continue
|
|
# Only the "needs" section: a library's own version definitions (e.g. libssl defining
|
|
# OPENSSL_3.5.0) are not needed from the system.
|
|
for needed in $(readelf -V --wide "$file" |
|
|
awk '/^Version needs section/ {n = 1; next} /^Version/ {n = 0} n' |
|
|
grep -oE "Name: (GLIBC|OPENSSL)_[0-9.]+" | cut -d' ' -f2 | sort -u); do
|
|
for max in "${frame_max[@]}"; do
|
|
[[ "${max%%_*}" == "${needed%%_*}" ]] || continue
|
|
if [[ "$(printf '%s\n%s\n' "$needed" "$max" | sort -V | tail -1)" != "$max" ]]; then
|
|
echo "${file#"$out"/} needs $needed; the Frame has at most $max" >&2
|
|
too_new=1
|
|
fi
|
|
done
|
|
done
|
|
done < <(find "$out" -type f -print0)
|
|
(( too_new )) && { echo "Package not usable on the Frame" >&2; exit 1; }
|
|
|
|
cat > "$out/install.sh" <<EOF
|
|
#!/bin/sh
|
|
# Installs or updates $name: registers it with SteamVR (starts automatically with
|
|
# SteamVR) and starts it now. SteamVR must be running. Works over SSH.
|
|
cd "\$(dirname "\$0")" || exit 1
|
|
mkdir -p logs
|
|
# An update replaces the files of a running instance: stop it, SteamVR restarts it below.
|
|
# (Match the command line: process names are cut to 15 characters.)
|
|
pkill -f "/bin/$exe( |\\$)" 2>/dev/null && sleep 1
|
|
exec ./bin/$exe --install-manifest --launch --log-file logs/install.log
|
|
EOF
|
|
|
|
cat > "$out/uninstall.sh" <<EOF
|
|
#!/bin/sh
|
|
# Stops $name, removes its device from Home Assistant (clears its retained MQTT
|
|
# topics) and unregisters it from SteamVR. The folder can be deleted afterwards.
|
|
cd "\$(dirname "\$0")" || exit 1
|
|
mkdir -p logs
|
|
# Stopped first, so it can't publish itself again; the broker sends its last will at once.
|
|
pkill -f "/bin/$exe( |\\$)" 2>/dev/null && sleep 1
|
|
./bin/$exe --ha-remove --log-file logs/install.log ||
|
|
echo "Could not remove the device from Home Assistant (see logs/install.log); unregistering anyway." >&2
|
|
exec ./bin/$exe --uninstall-manifest --log-file logs/install.log
|
|
EOF
|
|
chmod +x "$out/install.sh" "$out/uninstall.sh"
|
|
|
|
{
|
|
echo "$name $version (SteamVR dashboard overlay, app key $key)"
|
|
echo
|
|
if (( bundle_qt )); then
|
|
echo "Self-contained build: Qt is included."
|
|
else
|
|
echo "Uses the system's Qt (SteamOS: Qt 6.8 or newer). If it fails to start after a"
|
|
echo "SteamOS update, use the -bundled package instead."
|
|
fi
|
|
echo
|
|
echo "Settings (required before the first start):"
|
|
echo " mkdir -p ~/.config/$project"
|
|
echo " cp share/$project/config.example.json ~/.config/$project/config.json"
|
|
echo " chmod 600 ~/.config/$project/config.json"
|
|
echo " then edit it (device name, MQTT broker, Home Assistant URL)."
|
|
echo " Without valid settings the app exits; the reason is in"
|
|
echo " logs/$exe.log."
|
|
echo
|
|
echo "Install / update: ./install.sh (SteamVR must be running)"
|
|
echo " SteamVR remembers this folder's location: after moving it,"
|
|
echo " run ./install.sh again."
|
|
echo "Uninstall: ./uninstall.sh (also removes the device from Home Assistant;"
|
|
echo " needs the settings file and the MQTT broker)"
|
|
echo "Logs: logs/$exe.log (the app), logs/install.log (install.sh);"
|
|
echo " run ./bin/$exe --help for options"
|
|
echo
|
|
echo "License: MIT (LICENSE). Third-party notices: share/doc/$project/."
|
|
} > "$out/README.txt"
|
|
|
|
tar -C "$root/dist" -czf "$out.tar.gz" "$package"
|
|
echo "Release folder: $out"
|
|
echo "Archive: $out.tar.gz ($(du -h "$out.tar.gz" | cut -f1))"
|