Files

127 lines
3.7 KiB
Bash
Executable File

#!/usr/bin/env bash
# Build a Linux AppImage of OctoLauncher (local or CI).
# Usage: ./scripts/build.sh [--deps]
# --deps install native build deps via the distro package manager (needs sudo)
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT"
WITH_DEPS=0
for arg in "$@"; do
case "$arg" in
--deps) WITH_DEPS=1 ;;
-h | --help)
sed -n '2,5p' "$0"
exit 0
;;
*)
echo "Unknown option: $arg" >&2
exit 1
;;
esac
done
if [[ "$(uname -s)" != "Linux" ]]; then
echo "This script only builds Linux packages (host is $(uname -s))." >&2
exit 1
fi
NODE_MAJOR="$(node -p "process.versions.node.split('.')[0]" 2>/dev/null || true)"
if [[ -z "${NODE_MAJOR}" || "${NODE_MAJOR}" -ne 20 ]]; then
echo "Warning: Node 20 is recommended (found: $(node -v 2>/dev/null || echo none))." >&2
fi
# VS Code / Cursor set this and break Electron.
unset ELECTRON_RUN_AS_NODE
export ELECTRON_RUN_AS_NODE=
is_arch_like() {
# CachyOS, Arch, EndeavourOS, Manjaro, etc.
[[ -f /etc/arch-release ]] && return 0
if [[ -f /etc/os-release ]]; then
# shellcheck disable=SC1091
. /etc/os-release
[[ "${ID:-}" == "arch" || "${ID:-}" == "cachyos" || "${ID_LIKE:-}" == *"arch"* ]] && return 0
fi
command -v pacman >/dev/null 2>&1
}
is_debian_like() {
command -v apt-get >/dev/null 2>&1 || return 1
if [[ -f /etc/os-release ]]; then
# shellcheck disable=SC1091
. /etc/os-release
[[ "${ID:-}" == "debian" || "${ID:-}" == "ubuntu" || "${ID_LIKE:-}" == *"debian"* ]] && return 0
fi
# GitHub ubuntu-latest / other apt hosts without a clear ID_LIKE
return 0
}
install_deps() {
if is_arch_like; then
echo "==> install deps (pacman: base-devel python)"
sudo pacman -S --needed --noconfirm base-devel python
elif is_debian_like; then
echo "==> install deps (apt: build-essential python3)"
sudo apt-get update
sudo apt-get install -y build-essential python3
else
echo "Unsupported distro for --deps. Install a C++ toolchain + Python 3, then re-run without --deps." >&2
exit 1
fi
}
if [[ "${WITH_DEPS}" -eq 1 ]]; then
install_deps
fi
if ! command -v g++ >/dev/null 2>&1; then
echo "g++ not found. Install build tools (e.g. ./scripts/build.sh --deps) and retry." >&2
exit 1
fi
echo "==> npm install (ignore-scripts)"
npm install --ignore-scripts --no-audit --no-fund
# dll-inject is Windows-only (LoadLibrary) and unused in source.
echo "==> drop unused Windows native dep (dll-inject)"
rm -rf node_modules/dll-inject
echo "==> download Electron binary"
node node_modules/electron/install.js
# npm 12+ may no-op `npm rebuild` (install scripts blocked), so build stormlib
# against Electron headers explicitly. Package ships a Windows .node in dist/.
ELECTRON_VERSION="$(node -p "require('./node_modules/electron/package.json').version")"
ELECTRON_ARCH="$(node -p "process.arch")"
echo "==> rebuild stormlib-node for Electron ${ELECTRON_VERSION} (${ELECTRON_ARCH})"
(
cd node_modules/stormlib-node
# Don't use post-build.js — it deletes dist/ (wiping enums.js).
node scripts/pre-configure.js
npx --yes node-gyp rebuild \
--target="${ELECTRON_VERSION}" \
--arch="${ELECTRON_ARCH}" \
--dist-url=https://electronjs.org/headers
test -f build/Release/stormlib.node
cp build/Release/stormlib.node dist/stormlib.node
rm -rf build
)
file node_modules/stormlib-node/dist/stormlib.node
# Must be ELF on Linux, not the published Windows PE.
if ! file node_modules/stormlib-node/dist/stormlib.node | grep -q ELF; then
echo "stormlib.node is not a Linux ELF binary after rebuild." >&2
exit 1
fi
test -f node_modules/stormlib-node/dist/enums.js
echo "==> electron-vite build"
npm run build
echo "==> package AppImage"
npx electron-builder --linux AppImage --config
echo "==> done"
ls -lh distprod/*.AppImage