Files
OrcaSlicer/scripts/CAD/build-gui-incremental.sh
T

82 lines
4.3 KiB
Bash
Executable File

#!/usr/bin/env bash
# Incremental slicer build against the orcacad-deps base image.
#
# The deps-baked image (built from scripts/Dockerfile.deps) carries the pinned
# dependencies at /OrcaSlicer/deps/build/destdir. This script mounts the LIVE source
# tree and resources over the baked copy so code/CMake edits apply immediately, and
# persists /OrcaSlicer/build in a named volume so ninja recompiles only what changed.
#
# Result: edit -> rebuild in seconds-to-minutes instead of a full Docker rebuild.
#
# Usage (run on the build host, e.g. behemoth, from anywhere):
# scripts/CAD/build-gui-incremental.sh
# IMAGE=orcacad-deps scripts/CAD/build-gui-incremental.sh
#
# On success the binary is inside the persistent volume at
# /OrcaSlicer/build/package/bin/orca-slicer (copy it out with a follow-up
# `docker run --rm -v orcacad_buildcache:/b alpine cp ...` or via this script's tail).
# Rig build traps already paid for once each (stale project, NLopt cache, pybind11, OCCT_LIBS, SLIC3R_CAD gate): docs/rig_build_traps.md
set -euo pipefail
REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
# orcacad-deps, NOT snapmaker-deps: see the note in run-kernel-tests.sh — the wrong image
# fails at CMake configure, not at link time.
IMAGE="${IMAGE:-orcacad-deps}"
BUILD_VOL="${BUILD_VOL:-orcacad_buildcache}"
echo "REPO=$REPO IMAGE=$IMAGE BUILD_VOL=$BUILD_VOL"
# The root CMakeLists.txt and cmake/ must be mounted too, not taken from the baked image:
# they carry the build-time gates (e.g. SLIC3R_CAD -> add_definitions(-DSLIC3R_CAD)) that the
# mounted headers are compiled against. With a stale baked copy the gate silently stays off and
# the build fails with "class GLCanvas3D has no member named set_design_sketch_tool".
#
# build_linux.sh must be mounted for the same reason, and here the stale copy is guaranteed
# wrong rather than merely risky: orcacad-deps is layered on snapmaker-deps, so the baked script
# is the OTHER fork's and builds `--target Snapmaker_Orca`. This fork's target is `OrcaSlicer`,
# so without this mount configure succeeds and then ninja dies on "unknown target".
# scripts/ likewise: build_linux.sh's packaging step sources scripts/appimage_lib_policy.sh,
# which the baked Snapmaker tree does not have, so a fully successful link still exited
# non-zero with "missing AppImage helper" and the binary check never ran.
# ---- OOM guard (2026-08-21) -------------------------------------------------------------
# Two of these builds ran at once on 2026-08-21, each with ninja -j$(nproc)=16: ~36 cc1plus
# holding 42 GB of a 62 GB box -> global OOM at 21:05, a 2h28m kill storm, ssh unreachable,
# lightdm destroyed. Neither build produced a single object. scripts/CAD/build-gui.sh grew the
# bounds first; every script that starts a compile needs the same three, or the guard is only
# as strong as the script you happened not to use.
# flock — the lock path is SHARED with build-gui.sh and the other fork on purpose, so
# concurrent builds serialise instead of summing.
# -j — bounded parallelism; ~1.17 GB per cc1plus was the measured average.
# --memory — the actual guarantee: a runaway build dies in its own cgroup instead of taking
# the host down. --memory-swap equal to --memory forbids swap, which is what made
# ssh hang.
JOBS="${JOBS:-12}"
MEM="${MEM:-40g}"
LOCK=/tmp/orca-rig-build.lock
exec 9>"$LOCK"
if ! flock -n 9; then
echo "another build holds $LOCK — waiting (this is the OOM guard, not a hang)"
flock 9
fi
docker run --rm \
--memory="$MEM" --memory-swap="$MEM" \
-v "$REPO/src":/OrcaSlicer/src \
-v "$REPO/resources":/OrcaSlicer/resources \
-v "$REPO/CMakeLists.txt":/OrcaSlicer/CMakeLists.txt \
-v "$REPO/cmake":/OrcaSlicer/cmake \
-v "$REPO/deps_src":/OrcaSlicer/deps_src \
-v "$REPO/build_linux.sh":/OrcaSlicer/build_linux.sh \
-v "$REPO/scripts":/OrcaSlicer/scripts \
-v "$BUILD_VOL":/OrcaSlicer/build \
"$IMAGE" \
bash -lc "cd /OrcaSlicer && ./build_linux.sh -sr -j $JOBS"
# src/CMakeLists.txt:151 renames the OrcaSlicer target's output to "orca-slicer" — not
# "snapmaker-orca", which is the other fork's binary name.
echo "=== build finished; checking for binary ==="
docker run --rm -v "$BUILD_VOL":/b "$IMAGE" \
bash -lc 'ls -lh /b/package/bin/orca-slicer 2>/dev/null && file /b/package/bin/orca-slicer || echo "NO BINARY"'