132 lines
4.3 KiB
Bash
132 lines
4.3 KiB
Bash
# Sourced by the scripts in scripts/ (and tools/) so every one of them finds
|
|
# toolchains the same way: from the environment ./install.sh generates. A script calls joeyNeed for each tool it uses, and gets a clear
|
|
# "install this" message (exit 2, which the gate runners treat as SKIP)
|
|
# instead of failing halfway through with a missing binary.
|
|
|
|
JOEY_REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
|
|
if [ -f "$JOEY_REPO/toolchains/env.sh" ]; then
|
|
# shellcheck source=/dev/null
|
|
source "$JOEY_REPO/toolchains/env.sh"
|
|
fi
|
|
|
|
|
|
# joeyNeed VAR INSTALL-TARGET -- exit 2 unless VAR names an existing path.
|
|
joeyNeed() {
|
|
local var="$1"
|
|
local target="$2"
|
|
if [ -z "${!var:-}" ] || [ ! -e "${!var}" ]; then
|
|
echo "$(basename "$0"): $var is not available; run: ./install.sh install $target" >&2
|
|
exit 2
|
|
fi
|
|
}
|
|
|
|
|
|
# joeyNeedFile PATH INSTALL-TARGET -- exit 2 unless PATH exists.
|
|
joeyNeedFile() {
|
|
if [ ! -e "$1" ]; then
|
|
echo "$(basename "$0"): $1 is missing; run: ./install.sh install $2" >&2
|
|
exit 2
|
|
fi
|
|
}
|
|
|
|
|
|
# DOSBox Staging must never read or write the user's own DOSBox setup, even
|
|
# ~/.config/dosbox (it creates that tree even with --noprimaryconf). Launch
|
|
# it as
|
|
# XDG_CONFIG_HOME="$work/xdg" "$DOSBOX" "${JOEY_DOSBOX_ISOLATE[@]}" ...
|
|
JOEY_DOSBOX_ISOLATE=(--noprimaryconf --nolocalconf)
|
|
|
|
|
|
# joeyExampleProgram NAME PORT -- the built program for an example name. A
|
|
# program that ships in its own folder with its DATA (Space Taxi on every
|
|
# port but the IIgs) is found inside that folder. When nothing is built yet
|
|
# it prints the flat path, so the caller's "not built" message names it.
|
|
joeyExampleProgram() {
|
|
local name="$1"
|
|
local bin="$JOEY_REPO/build/$2/bin"
|
|
local up="${name^^}"
|
|
local ext=""
|
|
local candidate
|
|
[ "$up" = "SPACETAXI" ] && up=STAXI
|
|
case "$2" in
|
|
iigs)
|
|
printf '%s\n' "$bin/$up"
|
|
return 0
|
|
;;
|
|
amiga)
|
|
# Mixed-case names, and Space Taxi is called Taxi there.
|
|
up="${name,,}"
|
|
case "$up" in
|
|
staxi|spacetaxi) up=taxi ;;
|
|
esac
|
|
up="${up^}"
|
|
;;
|
|
atarist) ext=".PRG" ;;
|
|
dos) ext=".EXE" ;;
|
|
x68000) ext=".X" ;;
|
|
*)
|
|
echo "$(basename "$0"): unknown port '$2' (iigs, amiga, atarist, dos or x68000)" >&2
|
|
return 2
|
|
;;
|
|
esac
|
|
for candidate in "$bin/$up/$up$ext" "$bin/$up$ext"; do
|
|
if [ -f "$candidate" ]; then
|
|
printf '%s\n' "$candidate"
|
|
return 0
|
|
fi
|
|
done
|
|
# A mixed-case Amiga name (SerTest) is not derivable from the example
|
|
# name, so take the file in any case.
|
|
candidate="$(find "$bin" -maxdepth 1 -type f -iname "$up$ext" -print -quit 2>/dev/null)"
|
|
if [ -n "$candidate" ]; then
|
|
printf '%s\n' "$candidate"
|
|
return 0
|
|
fi
|
|
printf '%s\n' "$bin/$up$ext"
|
|
}
|
|
|
|
|
|
# joeyFindWindow DISPLAY PID -- print the X window owned by process PID.
|
|
# More robust than matching titles, which differ between emulator builds.
|
|
joeyFindWindow() {
|
|
local win
|
|
for win in $(DISPLAY="$1" xdotool search --name -- "." 2>/dev/null); do
|
|
if [ "$(DISPLAY="$1" xdotool getwindowpid "$win" 2>/dev/null)" = "$2" ]; then
|
|
printf '%s\n' "$win"
|
|
return 0
|
|
fi
|
|
done
|
|
return 1
|
|
}
|
|
|
|
|
|
# joeyAlive PID -- PID is running. A zombie (exited, not yet reaped) is not,
|
|
# although `kill -0` still succeeds on it.
|
|
joeyAlive() {
|
|
local stat
|
|
stat="$(ps -o stat= -p "$1" 2>/dev/null)" || return 1
|
|
[[ "$stat" != Z* ]]
|
|
}
|
|
|
|
|
|
# joeyStop PID... -- stop emulator processes and make sure they are gone.
|
|
# Hatari, MAME and DOSBox Staging ignore or are slow to act on SIGTERM; a
|
|
# plain `kill` left them running (and burning CPU) after their script had
|
|
# finished, so escalate to SIGKILL. Only ever pass PIDs this script started.
|
|
joeyStop() {
|
|
local pid
|
|
local tick
|
|
for pid in "$@"; do
|
|
[ -n "$pid" ] || continue
|
|
kill "$pid" 2>/dev/null || continue
|
|
for tick in 1 2 3 4 5 6 7 8 9 10; do
|
|
joeyAlive "$pid" || break
|
|
sleep 0.2
|
|
done
|
|
kill -9 "$pid" 2>/dev/null || true
|
|
# Reap it when it is this shell's child (a no-op otherwise), so no
|
|
# zombie outlives the script where nothing else would reap it.
|
|
wait "$pid" 2>/dev/null || true
|
|
done
|
|
}
|