mirror of
https://github.com/harry7557558/spirula-studio.git
synced 2026-10-02 02:44:54 +08:00
146 lines
5.8 KiB
Bash
Executable File
146 lines
5.8 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Development build for Linux and macOS. Extra arguments are passed to CMake:
|
|
# ./build_develop.bash -DSS_BACKEND=vulkan -DSS_BUILD_GUI=OFF
|
|
|
|
# One tree per backend, so building one does not reconfigure the other. The
|
|
# arguments are read, never consumed: your own -B still reaches CMake, and the
|
|
# build step below would then target a tree it did not configure.
|
|
ss_backend=cuda
|
|
for arg in "$@"; do
|
|
case "$arg" in
|
|
-DSS_BACKEND=*|-DSSPLAT_BACKEND=*)
|
|
ss_backend=$(printf '%s' "${arg#*=}" | tr 'A-Z' 'a-z') ;;
|
|
esac
|
|
done
|
|
if [ "$(uname)" = "Darwin" ]; then
|
|
build_dir=build # one backend on macOS (Vulkan via MoltenVK)
|
|
else
|
|
build_dir="build_$ss_backend"
|
|
fi
|
|
|
|
# Regenerate headers. Skipped when python3 is unavailable -- the generated
|
|
# files are committed, so the build still works without it.
|
|
if command -v python3 >/dev/null 2>&1; then
|
|
python3 tools/codegen/generate_headers.py
|
|
python3 tools/codegen/generate_kernel_instantiation.py
|
|
else
|
|
echo "python3 not found -- skipping codegen (using committed generated files)"
|
|
fi
|
|
|
|
# SS_ is a short prefix; refuse to define a name <signal.h> or winuser.h owns.
|
|
bash tools/check_ss_prefix.sh >/dev/null || exit 1
|
|
|
|
# The GUI must not hand ImGui a string that never became a translatable
|
|
# message. Prints the remaining SS_MSG_EN count, which is the Phase 4 TODO.
|
|
bash tools/check_i18n.sh || exit 1
|
|
|
|
# An error message must name a path the person reading it can open, so
|
|
# __FILE__ goes through SS_FILE (src/core/SourcePath.h).
|
|
bash tools/check_file_macro.sh >/dev/null || { bash tools/check_file_macro.sh; exit 1; }
|
|
|
|
# The embedded fonts are subset to the characters the catalogs use, so editing
|
|
# a translation can outgrow them. Cheap: no network, no fontTools.
|
|
if command -v python3 >/dev/null 2>&1; then
|
|
python3 tools/check_font_coverage.py || exit 1
|
|
fi
|
|
|
|
# A comment must not cite a file that does not exist -- an unfollowable
|
|
# pointer reads exactly like a live one.
|
|
bash tools/check_comments.sh >/dev/null || { bash tools/check_comments.sh; exit 1; }
|
|
|
|
# The mask editor's testable half is built without SS_BUILD_SAM; an unguarded
|
|
# sam/ include there is invisible to mask_doc_test's link-level symbol gate.
|
|
bash tools/check_sam_guard.sh >/dev/null || { bash tools/check_sam_guard.sh; exit 1; }
|
|
|
|
# The mask panel has no unit seam; this pins its gates as text, and names each
|
|
# one that went missing.
|
|
bash tools/mask_editor_checks/survivors.sh >/dev/null ||
|
|
{ bash tools/mask_editor_checks/survivors.sh | command grep '^FAIL'; exit 1; }
|
|
|
|
# Comment blocks in uncommitted work must fit the AGENTS.md budget. Also wired
|
|
# into CMake (cmake/SsChecks.cmake), which covers a bare cmake/ninja build;
|
|
# running it here fails before the configure step rather than after it.
|
|
if command -v python3 >/dev/null 2>&1; then
|
|
python3 tools/check_comment_length.py || exit 1
|
|
fi
|
|
|
|
# Homebrew's libomp is keg-only: nothing points at it, so CMake finds no
|
|
# OpenMP and meshing, UV unwrap and metrics run serial (cmake/SsMacBundle.cmake
|
|
# then has no dylib to make static either).
|
|
if [ "$(uname)" = "Darwin" ]; then
|
|
case " $* " in
|
|
*" -DOpenMP_ROOT="*) ;;
|
|
*)
|
|
for omp_root in "$(brew --prefix libomp 2>/dev/null)" \
|
|
/opt/homebrew/opt/libomp /usr/local/opt/libomp; do
|
|
[ -n "$omp_root" ] || continue
|
|
[ -f "$omp_root/lib/libomp.a" ] ||
|
|
[ -f "$omp_root/lib/libomp.dylib" ] || continue
|
|
set -- "$@" "-DOpenMP_ROOT=$omp_root"
|
|
echo "OpenMP: passing -DOpenMP_ROOT=$omp_root (keg-only formula)"
|
|
break
|
|
done ;;
|
|
esac
|
|
fi
|
|
|
|
cmake -G Ninja -B "$build_dir" "$@" || exit $?
|
|
|
|
# Repair the ninja dependency log.
|
|
if [ -f "$build_dir/.ninja_deps" ]; then
|
|
ss_deps_broken() {
|
|
case "$1" in
|
|
*"premature end of file"*|*"bad deps log signature"*|\
|
|
*"bad deps log version"*) return 0 ;;
|
|
esac
|
|
return 1
|
|
}
|
|
if ss_deps_broken "$(cmake --build "$build_dir" -- -t recompact 2>&1)"; then
|
|
# The rewrite is what heals it, so a second pass is what confirms it.
|
|
if ss_deps_broken "$(cmake --build "$build_dir" -- -t recompact 2>&1)"; then
|
|
echo "$build_dir/.ninja_deps did not survive a recompact -- removing it"
|
|
rm -f "$build_dir/.ninja_deps"
|
|
else
|
|
echo "repaired a corrupt $build_dir/.ninja_deps (this build recompiles everything once)"
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
echo ""
|
|
|
|
JOB_RAM_MB=750 # 750MB per job
|
|
if [ "$(uname)" = "Darwin" ]; then
|
|
# macOS has no MemAvailable; approximate with free+inactive pages.
|
|
PAGE_SIZE=$(sysctl -n hw.pagesize)
|
|
FREE_PAGES=$(vm_stat | awk -F'[:.]' '/Pages (free|inactive)/ {gsub(/ /,"",$2); sum+=$2} END {print sum}')
|
|
AVAILABLE_MB=$(( FREE_PAGES * PAGE_SIZE / 1048576 ))
|
|
CPU_CORES=$(sysctl -n hw.ncpu)
|
|
else
|
|
AVAILABLE_KB=$(grep MemAvailable /proc/meminfo | awk '{print $2}')
|
|
AVAILABLE_MB=$(( AVAILABLE_KB / 1024 ))
|
|
CPU_CORES=$(nproc)
|
|
fi
|
|
MAX_JOBS_FROM_RAM=$(( AVAILABLE_MB / JOB_RAM_MB ))
|
|
JOBS=$(( MAX_JOBS_FROM_RAM < CPU_CORES ? MAX_JOBS_FROM_RAM : CPU_CORES ))
|
|
[ "$JOBS" -lt 1 ] && JOBS=1
|
|
echo "Build dir : ${build_dir}"
|
|
echo "Available RAM : ${AVAILABLE_MB} MB"
|
|
echo "CPU cores : ${CPU_CORES}"
|
|
echo "Using jobs : ${JOBS}"
|
|
echo ""
|
|
# Propagate the build's exit status.
|
|
if ! cmake --build "$build_dir" --verbose -j"${JOBS}"; then
|
|
echo "BUILD FAILED" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# <windows.h> defines near, far and small; a local of that name breaks only
|
|
# Windows. After the build, because the check reuses its compile commands.
|
|
if command -v python3 >/dev/null 2>&1; then
|
|
python3 tools/check_winmacro.py --build "$build_dir" >/dev/null ||
|
|
{ python3 tools/check_winmacro.py --build "$build_dir" | command grep -v '^ok'; exit 1; }
|
|
fi
|
|
|
|
echo ""
|
|
echo "Build complete: $build_dir/spirula"
|