Initial FrameAssistant baseline from the vrdashboard template
Template stripped to the overlay platform (examples, demo UI and Frame test package removed), renamed to FrameAssistant, and working rules for the project recorded in CLAUDE.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Executable
+50
@@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env bash
|
||||
# Builds the app inside a Debian container and stages an install in build/<preset>/stage,
|
||||
# ready to copy to the Steam Frame.
|
||||
#
|
||||
# scripts/container-build.sh cross x86_64 host → aarch64, uses the target's
|
||||
# system Qt 6.8.x (default way to deploy)
|
||||
# scripts/container-build.sh native same for the host's own architecture
|
||||
# (run on the Frame for a native arm64 build)
|
||||
# scripts/container-build.sh cross-bundle / native-bundle
|
||||
# self-contained: Qt bundled (fallback if the
|
||||
# target's Qt doesn't fit)
|
||||
# scripts/container-build.sh <mode> shell interactive shell in that container
|
||||
#
|
||||
# Uses podman if available, else docker (override with CONTAINER_ENGINE).
|
||||
set -euo pipefail
|
||||
|
||||
root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
mode="${1:-}"
|
||||
case "$mode" in
|
||||
cross) dockerfile=cross-arm64.Dockerfile; preset=cross-arm64 ;;
|
||||
native) dockerfile=native.Dockerfile; preset=native-systemqt ;;
|
||||
cross-bundle) dockerfile=cross-arm64.Dockerfile; preset=cross-arm64-bundle ;;
|
||||
native-bundle) dockerfile=native.Dockerfile; preset=native-bundle ;;
|
||||
*) echo "usage: $0 cross|native|cross-bundle|native-bundle [shell]" >&2; exit 2 ;;
|
||||
esac
|
||||
image="frameassistant-build-${dockerfile%.Dockerfile}"
|
||||
engine="${CONTAINER_ENGINE:-$(command -v podman || command -v docker)}"
|
||||
|
||||
"$engine" build -q -t "$image" -f "$root/docker/$dockerfile" "$root/docker" >/dev/null
|
||||
|
||||
run=("$engine" run --rm -v "$root:$root:z" -w "$root")
|
||||
if [[ "$(basename "$engine")" == docker ]]; then
|
||||
run+=(--user "$(id -u):$(id -g)")
|
||||
else
|
||||
run+=(--userns=keep-id)
|
||||
fi
|
||||
[[ -t 0 ]] && run+=(-it)
|
||||
|
||||
if [[ "${2:-}" == shell ]]; then
|
||||
exec "${run[@]}" "$image" bash
|
||||
fi
|
||||
|
||||
"${run[@]}" "$image" bash -c "
|
||||
set -e
|
||||
cmake --preset $preset
|
||||
cmake --build --preset $preset
|
||||
rm -rf build/$preset/stage
|
||||
cmake --install build/$preset --prefix build/$preset/stage
|
||||
"
|
||||
echo "Staged: $root/build/$preset/stage"
|
||||
Executable
+41
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env bash
|
||||
# Builds and runs all tests in a Debian container with BOTH render backends, Vulkan with the
|
||||
# Khronos validation layers enabled. Fails on any validation message.
|
||||
#
|
||||
# scripts/container-test.sh GPU via /dev/dri if available, otherwise software
|
||||
# VK_DRIVER=lvp scripts/container-test.sh force lavapipe (software Vulkan)
|
||||
set -euo pipefail
|
||||
|
||||
root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
engine="${CONTAINER_ENGINE:-$(command -v podman || command -v docker)}"
|
||||
"$engine" build -q -t frameassistant-build-native -f "$root/docker/native.Dockerfile" "$root/docker" >/dev/null
|
||||
"$engine" build -q -t frameassistant-test -f "$root/docker/test.Dockerfile" "$root/docker" >/dev/null
|
||||
|
||||
run=("$engine" run --rm -v "$root:$root:z" -w "$root" -e HOME=/tmp -e "VK_DRIVER=${VK_DRIVER:-}")
|
||||
if [[ "$(basename "$engine")" == docker ]]; then
|
||||
run+=(--user "$(id -u):$(id -g)")
|
||||
else
|
||||
run+=(--userns=keep-id)
|
||||
fi
|
||||
[[ -e /dev/dri/renderD128 ]] && run+=(--device /dev/dri/renderD128)
|
||||
|
||||
"${run[@]}" frameassistant-test bash -c '
|
||||
set -e
|
||||
cmake -S . -B build/container-test -G Ninja -DCMAKE_BUILD_TYPE=Debug -DVRDASH_VULKAN=ON >/dev/null
|
||||
cmake --build build/container-test
|
||||
if [[ -n "$VK_DRIVER" ]]; then export VK_DRIVER_FILES=/usr/share/vulkan/icd.d/${VK_DRIVER}_icd.json; fi
|
||||
vulkaninfo --summary 2>/dev/null | grep -m1 deviceName || true
|
||||
Xvfb :99 >/dev/null 2>&1 &
|
||||
sleep 1
|
||||
export DISPLAY=:99 VRDASH_VULKAN_VALIDATION=1
|
||||
ctest --test-dir build/container-test --output-on-failure -V > build/container-test/ctest.log 2>&1 \
|
||||
|| { tail -40 build/container-test/ctest.log; exit 1; }
|
||||
grep -E "tests passed|Test +#" build/container-test/ctest.log
|
||||
messages=$(grep -oE "(VUID|UNASSIGNED)-[A-Za-z0-9_.-]+" build/container-test/ctest.log | sort | uniq -c || true)
|
||||
if [[ -n "$messages" ]]; then
|
||||
echo "Vulkan validation messages (see build/container-test/ctest.log):"
|
||||
echo "$messages"
|
||||
exit 1
|
||||
fi
|
||||
echo "No Vulkan validation messages."
|
||||
'
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copies a release package to the Steam Frame over SSH and installs it there (registers
|
||||
# it with SteamVR and starts it; an existing installation in the same place is updated).
|
||||
# SteamVR must be running on the Frame.
|
||||
#
|
||||
# scripts/deploy-to-frame.sh <ssh-target> [package-dir] [remote-dir]
|
||||
# e.g. scripts/deploy-to-frame.sh steamos@frame
|
||||
#
|
||||
# package-dir defaults to the newest dist/*-linux-arm64 package (scripts/package-release.sh);
|
||||
# remote-dir defaults to the package's base name in the remote home directory.
|
||||
set -euo pipefail
|
||||
|
||||
target="${1:?usage: $0 <ssh-target> [package-dir] [remote-dir]}"
|
||||
root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
package="${2:-$(ls -dt "$root"/dist/*-linux-arm64 "$root"/dist/*-linux-arm64-bundled 2>/dev/null | head -1)}"
|
||||
[[ -n "$package" && -x "$package/install.sh" ]] || {
|
||||
echo "No release package found (run scripts/package-release.sh first)" >&2; exit 1; }
|
||||
# Without the version: updates go to the same place and replace the old version.
|
||||
remote="${3:-$(basename "$package" | sed -E 's/-[0-9][0-9.]*-linux-arm64(-bundled)?$//')}"
|
||||
|
||||
rsync -a --delete --exclude logs/ "$package/" "$target:$remote/"
|
||||
ssh "$target" "\$HOME/$remote/install.sh"
|
||||
echo "Installed $(basename "$package") to $target:~/$remote"
|
||||
Executable
+95
@@ -0,0 +1,95 @@
|
||||
#!/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/"
|
||||
|
||||
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
|
||||
# Unregisters $name from SteamVR and stops it. The folder can be deleted afterwards.
|
||||
cd "\$(dirname "\$0")" || exit 1
|
||||
pkill -f "/bin/$exe( |\\$)" 2>/dev/null
|
||||
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 "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"
|
||||
echo "Logs: logs/install.log; 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))"
|
||||
Reference in New Issue
Block a user