mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-27 19:01:02 +00:00
Move the Design-tab scripts into scripts/CAD/ and name them by role
Requested by SoftFever on PR #15238: ten of these had accumulated loose in scripts/ next to ~20 unrelated upstream ones, with names that only meant something to whoever wrote them. They now sit in scripts/CAD/, mirroring the src/libslic3r/CAD/ and src/slic3r/GUI/CAD/ split, and the verb in the name is the role: build- produces a binary, start- brings something up, run- runs a suite, check- asserts one thing against a live app. kernel-test.sh -> CAD/run-kernel-tests.sh ladder-all.sh -> CAD/run-all-checks.sh sketch-ladder.py -> CAD/check-sketch-engine.py ladder-corpus.py -> CAD/check-sketch-engine-corpus.py gui-ladder.py -> CAD/check-gui-sketching.py offer-ladder.py -> CAD/check-gui-context-menu.py mcp-sketch-smoke.py -> CAD/check-mcp-sketch.py rig-build.sh -> CAD/build-gui.sh docker-iter-build.sh -> CAD/build-gui-incremental.sh gui-session.sh -> CAD/start-headless-gui.sh "Ladder" was the worst of them: it named the shape of the test (rungs of increasing difficulty) rather than what the test proves, so nothing in the directory listing told you which one needed a GPU and which was pure kernel. Every reference rewritten -- the docs, the cross-calls between the scripts, Dockerfile.deps, and the container-side /OrcaSlicer/scripts paths. The three shell scripts resolve REPO relative to themselves and now sit one level deeper, so that walk went from /.. to /../.. . The copies these push into a container's /tmp were renamed to match, or the container would have kept the old names alive. Two runtime paths deliberately NOT renamed. /tmp/orca-rig-build.lock is a cross-fork contract -- both forks take the same lock so two concurrent builds serialise instead of OOMing the box, and renaming it on one side silently removes that guard. /tmp/gui-session.log is a runtime artefact, not a script. Added scripts/CAD/README.md: what each script proves, what it needs, and the two constraints that have each cost a session (never build inside the GUI container; a window manager is required or synthetic keys are ignored). On CI, which was the other half of the request: the kernel suite is already there and always has been. The cases are registered in tests/libslic3r/CMakeLists.txt under if (SLIC3R_CAD), which defaults ON and no workflow turns off, so they build into libslic3r_tests and run under ctest on every platform via unit_tests.yml -- like any other unit test, needing no new job. They have simply never been seen to run, because the workflows on this PR are still awaiting maintainer approval. run-kernel-tests.sh is the local loop over the same cases, and it is the only script here CI could run: the other six need an OpenGL canvas and synthetic input. Verified: scripts/CAD/run-kernel-tests.sh from its new location, all tests passed, 2562 assertions in 190 test cases.
This commit is contained in:
Executable
+149
@@ -0,0 +1,149 @@
|
||||
#!/usr/bin/env bash
|
||||
# Headless CAD-kernel test loop. THE verification contract for delegated work:
|
||||
# exit 0 means the kernel builds and the selected Catch2 tags pass. Nothing else counts.
|
||||
#
|
||||
# Builds only the `libslic3r_tests` target (not the GUI app), so a round trip is
|
||||
# minutes, not tens of minutes. Needs no display: every [CadDocument] case builds a
|
||||
# CadDocument, recompute()s it and asserts on geometry.
|
||||
#
|
||||
# Usage:
|
||||
# scripts/CAD/run-kernel-tests.sh # [CadDocument] tags, default volume
|
||||
# scripts/CAD/run-kernel-tests.sh --tags '[CadDocument],[Sketch]'
|
||||
# scripts/CAD/run-kernel-tests.sh --vol wt_mirror # private build cache (parallel workers)
|
||||
# scripts/CAD/run-kernel-tests.sh --host tommaso@100.103.234.2 # build on a remote host
|
||||
#
|
||||
# Parallel workers MUST pass a distinct --vol: two builds sharing one cache corrupt
|
||||
# each other. A new volume pays one full build; runs after that are incremental.
|
||||
#
|
||||
# --host exists because the deps image lives wherever it was first built. It rsyncs this
|
||||
# working tree to a per-volume staging dir on that host and re-runs this same script
|
||||
# there, so the verification contract is identical either way. Drop --host once the image
|
||||
# is present locally.
|
||||
# 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 snaporca-deps: this fork is mainline-based and needs Eigen 5.0.1,
|
||||
# CGAL 5.6.3, wx 3.3.2 and Python 3.12 Development.Embed, none of which snaporca-deps has.
|
||||
# With the wrong image CMake dies at configure, which is exactly why this fork went
|
||||
# M1-M8 without ever compiling (see commit 1633005bba).
|
||||
IMAGE="${IMAGE:-orcacad-deps}"
|
||||
# Must NOT default to snaporca_buildcache: that is the other fork's volume, and pointing
|
||||
# this fork at it makes the two silently trade build artefacts. build-gui-incremental.sh had the
|
||||
# identical defect and was fixed to orcacad_buildcache; this script was missed.
|
||||
VOL="${BUILD_VOL:-orcacad_kerneltest}"
|
||||
# No exclusions. Both cases that used to be quarantined now run: the solver SIGABRT on
|
||||
# circle-line tangency is fixed (snaporca-tkz), and the internal-thread case turned out to have
|
||||
# correct geometry and a wrong reference in the test (snaporca-kzy). A green run here now means
|
||||
# the whole CAD suite passed, not "everything except the two we gave up on".
|
||||
TAGS="${TAGS:-[CadDocument]}"
|
||||
HOST=""
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--vol) VOL="$2"; shift 2 ;;
|
||||
--tags) TAGS="$2"; shift 2 ;;
|
||||
--image) IMAGE="$2"; shift 2 ;;
|
||||
--host) HOST="$2"; shift 2 ;;
|
||||
*) echo "unknown arg: $1" >&2; exit 2 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo "REPO=$REPO IMAGE=$IMAGE VOL=$VOL TAGS=$TAGS HOST=${HOST:-local}"
|
||||
|
||||
if [[ -n "$HOST" ]]; then
|
||||
# Stage per-volume so parallel workers never share a remote tree.
|
||||
REMOTE="kt-$VOL" # relative: ssh and rsync both start in the remote home dir
|
||||
# SC2029: $REMOTE expanding on the CLIENT is the point -- it is derived from $VOL here,
|
||||
# and the remote has no such variable. The rsync destination below expands it the same way.
|
||||
# shellcheck disable=SC2029
|
||||
ssh "$HOST" "mkdir -p $REMOTE"
|
||||
# Only the inputs the build reads. --delete keeps a stale file from a prior worker from
|
||||
# silently compiling in.
|
||||
rsync -a --delete \
|
||||
"$REPO/src" "$REPO/tests" "$REPO/resources" "$REPO/cmake" "$REPO/scripts" \
|
||||
"$REPO/CMakeLists.txt" \
|
||||
"$HOST:$REMOTE/"
|
||||
exec ssh "$HOST" "cd $REMOTE && scripts/CAD/run-kernel-tests.sh --vol '$VOL' --tags '$TAGS' --image '$IMAGE'"
|
||||
fi
|
||||
|
||||
if ! docker image inspect "$IMAGE" >/dev/null 2>&1; then
|
||||
echo "FATAL: image '$IMAGE' not present locally. Either transfer it, or pass" >&2
|
||||
echo " --host <user@host> to build where the image already exists." >&2
|
||||
exit 3
|
||||
fi
|
||||
|
||||
# A private volume is always built CLEAN on first use. Cloning a warm cache from another
|
||||
# tree looks tempting but is a correctness trap: rsync preserves source mtimes, so ninja
|
||||
# compares foreign object timestamps against them, decides everything is up to date, and
|
||||
# relinks stale objects. That produced a binary with NO [CadDocument] tests at all while
|
||||
# reporting success -- a green run that tested nothing. Pay the one-off full build instead;
|
||||
# incremental rebuilds within a volume are correct because the mtimes then share a lineage.
|
||||
if ! docker volume inspect "$VOL" >/dev/null 2>&1; then
|
||||
echo "=== $VOL: new volume, clean configure + full build (one-off, slow) ==="
|
||||
docker volume create "$VOL" >/dev/null
|
||||
fi
|
||||
|
||||
# tests/ is mounted too -- unlike build-gui-incremental.sh, this script exists precisely to
|
||||
# compile tests being edited. CMakeLists.txt and cmake/ carry the SLIC3R_CAD gate; taking
|
||||
# them from the baked image instead leaves the gate off and the CAD symbols vanish.
|
||||
|
||||
# ---- 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/tests":/OrcaSlicer/tests \
|
||||
-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 "$VOL":/OrcaSlicer/build \
|
||||
"$IMAGE" \
|
||||
bash -lc "set -e
|
||||
cd /OrcaSlicer
|
||||
DESTDIR=/OrcaSlicer/deps/build/destdir/usr/local
|
||||
export PATH=\$DESTDIR/bin:\$PATH # wx-config, and anything else the deps prefix ships
|
||||
# Configure unconditionally. Guarding on 'CMakeCache.txt exists' is wrong: a FAILED
|
||||
# configure still writes that file, so the guard then skips reconfiguring forever and
|
||||
# every later run reuses a poisoned cache while ignoring corrected flags. A no-op
|
||||
# reconfigure costs seconds; that bug costs an afternoon.
|
||||
# SLIC3R_GTK=3 and BUILD_TESTS=ON are not optional extras: src/CMakeLists.txt turns
|
||||
# SLIC3R_GTK into 'wx-config --toolkit=gtk<N>', so omitting it asks for toolkit 'gtk'
|
||||
# and no wx build matches -> 'Could NOT find wxWidgets'. BUILD_TESTS=ON is what makes
|
||||
# the libslic3r_tests target exist at all. build_linux.sh sets both (lines 218, 226).
|
||||
cmake -S . -B build -G 'Ninja Multi-Config' \
|
||||
-DCMAKE_PREFIX_PATH=\$DESTDIR \
|
||||
-DwxWidgets_CONFIG_EXECUTABLE=\$DESTDIR/bin/wx-config \
|
||||
-DSLIC3R_GTK=3 -DBUILD_TESTS=ON -DSLIC3R_GUI=OFF \
|
||||
-DSLIC3R_CAD=ON -DSLIC3R_STATIC=1 -DORCA_TOOLS=ON -DCMAKE_BUILD_TYPE=Release
|
||||
# SLIC3R_GUI=OFF: this script builds ONLY libslic3r_tests, which links libslic3r and no GUI
|
||||
# code, but cmake still PROCESSES the if SLIC3R_GUI block of src/CMakeLists.txt (lines 16-98)
|
||||
# and every find_package inside it. That made the kernel suite depend on the GUI dependency
|
||||
# set for no benefit, and it broke the moment upstream added wxInspector as a REQUIRED
|
||||
# find_package at line 92: the orcacad-deps image predates it, so configure died pointing at
|
||||
# src/CMakeLists.txt:92 while nothing about the kernel had changed. Turning the block off is
|
||||
# not a workaround for that one dependency; it is the kernel suite finally declaring what it
|
||||
# actually needs, so the next GUI-side dependency upstream adds cannot break it either.
|
||||
cmake --build build --config Release --target libslic3r_tests -- -j$JOBS
|
||||
./build/tests/libslic3r/Release/libslic3r_tests '$TAGS' --order decl"
|
||||
Reference in New Issue
Block a user