mirror of
https://github.com/Toastconcern/FrameStudio.git
synced 2026-10-29 04:02:56 +01:00
Frame Studio and Frame Home: cross-platform builds
Frame Studio now builds for Windows (x64, x86, ARM64), Linux (x64, x86, ARM64)
and macOS (Apple Silicon, Intel):
- studio/platform.h with Win32 and POSIX implementations (dialogs through
tinyfiledialogs on Linux/macOS), a GLFW window beside the Win32 one, and a
platform-neutral frame pacer
- MoltenVK support in the renderer (portability enumeration) and bundled in
the macOS app
- 32-bit builds: large-address-aware, LZMA packing within a 32-bit address space
- unaligned file reads in the loaders go through loadUnaligned (no UB)
- scripts/build-studio.sh, studio/build_windows.bat [x64|x86|arm64],
cmake/llvm-mingw.cmake, and a GitHub Actions workflow building every target
Frame Home installs without Studio: frame/install-frame-home.{sh,ps1} and
"Install Frame Home.bat" (packaged as FrameHome-installer.zip).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
commit
f7345a5ac3
1176 files changed
+1634784
No files matched your search
Executable
+109
@@ -0,0 +1,109 @@
|
||||
#!/bin/sh
|
||||
# Builds Frame Studio for one or more computers and packages each into dist/, ready to hand out.
|
||||
#
|
||||
# scripts/build-studio.sh TARGET... [--build-dir DIR]
|
||||
#
|
||||
# Targets (each needs the matching compiler; GitHub Actions builds all of them: .github/workflows/build.yml):
|
||||
# linux-x64 linux-x86 linux-arm64 on Linux: the native compiler (x86: gcc-multilib / g++-multilib); X11
|
||||
# headers (libx11-dev libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev)
|
||||
# windows-x64 windows-x86 windows-arm64 on Linux with llvm-mingw (cmake/llvm-mingw.cmake; $LLVM_MINGW)
|
||||
# (on Windows itself: studio\build_windows.bat x64|x86|arm64)
|
||||
# macos-arm64 macos-x64 on a Mac with Xcode's command line tools; MoltenVK is bundled into the
|
||||
# app from $MOLTENVK (a libMoltenVK.dylib) or Homebrew's molten-vk
|
||||
# frame-home the Steam Frame installer on its own (no Studio needed): the headset
|
||||
# files from frame/payload and the install scripts
|
||||
# all every target this computer can build
|
||||
# Output: dist/FrameStudio-<target>.zip (.tar.gz on Linux) and dist/FrameHome-installer.zip.
|
||||
set -eu
|
||||
ROOT=$(cd "$(dirname "$0")/.." && pwd)
|
||||
DIST="$ROOT/dist"
|
||||
BUILD="$ROOT/build"
|
||||
CMAKE=${CMAKE:-cmake}
|
||||
TARGETS=""
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--build-dir) BUILD=$2; shift 2 ;;
|
||||
-h|--help) sed -n '2,19p' "$0"; exit 0 ;;
|
||||
*) TARGETS="$TARGETS $1"; shift ;;
|
||||
esac
|
||||
done
|
||||
[ -n "$TARGETS" ] || { sed -n '2,19p' "$0"; exit 1; }
|
||||
mkdir -p "$DIST" "$BUILD"
|
||||
say() { echo "build-studio: $*"; }
|
||||
|
||||
if [ "$TARGETS" = " all" ]; then
|
||||
case "$(uname -s)" in
|
||||
Darwin) TARGETS="macos-arm64 macos-x64 frame-home" ;;
|
||||
*) case "$(uname -m)" in
|
||||
aarch64|arm64) TARGETS="linux-arm64 frame-home" ;;
|
||||
*) TARGETS="linux-x64 linux-x86 frame-home" ;;
|
||||
esac
|
||||
[ -x "${LLVM_MINGW:-$HOME/.local/opt/llvm-mingw}/bin/x86_64-w64-mingw32-clang" ] && TARGETS="$TARGETS windows-x64 windows-x86 windows-arm64" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# configure + build one target; $1 target, then extra cmake arguments
|
||||
build() {
|
||||
target=$1; shift
|
||||
dir="$BUILD/$target"
|
||||
say "building $target"
|
||||
"$CMAKE" -S "$ROOT/studio" -B "$dir" -DCMAKE_BUILD_TYPE=Release "$@" > "$dir.configure.log" 2>&1 || {
|
||||
tail -20 "$dir.configure.log"; say "$target: configure failed (full log: $dir.configure.log)"; exit 1; }
|
||||
"$CMAKE" --build "$dir" --target frame-studio --parallel
|
||||
}
|
||||
|
||||
# dist/FrameStudio-<target>: the program and, beside it, frame/ (the headset side Studio installs)
|
||||
package() {
|
||||
target=$1 dir="$BUILD/$1" name="FrameStudio-$1"
|
||||
stage="$BUILD/stage/$name"
|
||||
rm -rf "$stage" && mkdir -p "$stage"
|
||||
case "$target" in
|
||||
windows-*) cp "$dir/Frame Studio.exe" "$stage/" && cp -R "$dir/frame" "$stage/frame"
|
||||
(cd "$BUILD/stage" && rm -f "$DIST/$name.zip" && zip -qr "$DIST/$name.zip" "$name") ;;
|
||||
linux-*) cp "$dir/Frame Studio" "$stage/" && cp -R "$dir/frame" "$stage/frame"
|
||||
tar -czf "$DIST/$name.tar.gz" -C "$BUILD/stage" "$name" ;;
|
||||
macos-*) cp -R "$dir/Frame Studio.app" "$stage/"
|
||||
bundle_moltenvk "$stage/Frame Studio.app"
|
||||
(cd "$BUILD/stage" && rm -f "$DIST/$name.zip" && ditto -c -k --keepParent "$name" "$DIST/$name.zip") ;;
|
||||
esac
|
||||
say "$target -> dist/$(ls "$DIST" | grep "^$name\." | head -1)"
|
||||
}
|
||||
|
||||
# MoltenVK (Vulkan on Metal) inside the app: Contents/Frameworks/libMoltenVK.dylib, which Studio loads itself when
|
||||
# the Mac has no Vulkan loader installed.
|
||||
bundle_moltenvk() {
|
||||
app=$1
|
||||
lib=${MOLTENVK:-}
|
||||
[ -n "$lib" ] || { command -v brew > /dev/null && lib="$(brew --prefix molten-vk 2>/dev/null)/lib/libMoltenVK.dylib"; } || true
|
||||
if [ -n "$lib" ] && [ -f "$lib" ]; then
|
||||
mkdir -p "$app/Contents/Frameworks" && cp "$lib" "$app/Contents/Frameworks/"
|
||||
else
|
||||
say "warning: no MoltenVK found (set MOLTENVK or: brew install molten-vk): the app needs the Vulkan SDK installed to run"
|
||||
fi
|
||||
}
|
||||
|
||||
# dist/FrameHome-installer.zip: Frame Home for the Steam Frame, installed without Frame Studio
|
||||
package_frame_home() {
|
||||
stage="$BUILD/stage/FrameHome-installer"
|
||||
rm -rf "$stage" && mkdir -p "$stage"
|
||||
cp -R "$ROOT/frame/payload" "$stage/payload"
|
||||
cp "$ROOT/frame/install-frame-home.sh" "$ROOT/frame/install-frame-home.ps1" "$ROOT/frame/Install Frame Home.bat" "$ROOT/frame/README-frame-home.txt" "$stage/"
|
||||
chmod +x "$stage/install-frame-home.sh" "$stage/payload/install.sh" "$stage"/payload/bin/* 2>/dev/null || true
|
||||
(cd "$BUILD/stage" && rm -f "$DIST/FrameHome-installer.zip" && zip -qr "$DIST/FrameHome-installer.zip" FrameHome-installer)
|
||||
say "frame-home -> dist/FrameHome-installer.zip"
|
||||
}
|
||||
|
||||
for t in $TARGETS; do
|
||||
case "$t" in
|
||||
linux-x64|linux-arm64) build "$t" -G Ninja && package "$t" ;;
|
||||
linux-x86) build "$t" -G Ninja -DCMAKE_C_FLAGS=-m32 -DCMAKE_CXX_FLAGS=-m32 -DCMAKE_SYSTEM_PROCESSOR=i686 \
|
||||
-DCMAKE_LIBRARY_ARCHITECTURE=i386-linux-gnu && package "$t" ;;
|
||||
windows-x64) build "$t" -G Ninja -DCMAKE_TOOLCHAIN_FILE="$ROOT/cmake/llvm-mingw.cmake" -DWINDOWS_ARCH=x86_64 && package "$t" ;;
|
||||
windows-x86) build "$t" -G Ninja -DCMAKE_TOOLCHAIN_FILE="$ROOT/cmake/llvm-mingw.cmake" -DWINDOWS_ARCH=i686 && package "$t" ;;
|
||||
windows-arm64) build "$t" -G Ninja -DCMAKE_TOOLCHAIN_FILE="$ROOT/cmake/llvm-mingw.cmake" -DWINDOWS_ARCH=aarch64 && package "$t" ;;
|
||||
macos-arm64) build "$t" -G Ninja -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 && package "$t" ;;
|
||||
macos-x64) build "$t" -G Ninja -DCMAKE_OSX_ARCHITECTURES=x86_64 -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 && package "$t" ;;
|
||||
frame-home) package_frame_home ;;
|
||||
*) say "unknown target: $t (see --help)"; exit 1 ;;
|
||||
esac
|
||||
done
|
||||
Reference in new issue
Block a user