From 56e0d3662b55cee108b5c6f74e8d96e121342911 Mon Sep 17 00:00:00 2001 From: Florian Egger Date: Mon, 7 Sep 2026 13:20:14 +0200 Subject: [PATCH] build: survive low-memory boards in the receiver install script MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Raspberry Pi Zero 2 W (512 MB RAM) ran out of memory compiling signaling.cpp — nlohmann/json peaks well above available RAM at -O3, and ninja runs 6 parallel jobs on a quad-core — so the OOM killer terminated the compiler with 'Killed signal terminated program cc1plus'. When less than 1.5 GB RAM is detected, the install script now adds 1 GB of temporary build-time swap (fallocate with a dd fallback, removed on exit; some filesystems such as btrfs refuse swapfiles outright, in which case it warns and continues) and compiles with a single job. The cleanup trap also covers the SDL3 source directory. The swap mechanics were live-tested with a small swapfile (swapon/ swapoff lifecycle); this dev machine's filesystem rejects swapfiles, which is what exposed the need for the warning fallback. The Pi's ext4 rootfs accepts them. --- scripts/install-receiver.sh | 50 ++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/scripts/install-receiver.sh b/scripts/install-receiver.sh index 4b08cd9..04e2927 100755 --- a/scripts/install-receiver.sh +++ b/scripts/install-receiver.sh @@ -34,6 +34,19 @@ ENABLE_SERVICE="${SC_RECEIVER_SERVICE:-1}" log() { printf '\n=== %s\n' "$*"; } die() { printf 'install-receiver: error: %s\n' "$*" >&2; exit 1; } +TEMP_SWAP="" +SDL_DIR="" +cleanup() { + if [ -n "${TEMP_SWAP}" ]; then + swapoff "${TEMP_SWAP}" 2>/dev/null || true + rm -f "${TEMP_SWAP}" + fi + if [ -n "${SDL_DIR}" ]; then + rm -rf "${SDL_DIR}" + fi +} +trap cleanup EXIT + [ "$(id -u)" = 0 ] || die "run with sudo (installs to ${INSTALL_DIR})" [ -f "${REPO_ROOT}/meson.build" ] || die "run from the screen_cast repository" command -v apt-get >/dev/null 2>&1 || die "this script supports apt-based systems only" @@ -62,7 +75,6 @@ if ! apt-get install -y --no-install-recommends libsdl3-dev; then log "libsdl3-dev is not packaged; building SDL3 from source (15-30 min on small boards)" apt-get install -y --no-install-recommends cmake git SDL_DIR="$(mktemp -d)" - trap 'rm -rf "${SDL_DIR}"' EXIT git clone --depth 1 --branch release-3.2.x \ https://github.com/libsdl-org/SDL.git "${SDL_DIR}/SDL" cmake -S "${SDL_DIR}/SDL" -B "${SDL_DIR}/build" \ @@ -82,13 +94,45 @@ if ! printf '#include \nint main() { return 0; }\n' | Trixie or newer ships one). Aborting before a long build." fi +# --- memory-constrained boards ---------------------------------------------- +# The signaling unit includes nlohmann/json.hpp, which can peak well above +# the RAM of small boards; the OOM killer then terminates the compiler +# ("Killed signal terminated program cc1plus"). Give such boards temporary +# swap and a single compile job. +BUILD_JOBS="$(nproc)" +MEM_TOTAL_KB="$(awk '/^MemTotal:/ {print $2}' /proc/meminfo)" +if [ "${MEM_TOTAL_KB}" -lt 1500000 ]; then + SWAP_TOTAL_KB="$(awk '/^SwapTotal:/ {print $2}' /proc/meminfo)" + if [ "${SWAP_TOTAL_KB}" -lt 1000000 ]; then + FREE_KB="$(df -k --output=avail / | awk 'NR==2 {print $1}')" + if [ "${FREE_KB}" -lt 1572864 ]; then + die "board has little RAM and not enough free disk for 1 GB of temporary build swap; build on a larger machine or add swap manually" + fi + log "low-memory board: adding 1 GB of temporary swap for the build (removed afterwards)" + TEMP_SWAP="/var/tmp/screencast-build.swap" + if ! (fallocate -l 1G "${TEMP_SWAP}" 2>/dev/null || + dd if=/dev/zero of="${TEMP_SWAP}" bs=1M count=1024 status=none); then + die "failed to write the swapfile" + fi + chmod 600 "${TEMP_SWAP}" + if ! mkswap "${TEMP_SWAP}" >/dev/null 2>&1 || ! swapon "${TEMP_SWAP}" 2>/dev/null; then + # Some filesystems (e.g. btrfs) refuse swapfiles outright. + rm -f "${TEMP_SWAP}" + TEMP_SWAP="" + log "WARNING: could not activate a swapfile on this filesystem; continuing with a single compile job — the build may still run out of memory" + fi + fi + BUILD_JOBS=1 + log "low-memory board: compiling with a single job" +fi + # --- build the receiver ------------------------------------------------------ log "configuring a receiver-only build in ${BUILD_DIR}" rm -rf "${BUILD_DIR}" meson setup "${BUILD_DIR}" "${REPO_ROOT}" -Dsender=false -log "compiling (this takes a few minutes on small boards)" -meson compile -C "${BUILD_DIR}" +log "compiling (this takes a while on small boards)" +meson compile -C "${BUILD_DIR}" --jobs "${BUILD_JOBS}" if [ "${SKIP_TESTS}" != "1" ]; then log "running the test suite"