mirror of
https://github.com/InstanceBrick/nightcap.git
synced 2026-10-17 20:00:46 +02:00
Texture overrides decode PNG through libpng, which stubs/CMakeLists.txt already requires. Lists it in the Arch, AUR, and Nix packages, the thin dependency installer, and the README build instructions.
355 lines
7.5 KiB
Bash
Executable File
355 lines
7.5 KiB
Bash
Executable File
#!/bin/sh
|
|
# Copyright 2026 Mocktail Project Authors
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
set -eu
|
|
set -f
|
|
|
|
PROGRAM=${0##*/}
|
|
OS_RELEASE_FILE=${MOCKTAIL_OS_RELEASE_FILE:-/etc/os-release}
|
|
ACTION=
|
|
DISTRO=
|
|
MANAGER=
|
|
PACKAGES=
|
|
INSTALL_ARGS=
|
|
MISSING_PACKAGES=
|
|
|
|
Die() {
|
|
printf '%s: %s\n' "$PROGRAM" "$*" >&2
|
|
exit 2
|
|
}
|
|
|
|
Usage() {
|
|
cat <<'EOF'
|
|
Usage: install_thin_dependencies.sh --check|--print|--install
|
|
|
|
--check Exit successfully when every declared host package is installed.
|
|
--print Print the detected distribution and exact package set.
|
|
--install Interactively install missing packages through pkexec or sudo.
|
|
|
|
Set MOCKTAIL_AUTO_INSTALL_DEPS=1 to permit installation without a terminal.
|
|
Physical GPU drivers and Vulkan ICD packages are never selected automatically.
|
|
EOF
|
|
}
|
|
|
|
StripOsReleaseValue() {
|
|
value=$1
|
|
case $value in
|
|
\"*\") value=${value#\"}; value=${value%\"} ;;
|
|
\'*\') value=${value#\'}; value=${value%\'} ;;
|
|
esac
|
|
printf '%s\n' "$value"
|
|
}
|
|
|
|
ReadDistributionId() {
|
|
[ -f "$OS_RELEASE_FILE" ] && [ -r "$OS_RELEASE_FILE" ] || return 1
|
|
while IFS='=' read -r key value; do
|
|
case $key in
|
|
ID)
|
|
StripOsReleaseValue "$value"
|
|
return 0
|
|
;;
|
|
esac
|
|
done <"$OS_RELEASE_FILE"
|
|
return 1
|
|
}
|
|
|
|
DetectDistribution() {
|
|
distro_id=$(ReadDistributionId 2>/dev/null || true)
|
|
case $distro_id in
|
|
arch|archlinux) DISTRO=arch; MANAGER=pacman ;;
|
|
void) DISTRO=void; MANAGER=xbps-install ;;
|
|
alpine) DISTRO=alpine; MANAGER=apk ;;
|
|
*)
|
|
manager_count=0
|
|
if command -v pacman >/dev/null 2>&1; then
|
|
DISTRO=arch; MANAGER=pacman; manager_count=$((manager_count + 1))
|
|
fi
|
|
if command -v xbps-install >/dev/null 2>&1; then
|
|
DISTRO=void; MANAGER=xbps-install; manager_count=$((manager_count + 1))
|
|
fi
|
|
if command -v apk >/dev/null 2>&1; then
|
|
DISTRO=alpine; MANAGER=apk; manager_count=$((manager_count + 1))
|
|
fi
|
|
[ "$manager_count" -eq 1 ] ||
|
|
Die "unsupported or ambiguous Linux distribution: ${distro_id:-unknown}"
|
|
;;
|
|
esac
|
|
command -v "$MANAGER" >/dev/null 2>&1 ||
|
|
Die "$MANAGER is unavailable on detected $DISTRO host"
|
|
}
|
|
|
|
HostUsesMusl() {
|
|
case ${MOCKTAIL_HOST_LIBC:-} in
|
|
musl) return 0 ;;
|
|
glibc) return 1 ;;
|
|
'') ;;
|
|
*) Die "MOCKTAIL_HOST_LIBC must be glibc or musl" ;;
|
|
esac
|
|
[ -e /lib/ld-musl-x86_64.so.1 ] ||
|
|
[ -e /lib64/ld-musl-x86_64.so.1 ]
|
|
}
|
|
|
|
LoadPackageManifest() {
|
|
case $DISTRO in
|
|
arch)
|
|
PACKAGES='bash
|
|
bubblewrap
|
|
xdg-dbus-proxy
|
|
vulkan-icd-loader
|
|
libadwaita
|
|
webkitgtk-6.0
|
|
jq
|
|
unzip
|
|
file
|
|
binutils
|
|
jre-openjdk-headless
|
|
sdl3
|
|
sdl3_ttf
|
|
libutf8proc
|
|
libelf
|
|
capstone
|
|
curl
|
|
libyaml
|
|
fontconfig
|
|
minizip
|
|
libplacebo
|
|
libpng
|
|
util-linux'
|
|
INSTALL_ARGS='-S --needed --noconfirm'
|
|
;;
|
|
void)
|
|
PACKAGES='bash
|
|
bubblewrap
|
|
xdg-dbus-proxy
|
|
vulkan-loader
|
|
libadwaita
|
|
libwebkitgtk60
|
|
jq
|
|
unzip
|
|
file
|
|
binutils
|
|
openjdk17-jre
|
|
SDL3
|
|
SDL3_ttf
|
|
libutf8proc
|
|
libelf
|
|
capstone
|
|
libcurl
|
|
libyaml
|
|
fontconfig
|
|
minizip
|
|
libplacebo
|
|
libpng
|
|
util-linux'
|
|
if HostUsesMusl; then
|
|
PACKAGES="$PACKAGES gcompat"
|
|
fi
|
|
INSTALL_ARGS='-Sy'
|
|
;;
|
|
alpine)
|
|
PACKAGES='bash
|
|
bubblewrap
|
|
xdg-dbus-proxy
|
|
vulkan-loader
|
|
libadwaita
|
|
webkit2gtk-6.0
|
|
jq
|
|
unzip
|
|
file
|
|
binutils
|
|
openjdk17-jre-headless
|
|
sdl3
|
|
sdl3_ttf
|
|
utf8proc
|
|
libelf
|
|
capstone
|
|
curl
|
|
libyaml
|
|
fontconfig
|
|
minizip
|
|
libplacebo
|
|
libpng
|
|
coreutils
|
|
findutils
|
|
util-linux'
|
|
PACKAGES="$PACKAGES gcompat"
|
|
INSTALL_ARGS='add --no-interactive'
|
|
;;
|
|
*) Die "internal error: no package manifest for $DISTRO" ;;
|
|
esac
|
|
}
|
|
|
|
PackageInstalled() {
|
|
package=$1
|
|
case $package in
|
|
bash) command -v bash >/dev/null 2>&1 && return 0 ;;
|
|
jre-openjdk-headless|openjdk17-jre|openjdk17-jre-headless)
|
|
command -v java >/dev/null 2>&1 && return 0
|
|
;;
|
|
binutils) command -v readelf >/dev/null 2>&1 && return 0 ;;
|
|
jq|unzip|file) command -v "$package" >/dev/null 2>&1 && return 0 ;;
|
|
util-linux) command -v flock >/dev/null 2>&1 && return 0 ;;
|
|
esac
|
|
case $DISTRO in
|
|
arch) pacman -Qq "$package" >/dev/null 2>&1 ;;
|
|
void) xbps-query -p pkgver "$package" >/dev/null 2>&1 ;;
|
|
alpine) apk info -e "$package" >/dev/null 2>&1 ;;
|
|
*) return 1 ;;
|
|
esac
|
|
}
|
|
|
|
FindMissingPackages() {
|
|
MISSING_PACKAGES=
|
|
for package in $PACKAGES; do
|
|
if ! PackageInstalled "$package"; then
|
|
if [ -n "$MISSING_PACKAGES" ]; then
|
|
MISSING_PACKAGES="$MISSING_PACKAGES $package"
|
|
else
|
|
MISSING_PACKAGES=$package
|
|
fi
|
|
fi
|
|
done
|
|
}
|
|
|
|
PrintPackages() {
|
|
printf 'distribution=%s\n' "$DISTRO"
|
|
printf 'manager=%s\n' "$MANAGER"
|
|
printf 'packages:'
|
|
for package in $PACKAGES; do
|
|
printf ' %s' "$package"
|
|
done
|
|
printf '\n'
|
|
printf 'install_command=%s' "$MANAGER"
|
|
for argument in $INSTALL_ARGS; do
|
|
printf ' %s' "$argument"
|
|
done
|
|
for package in $PACKAGES; do
|
|
printf ' %s' "$package"
|
|
done
|
|
printf '\n'
|
|
printf 'gpu_driver=manual\n'
|
|
printf 'Physical GPU driver and Vulkan ICD package selection remains manual.\n'
|
|
}
|
|
|
|
PrintManualCommand() {
|
|
printf 'Run this command as root:\n %s' "$MANAGER" >&2
|
|
for argument in $INSTALL_ARGS; do
|
|
printf ' %s' "$argument" >&2
|
|
done
|
|
for package in $MISSING_PACKAGES; do
|
|
printf ' %s' "$package" >&2
|
|
done
|
|
printf '\n' >&2
|
|
}
|
|
|
|
ConfirmInteractiveInstall() {
|
|
if [ "${MOCKTAIL_AUTO_INSTALL_DEPS:-0}" = 1 ]; then
|
|
return 0
|
|
fi
|
|
[ -t 0 ] && [ -t 1 ] || {
|
|
printf '%s: dependency installation requires an interactive terminal; ' \
|
|
"$PROGRAM" >&2
|
|
printf 'set MOCKTAIL_AUTO_INSTALL_DEPS=1 to authorize unattended installation\n' \
|
|
>&2
|
|
return 1
|
|
}
|
|
printf 'Mocktail needs these %s packages:%s\n' "$DISTRO" "$MISSING_PACKAGES"
|
|
printf 'Install them now? [y/N] '
|
|
IFS= read -r answer || return 1
|
|
case $answer in
|
|
y|Y|yes|YES|Yes) return 0 ;;
|
|
*) return 1 ;;
|
|
esac
|
|
}
|
|
|
|
RunManager() {
|
|
elevator=$1
|
|
shift
|
|
set -- "$@" "$MANAGER"
|
|
for argument in $INSTALL_ARGS; do
|
|
set -- "$@" "$argument"
|
|
done
|
|
for package in $MISSING_PACKAGES; do
|
|
set -- "$@" "$package"
|
|
done
|
|
if [ -n "$elevator" ]; then
|
|
"$elevator" "$@"
|
|
else
|
|
"$@"
|
|
fi
|
|
}
|
|
|
|
InstallMissingPackages() {
|
|
[ -n "$MISSING_PACKAGES" ] || return 0
|
|
ConfirmInteractiveInstall || {
|
|
PrintManualCommand
|
|
return 1
|
|
}
|
|
|
|
if [ "$(id -u)" -eq 0 ]; then
|
|
RunManager ''
|
|
return $?
|
|
fi
|
|
if command -v pkexec >/dev/null 2>&1; then
|
|
if RunManager pkexec; then
|
|
return 0
|
|
fi
|
|
printf '%s: pkexec failed; trying sudo\n' "$PROGRAM" >&2
|
|
fi
|
|
if command -v sudo >/dev/null 2>&1; then
|
|
if RunManager sudo; then
|
|
return 0
|
|
fi
|
|
printf '%s: sudo failed\n' "$PROGRAM" >&2
|
|
fi
|
|
PrintManualCommand
|
|
return 1
|
|
}
|
|
|
|
[ "$#" -eq 1 ] || {
|
|
Usage >&2
|
|
exit 2
|
|
}
|
|
case $1 in
|
|
--check|--print|--install) ACTION=$1 ;;
|
|
-h|--help) Usage; exit 0 ;;
|
|
*) Usage >&2; exit 2 ;;
|
|
esac
|
|
|
|
DetectDistribution
|
|
LoadPackageManifest
|
|
|
|
case $ACTION in
|
|
--print)
|
|
PrintPackages
|
|
;;
|
|
--check)
|
|
FindMissingPackages
|
|
if [ -n "$MISSING_PACKAGES" ]; then
|
|
printf '%s: missing %s packages:%s\n' "$PROGRAM" "$DISTRO" \
|
|
"$MISSING_PACKAGES" >&2
|
|
exit 1
|
|
fi
|
|
;;
|
|
--install)
|
|
FindMissingPackages
|
|
if [ -z "$MISSING_PACKAGES" ]; then
|
|
printf 'Mocktail thin host dependencies are already installed.\n'
|
|
exit 0
|
|
fi
|
|
InstallMissingPackages
|
|
FindMissingPackages
|
|
[ -z "$MISSING_PACKAGES" ] || {
|
|
printf '%s: packages remain unavailable after installation:%s\n' \
|
|
"$PROGRAM" "$MISSING_PACKAGES" >&2
|
|
exit 1
|
|
}
|
|
;;
|
|
esac
|