mirror of
https://github.com/SpeedBreakerProject/speedbreaker.git
synced 2026-10-18 08:01:27 +02:00
Co-authored-by: Lydacious <81742991+lydacious@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
336 lines
18 KiB
Bash
Executable File
336 lines
18 KiB
Bash
Executable File
#!/bin/bash
|
|
# SpeedBreaker: a self-contained SteamOS build (for a Steam Deck, a Steam
|
|
# Machine or a Steam Frame) that needs no distrobox and no compiler. Run it
|
|
# inside the nfsmw-build distrobox after building, or on the Steam Frame
|
|
# itself (README.md here):
|
|
#
|
|
# scripts/steamos/make_bundle.sh [build dir] [output dir]
|
|
#
|
|
# (defaults build/main and build/bundle). It makes <output>/SpeedBreaker/ and
|
|
# the release download <output>/SpeedBreaker-steamos-<x86_64 or arm64>.tar.xz
|
|
# (plus .sha256), with a copy named by the version,
|
|
# SpeedBreaker-<version>-steamos-<arch>.tar.xz (a hard link; its own .sha256):
|
|
# the game, the libraries it needs that SteamOS doesn't provide at the
|
|
# versions it was built against, the launcher (bundle/speedbreaker.sh), the
|
|
# player's README (bundle/README.md, or bundle/README-steam-frame.md for
|
|
# arm64) and licenses. Never any game data: players install from their own
|
|
# disc image on the first run.
|
|
#
|
|
# The launcher is the only program at the top of the folder: the game is
|
|
# lib/SpeedBreaker, beside its libraries (since v0.1.1; v0.1.0 had it at the
|
|
# top, where a player ran it directly and got "GLIBC_2.44 not found", since
|
|
# only the launcher picks the C library it needs). A v0.1.1 folder unpacked
|
|
# over a v0.1.0 one still holds v0.1.0's SpeedBreaker at the top: the
|
|
# launcher removes it at its first start.
|
|
#
|
|
# The game's binary has its debug information stripped (its symbol table
|
|
# stays: crash reports name functions with it, and the recompiled ones with
|
|
# the game's own table either way). The full symbols go to
|
|
# <output>/symbols/SpeedBreaker-<version>-<commit>-steamos-<arch>.debug, for
|
|
# us: never published, they map a player's report back to the exact build.
|
|
#
|
|
# Which libraries go in (ldd of the binary, sorted by soname):
|
|
# - From the system, never bundled: the Vulkan loader, which must find the
|
|
# system's GPU drivers and Steam's and gamescope's layers, and everything
|
|
# SDL loads at run time (X11, Wayland, PipeWire, PulseAudio, ALSA, udev,
|
|
# D-Bus), which must match the system's display and audio servers. SteamOS
|
|
# has them all; in a distrobox this script checks the host's copies
|
|
# (/run/host) and says which are missing.
|
|
# - x86-64: the C and C++ runtimes, in lib/glibc and lib/cxx. The distrobox is
|
|
# rolling Arch: its builds need glibc 2.44 (sinh and cosh got new symbol
|
|
# versions; SDL 3.4 needs 2.43) and GLIBCXX_3.4.35, where SteamOS 3.8 has
|
|
# glibc 2.41 and GLIBCXX_3.4.34. Building against an older baseline would
|
|
# need another toolchain and SDL 3.4 rebuilt; instead the launcher runs the
|
|
# game through the bundled loader, each runtime only while the system's is
|
|
# older.
|
|
# - arm64 (built on the Steam Frame, against its own SteamOS): no C or C++
|
|
# runtime. The system's are the ones it was built against, and the check
|
|
# below holds the build to them.
|
|
# - Everything else (SDL3, glslang, SPIRV-Tools, and whatever the binary links
|
|
# later) in lib/: SteamOS lacks glslang and ships SDL 3.2 and another
|
|
# release of SPIRV-Tools, whose soname carries no version.
|
|
set -euo pipefail
|
|
# x86-64 in the nfsmw-build distrobox (Steam Deck, Steam Machine), or arm64 on
|
|
# the Steam Frame itself (its SteamOS has the compilers; see README.md).
|
|
case "$(uname -s)-$(uname -m)" in
|
|
Linux-x86_64) ARCH=x86_64 LOADER=ld-linux-x86-64.so.2 HOST_LOADER=/lib64/ld-linux-x86-64.so.2 RUNTIMES=bundled README=README.md ;;
|
|
Linux-aarch64) ARCH=arm64 LOADER=ld-linux-aarch64.so.1 HOST_LOADER=/lib/ld-linux-aarch64.so.1 RUNTIMES=system README=README-steam-frame.md ;;
|
|
*) echo "make_bundle.sh: x86-64 or arm64 Linux only" >&2; exit 1 ;;
|
|
esac
|
|
SCRIPTS="$(cd "$(dirname "$(readlink -f "$0")")" && pwd)"
|
|
ROOT="$(cd "$SCRIPTS/../.." && pwd)"
|
|
BUILD="$(readlink -f "${1:-$ROOT/build/main}")"
|
|
mkdir -p "${2:-$ROOT/build/bundle}"
|
|
OUT="$(readlink -f "${2:-$ROOT/build/bundle}")"
|
|
BIN="$BUILD/runtime/SpeedBreaker"
|
|
NAME=SpeedBreaker
|
|
STAGE="$OUT/$NAME"
|
|
|
|
[ -x "$BIN" ] || { echo "make_bundle.sh: no $BIN; build first (scripts/steamos/README.md)" >&2; exit 1; }
|
|
# The sources the binary was built from (licenses, version): the build's own.
|
|
SRC="$(sed -n 's/^CMAKE_HOME_DIRECTORY:INTERNAL=//p' "$BUILD/CMakeCache.txt" 2>/dev/null || true)"
|
|
[ -d "$SRC" ] || SRC="$ROOT"
|
|
TYPE="$(sed -n 's/^CMAKE_BUILD_TYPE:STRING=//p' "$BUILD/CMakeCache.txt" 2>/dev/null || true)"
|
|
[ "$TYPE" = Release ] || echo "make_bundle.sh: warning: build type '${TYPE:-unknown}', not Release" >&2
|
|
# The version and commit the build compiled in (runtime/report/build_info.cmake),
|
|
# not the checkout's state now.
|
|
INFO="$BUILD/runtime/generated/build_info.inc"
|
|
define() { sed -n "s/^#define NFSMW_BUILD_$1 \"\{0,1\}\([^\"]*\)\"\{0,1\}\$/\1/p" "$INFO" 2>/dev/null; }
|
|
VERSION="$(define VERSION)"
|
|
[ -n "$VERSION" ] || VERSION="$(sed -n 's/^CMAKE_PROJECT_VERSION:STATIC=//p' "$BUILD/CMakeCache.txt" 2>/dev/null || true)"
|
|
[[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || { echo "make_bundle.sh: no version in $BUILD (project() in CMakeLists.txt)" >&2; exit 1; }
|
|
COMMIT="$(define COMMIT)"
|
|
[ "$(define DIRTY)" = 1 ] && COMMIT="$COMMIT-dirty"
|
|
case "$COMMIT" in
|
|
"" | unknown*) echo "make_bundle.sh: warning: the build doesn't know its commit" >&2 ;;
|
|
*-dirty) echo "make_bundle.sh: warning: the build is $COMMIT (uncommitted changes): not for release" >&2 ;;
|
|
esac
|
|
|
|
# The stage is deleted and rebuilt, so it must be one of ours: with ~ as the
|
|
# output folder it could be a folder of the player's (or a checkout of the
|
|
# repo). A bundle folder has the launcher and bundle-info.txt
|
|
# (an arm64 one has no lib/glibc).
|
|
if [ -e "$STAGE" ] && { [ -e "$STAGE/.git" ] || [ ! -f "$STAGE/speedbreaker.sh" ] || [ ! -f "$STAGE/bundle-info.txt" ]; }; then
|
|
echo "make_bundle.sh: $STAGE exists and isn't a bundle folder; not replacing it (give another output folder)" >&2
|
|
exit 1
|
|
fi
|
|
# A bundle folder someone played from in portable mode holds their saves (and
|
|
# maybe the game) in data/: never deleted here.
|
|
if [ -e "$STAGE/portable.txt" ] || [ -e "$STAGE/data" ]; then
|
|
echo "make_bundle.sh: $STAGE is a portable folder (portable.txt or data/: saves); not replacing it (give another output folder)" >&2
|
|
exit 1
|
|
fi
|
|
rm -rf "$STAGE"
|
|
mkdir -p "$STAGE/lib" "$STAGE/licenses"
|
|
[ "$RUNTIMES" = bundled ] && mkdir -p "$STAGE/lib/cxx" "$STAGE/lib/glibc"
|
|
|
|
# The binary without its debug information; the full symbols beside the bundle.
|
|
SYMBOLS="$OUT/symbols"
|
|
mkdir -p "$SYMBOLS"
|
|
OBJCOPY="$(command -v objcopy || command -v llvm-objcopy || true)"
|
|
[ -n "$OBJCOPY" ] || { echo "make_bundle.sh: no objcopy (binutils) to strip the binary" >&2; exit 1; }
|
|
DEBUG="SpeedBreaker-$VERSION-$COMMIT-steamos-$ARCH.debug"
|
|
"$OBJCOPY" --only-keep-debug "$BIN" "$SYMBOLS/$DEBUG"
|
|
GAME="$STAGE/lib/SpeedBreaker"
|
|
"$OBJCOPY" --strip-debug --add-gnu-debuglink="$SYMBOLS/$DEBUG" "$BIN" "$GAME"
|
|
# A build-time library path (a hand-built SDL3 in ~/deps) has no use in the
|
|
# bundle, which passes the loader its own lib/.
|
|
if readelf -d "$GAME" | grep -qE '\((RUNPATH|RPATH)\)'; then
|
|
if command -v patchelf > /dev/null; then
|
|
patchelf --remove-rpath "$GAME"
|
|
else
|
|
echo "make_bundle.sh: warning: the binary keeps its build's library path ($(readelf -d "$GAME" |
|
|
sed -n 's/.*(R[UN]*PATH).*\[\(.*\)\]/\1/p')): harmless (the launcher's lib/ comes first), but install patchelf to drop it" >&2
|
|
fi
|
|
fi
|
|
cp "$SCRIPTS/bundle/speedbreaker.sh" "$STAGE/"
|
|
cp "$SCRIPTS/bundle/$README" "$STAGE/README.md"
|
|
chmod 755 "$GAME" "$STAGE/speedbreaker.sh"
|
|
echo "SpeedBreaker v$VERSION ($COMMIT, built $(date -u -r "$BIN" +%F)), SteamOS $ARCH" > "$STAGE/VERSION"
|
|
|
|
# Sorted by soname; `ldd` lists the whole closure. A library the build found
|
|
# outside the system's folders (CMake's <Package>_DIR, such as the Frame's
|
|
# SDL3 in ~/deps/sdl3/lib/cmake/SDL3) is looked up in that package's lib/: the
|
|
# binary carries no RUNPATH to it (-DCMAKE_SKIP_BUILD_RPATH=ON, see the folder
|
|
# check below).
|
|
libdirs="$(sed -n 's|^[A-Za-z0-9_-]*_DIR:[A-Z]*=\(/.*/lib\(64\)\{0,1\}\)/cmake/[^/]*$|\1|p' "$BUILD/CMakeCache.txt" 2>/dev/null |
|
|
grep -v -x -e /usr/lib -e /usr/lib64 -e /lib -e /lib64 | sort -u | paste -sd: - || true)"
|
|
ldd() {
|
|
if [ -n "$libdirs" ]; then LD_LIBRARY_PATH="$libdirs${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" command ldd "$@"
|
|
else command ldd "$@"; fi
|
|
}
|
|
system=() bundled=()
|
|
LIBC=""
|
|
while read -r soname arrow path _; do
|
|
[ "$arrow" = "=>" ] || continue # the vdso
|
|
if [ "$path" = not ]; then echo "make_bundle.sh: $soname not found" >&2; exit 1; fi
|
|
case "$soname" in
|
|
*/ld-linux* | ld-linux*) ;; # the loader (by path): with glibc below
|
|
libvulkan.so.* | libX11* | libXext* | libxcb* | libwayland-* | libdecor-* | libdrm* | libgbm* | libGL* | libEGL* | \
|
|
libpipewire-* | libpulse* | libasound* | libudev* | libdbus-1* | libsystemd*)
|
|
system+=("$soname") ;;
|
|
libc.so.*) LIBC="$path" ;;
|
|
libm.so.* | libmvec.so.* | libpthread.so.* | libdl.so.* | librt.so.* | libutil.so.* | libanl.so.* | libresolv.so.*) ;;
|
|
libstdc++.so.* | libgcc_s.so.*)
|
|
if [ "$RUNTIMES" = bundled ]; then
|
|
cp -L "$path" "$STAGE/lib/cxx/$soname"; bundled+=("cxx/$soname:$path")
|
|
else
|
|
system+=("$soname")
|
|
fi ;;
|
|
*) cp -L "$path" "$STAGE/lib/$soname"; bundled+=("$soname:$path") ;;
|
|
esac
|
|
done < <(ldd "$BIN")
|
|
[ -n "$LIBC" ] || { echo "make_bundle.sh: no libc.so.6 in ldd's list" >&2; exit 1; }
|
|
if [ "$RUNTIMES" = bundled ]; then
|
|
# All of glibc, not only what the binary names: system libraries loaded
|
|
# into the game (Mesa, PipeWire, Steam's overlay) may still name
|
|
# libpthread.so.0, libdl.so.2 or librt.so.1, and those must be this
|
|
# glibc's, not the system's.
|
|
GLIBC_DIR="$(dirname "$(readlink -f "$LIBC")")"
|
|
for soname in $LOADER libc.so.6 libm.so.6 libmvec.so.1 libpthread.so.0 libdl.so.2 librt.so.1 libutil.so.1 \
|
|
libanl.so.1 libresolv.so.2 libnss_files.so.2 libnss_dns.so.2 libnss_compat.so.2; do
|
|
if [ -e "$GLIBC_DIR/$soname" ]; then
|
|
cp -L "$GLIBC_DIR/$soname" "$STAGE/lib/glibc/$soname"
|
|
bundled+=("glibc/$soname:$GLIBC_DIR/$soname")
|
|
fi
|
|
done
|
|
chmod 755 "$STAGE/lib/glibc/$LOADER"
|
|
fi
|
|
|
|
# The newest symbol versions everything here asks for, against what the
|
|
# runtimes it runs on give (a check that nothing needs more than they have):
|
|
# the bundled ones on x86-64, the system's on arm64.
|
|
newest() { # newest <prefix> <files...>: from each file's needs, not its definitions
|
|
local prefix=$1; shift
|
|
for f in "$@"; do readelf -V --wide "$f" 2>/dev/null | sed -n '/\.gnu\.version_r/,$p'; done |
|
|
grep -oE "Name: ${prefix}_[0-9.]+" | awk '{ print $2 }' | sort -uV | tail -1
|
|
}
|
|
provides() { grep -ao "${1}_[0-9.]*[0-9]" "$2" | sort -uV | tail -1; }
|
|
shopt -s nullglob
|
|
elves=("$GAME" "$STAGE"/lib/*.so* "$STAGE"/lib/cxx/*)
|
|
shopt -u nullglob
|
|
need_glibc="$(newest GLIBC "${elves[@]}")"
|
|
need_cxx="$(newest GLIBCXX "${elves[@]}")"
|
|
if [ "$RUNTIMES" = bundled ]; then
|
|
have_glibc="$("$STAGE/lib/glibc/$LOADER" --version | sed -n '1s/.* version \([0-9][0-9.]*[0-9]\).*/\1/p')"
|
|
have_cxx="$(provides GLIBCXX "$STAGE/lib/cxx/libstdc++.so.6")"
|
|
runtimes="bundled"
|
|
else
|
|
have_glibc="$("$HOST_LOADER" --version | sed -n '1s/.* version \([0-9][0-9.]*[0-9]\).*/\1/p')"
|
|
cxx_path="$(ldd "$BIN" | sed -n 's/^\s*libstdc++\.so\.6 => \(\S*\).*/\1/p')"
|
|
have_cxx="$(provides GLIBCXX "${cxx_path:-/usr/lib/libstdc++.so.6}")"
|
|
runtimes="the system's"
|
|
fi
|
|
if [ -z "$have_glibc" ] || [ -z "$have_cxx" ] ||
|
|
[ "$(printf '%s\n%s\n' "${need_glibc#GLIBC_}" "$have_glibc" | sort -V | tail -1)" != "$have_glibc" ] ||
|
|
[ "$(printf '%s\n%s\n' "$need_cxx" "$have_cxx" | sort -V | tail -1)" != "$have_cxx" ]; then
|
|
echo "make_bundle.sh: needs $need_glibc and $need_cxx; $runtimes: glibc ${have_glibc:-?} and ${have_cxx:-?}" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Licenses: the game's notices (COPYING, NOTICE, THIRD_PARTY_NOTICES.md and
|
|
# LICENSES/, which cover what is compiled into it), and each bundled
|
|
# library's own: its package's (Arch and SteamOS keep them in
|
|
# /usr/share/licenses/<package>), or for one built by hand (the Frame's SDL3
|
|
# in ~/deps/sdl3), the license files its install prefix holds. A bundled
|
|
# library without one stops the bundle: the README promises them all.
|
|
for f in COPYING NOTICE THIRD_PARTY_NOTICES.md; do
|
|
[ -f "$SRC/$f" ] || { echo "make_bundle.sh: no $f in $SRC" >&2; exit 1; }
|
|
cp "$SRC/$f" "$STAGE/licenses/"
|
|
done
|
|
cp -R "$SRC/LICENSES" "$STAGE/licenses/LICENSES"
|
|
DISTRO="$(. /etc/os-release 2>/dev/null; echo "${NAME:-the build system}")"
|
|
{
|
|
echo "SpeedBreaker is free software under the GPL-3.0-or-later (COPYING, NOTICE). What is"
|
|
echo "compiled into it, and each license, is in THIRD_PARTY_NOTICES.md and LICENSES/."
|
|
echo
|
|
echo "Bundled libraries (lib/), from $DISTRO packages unless noted:"
|
|
} > "$STAGE/licenses/README.txt"
|
|
declare -A packages=()
|
|
unlicensed=()
|
|
for entry in "${bundled[@]}"; do
|
|
pkg=""
|
|
command -v pacman > /dev/null && pkg="$(pacman -Qqo "${entry#*:}" 2>/dev/null || true)"
|
|
if [ -n "$pkg" ]; then
|
|
echo " ${entry%%:*}: $pkg$(pacman -Qi "$pkg" | sed -n 's/^Version *: / /p; s/^Licenses *: /, /p' | tr -d '\n')" >> "$STAGE/licenses/README.txt"
|
|
packages[$pkg]=1
|
|
continue
|
|
fi
|
|
# Built by hand: <prefix>/lib/<file>, its license under <prefix>/share.
|
|
prefix="$(dirname "$(dirname "$(readlink -f "${entry#*:}")")")"
|
|
name="$(basename "${entry%%:*}" | sed 's/^lib//; s/\.so.*//')"
|
|
found=()
|
|
while IFS= read -r f; do found+=("$f"); done < <(find "$prefix/share/licenses" "$prefix/share/doc" -maxdepth 3 -type f \
|
|
\( -iname 'LICENSE*' -o -iname 'COPYING*' \) 2>/dev/null | sort)
|
|
if [ ${#found[@]} -eq 0 ]; then
|
|
unlicensed+=("${entry%%:*} (${entry#*:})")
|
|
continue
|
|
fi
|
|
mkdir -p "$STAGE/licenses/$name"
|
|
cp "${found[@]}" "$STAGE/licenses/$name/"
|
|
echo " ${entry%%:*}: built from source (not a package); license: $name/$(cd "$STAGE/licenses/$name" && ls | tr '\n' ' ')" >> "$STAGE/licenses/README.txt"
|
|
done
|
|
if [ ${#unlicensed[@]} -gt 0 ]; then
|
|
echo "make_bundle.sh: no license found for: ${unlicensed[*]}" >&2
|
|
exit 1
|
|
fi
|
|
for pkg in "${!packages[@]}"; do
|
|
if [ -d "/usr/share/licenses/$pkg" ]; then
|
|
mkdir -p "$STAGE/licenses/$pkg"
|
|
cp -rL "/usr/share/licenses/$pkg/." "$STAGE/licenses/$pkg/"
|
|
fi
|
|
for id in $(pacman -Qi "$pkg" | sed -n 's/^Licenses *: //p' | sed 's/ WITH [^ ]*//g'); do
|
|
[ -f "/usr/share/licenses/spdx/$id.txt" ] && mkdir -p "$STAGE/licenses/$pkg" && cp "/usr/share/licenses/spdx/$id.txt" "$STAGE/licenses/$pkg/"
|
|
done
|
|
done
|
|
|
|
# Never a portable-mode switch or data folder (README.md, "Portable mode"):
|
|
# unpacked over a player's folder, the download must leave theirs as it is.
|
|
for f in portable.txt data cache; do
|
|
[ -e "$STAGE/$f" ] && { echo "make_bundle.sh: $STAGE/$f: portable mode's, never part of the download" >&2; exit 1; }
|
|
done
|
|
|
|
# Never game data (the installer brings it from the player's own disc).
|
|
if find "$STAGE" \( -iname '*.xex' -o -iname '*.iso' -o -iname '*.bin' -o -iname '*.xmv' -o -iname '*.big' \) | grep -q .; then
|
|
echo "make_bundle.sh: game data in $STAGE" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# No folder of the build machine in what's published (the sources are named
|
|
# from the repository root, CMakeLists.txt's -ffile-prefix-map; FFmpeg-XMA is
|
|
# built without debug information, scripts/build_ffmpeg_xma.sh). tools/ and
|
|
# ppc/ may be links into another checkout. The home folder too: a removed
|
|
# RUNPATH (patchelf above) leaves its text behind, so a library folder under
|
|
# ~ (a hand-built SDL3 in ~/deps) is kept out at configure time instead
|
|
# (-DCMAKE_SKIP_BUILD_RPATH=ON, as the README's Steam Frame line does).
|
|
folders=(-e "$SRC" -e "$BUILD")
|
|
for d in tools ppc; do [ -L "$SRC/$d" ] && folders+=(-e "$(dirname "$(readlink -f "$SRC/$d")")"); done
|
|
[ "${#HOME}" -gt 1 ] && folders+=(-e "$HOME/")
|
|
leaks="$(grep -aoF "${folders[@]}" "$GAME" | sort | uniq -c || true)"
|
|
if [ -n "$leaks" ]; then
|
|
echo "make_bundle.sh: the binary names the build machine's folders (for a library folder, configure with -DCMAKE_SKIP_BUILD_RPATH=ON):" >&2
|
|
echo "$leaks" >&2
|
|
[ "${SB_ALLOW_PATHS:-0}" = 1 ] || exit 1
|
|
fi
|
|
|
|
# The top of the folder: the launcher is the only program there (lib/ holds the
|
|
# game), so nothing else can be run by mistake.
|
|
top="$(cd "$STAGE" && find . -mindepth 1 -maxdepth 1 -type f -perm -u+x ! -name speedbreaker.sh | sed 's|^\./||')"
|
|
if [ -n "$top" ]; then
|
|
echo "make_bundle.sh: programs at the top of $STAGE besides speedbreaker.sh: $top" >&2
|
|
exit 1
|
|
fi
|
|
|
|
{
|
|
echo "SpeedBreaker v$VERSION ($COMMIT), $TYPE build for SteamOS $ARCH, bundled $(date -u '+%F %T UTC')"
|
|
echo "Needs: $need_glibc and $need_cxx ($runtimes: glibc $have_glibc, $have_cxx)"
|
|
echo "From the system: ${system[*]} (and what SDL loads at run time)"
|
|
} > "$STAGE/bundle-info.txt"
|
|
(cd "$STAGE" && find . -type f ! -name SHA256SUMS | sort | sed 's|^\./||' | xargs sha256sum > SHA256SUMS)
|
|
|
|
# The host's side, when this runs in a distrobox: what the launcher will find.
|
|
if [ -d /run/host/usr/lib ]; then
|
|
# (The loader is self-contained, so the host's runs here.)
|
|
host_glibc="$(/run/host/usr/lib/$LOADER --version 2>/dev/null | sed -n '1s/.* version \([0-9][0-9.]*[0-9]\).*/\1/p' || true)"
|
|
echo "host: glibc ${host_glibc:-?}, $(provides GLIBCXX /run/host/usr/lib/libstdc++.so.6 2>/dev/null || echo 'no libstdc++')"
|
|
for soname in "${system[@]}" libX11.so.6 libXext.so.6 libXcursor.so.1 libXi.so.6 libXfixes.so.3 libXrandr.so.2 libXss.so.1 \
|
|
libxkbcommon.so.0 libwayland-client.so.0 libdecor-0.so.0 libpipewire-0.3.so.0 libpulse.so.0 libasound.so.2 libudev.so.1 libdbus-1.so.3; do
|
|
[ -e "/run/host/usr/lib/$soname" ] || echo "host: warning: no $soname (the system's copy is used)"
|
|
done
|
|
fi
|
|
|
|
# The release download, by the name the website links to, and a copy named by
|
|
# the version (a hard link). Each .sha256 names its own file.
|
|
TAR="$OUT/SpeedBreaker-steamos-$ARCH.tar.xz"
|
|
VERSIONED="$OUT/SpeedBreaker-$VERSION-steamos-$ARCH.tar.xz"
|
|
tar -C "$OUT" --sort=name --owner=0 --group=0 --numeric-owner --mtime="@$(stat -c %Y "$BIN")" -cf - "$NAME" |
|
|
xz -T0 -9 > "$TAR.partial"
|
|
mv "$TAR.partial" "$TAR"
|
|
rm -f "$VERSIONED"
|
|
ln "$TAR" "$VERSIONED" 2>/dev/null || cp "$TAR" "$VERSIONED"
|
|
for f in "$TAR" "$VERSIONED"; do
|
|
(cd "$OUT" && sha256sum "$(basename "$f")" > "$(basename "$f").sha256")
|
|
done
|
|
echo "$(du -sh "$STAGE" | cut -f1) in $STAGE; $(du -h "$TAR" | cut -f1) $TAR (and $(basename "$VERSIONED")); symbols: $SYMBOLS/$DEBUG"
|
|
echo "v$VERSION ($COMMIT); needs $need_glibc and $need_cxx ($runtimes); bundled: ${bundled[*]%%:*}"
|