#!/usr/bin/env bash set -euo pipefail if [[ "${VOXELFORGE_LIMITED_BUILD:-0}" != "1" ]]; then exec taskset -c 0-11 prlimit --as=6442450944 -- env VOXELFORGE_LIMITED_BUILD=1 "$0" "$@" fi SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" ROOT="$SCRIPT_DIR" PROJECT_ROOT="$(cd -- "$ROOT/.." && pwd)" VERIFY_DIR="$ROOT/Tools/verify" COMPILER="clang++-19" VARIANT="clang19" FP_CONTRACT="off" JOBS=12 SANITIZERS="" EXCLUDE_UNSIGNED_OVERFLOW=0 while (($#)); do case "$1" in --compiler=*) COMPILER="${1#*=}" ;; --variant=*) VARIANT="${1#*=}" ;; --fp-contract=*) FP_CONTRACT="${1#*=}" ;; --jobs=*) JOBS="${1#*=}" ;; --sanitize=*) SANITIZERS="${1#*=}" ;; --exclude-unsigned-integer-overflow) EXCLUDE_UNSIGNED_OVERFLOW=1 ;; *) printf 'Unknown build option: %s\n' "$1" >&2; exit 2 ;; esac shift done if [[ ! "$JOBS" =~ ^[0-9]+$ ]] || ((JOBS < 1 || JOBS > 12)); then printf 'jobs must be from 1 to 12\n' >&2 exit 2 fi if [[ "$FP_CONTRACT" != "default" && "$FP_CONTRACT" != "off" && "$FP_CONTRACT" != "on" && "$FP_CONTRACT" != "fast" ]]; then printf 'fp-contract must be default, off, on, or fast\n' >&2 exit 2 fi command -v "$COMPILER" >/dev/null || { printf 'Compiler not found: %s\n' "$COMPILER" >&2; exit 2; } command -v ar >/dev/null || { printf 'ar not found\n' >&2; exit 2; } command -v pkg-config >/dev/null || { printf 'pkg-config not found\n' >&2; exit 2; } pkg-config --exists egl glesv2 libpng || { printf 'EGL, GLESv2, and libpng development files are required\n' >&2; exit 2; } BUILD_ROOT="${VOXELFORGE_BUILD_ROOT:-$ROOT/Build}" BIN_DIR="${VOXELFORGE_BIN_DIR:-$ROOT/bin/linux}" BUILD_DIR="$BUILD_ROOT/linux-$VARIANT" mkdir -p "$BUILD_DIR/wrappers" "$BUILD_DIR/objects" "$BIN_DIR" STAMP_HELPER="$VERIFY_DIR/source_stamp.py" STAMP_ARGS=() if [[ "${VOXELFORGE_INCLUDE_UNREAL_ADAPTER:-0}" == "1" ]]; then STAMP_ARGS+=(--include-unreal-adapter) fi SOURCE_STAMP="$(python3 -B "$STAMP_HELPER" stamp --root "$PROJECT_ROOT" "${STAMP_ARGS[@]}")" python3 -B "$STAMP_HELPER" write-manifest --root "$PROJECT_ROOT" --output "$BUILD_DIR/source-manifest.txt" "${STAMP_ARGS[@]}" >/dev/null printf 'Source stamp: %s\n' "$SOURCE_STAMP" INCLUDES=( "-I$ROOT/Core/include" "-I$ROOT/Core/src" "-I$ROOT/Compat" "-I$ROOT/Source" "-I$ROOT/Source/VoxelForge/Public" "-I$ROOT/Source/VoxelForge/Private" ) OPT_LEVEL=-O2 LINK_FLAGS=() if [[ -n "$SANITIZERS" ]]; then OPT_LEVEL=-O1 LINK_FLAGS+=("-fsanitize=$SANITIZERS" -fno-sanitize-recover=undefined) if ((EXCLUDE_UNSIGNED_OVERFLOW)); then LINK_FLAGS+=(-fno-sanitize=unsigned-integer-overflow) fi fi FLAGS=( -std=c++20 "$OPT_LEVEL" -mavx2 -mfma -fno-fast-math -fexceptions -pthread "${INCLUDES[@]}" "-DVOXELFORGE_SOURCE_STAMP=\"$SOURCE_STAMP\"" ) FLAGS+=("${LINK_FLAGS[@]}") if [[ "$FP_CONTRACT" != "default" ]]; then FLAGS+=("-ffp-contract=$FP_CONTRACT") fi if [[ "$($COMPILER --version | head -n 1)" == *clang* ]]; then FLAGS+=(-Wno-c++11-narrowing) else FLAGS+=(-Wno-narrowing) fi CORE_OBJECTS=() LEGACY_OBJECTS=() PIDS=() wait_oldest() { local pid="${PIDS[0]}" wait "$pid" PIDS=("${PIDS[@]:1}") } compile_background() { local source="$1" output="$2" "$COMPILER" "${FLAGS[@]}" -c "$source" -o "$output" & PIDS+=("$!") if ((${#PIDS[@]} >= JOBS)); then wait_oldest; fi } while IFS= read -r source_name || [[ -n "$source_name" ]]; do source_name="${source_name%%#*}" source_name="${source_name//[[:space:]]/}" [[ -z "$source_name" ]] && continue source_path="$ROOT/$source_name" [[ -f "$source_path" ]] || { printf 'Missing source from core_sources.txt: %s\n' "$source_name" >&2; exit 2; } if [[ "$source_name" == "Core/src/VoxelForgeCore.cpp" ]]; then object="$BUILD_DIR/objects/VoxelForgeCore.o" compile_background "$source_path" "$object" CORE_OBJECTS+=("$object") continue fi wrapper_name="vfcore_${source_name//[^A-Za-z0-9]/_}" wrapper="$BUILD_DIR/wrappers/$wrapper_name.cpp" cat > "$wrapper" <&2 exit 1 fi printf 'Built Core library: %s\nBuilt headless benchmark: %s\n' "$CORE_LIBRARY" "$OUTPUT" printf 'Built EGL offscreen capture: %s\n' "$CAPTURE_OUTPUT" printf 'Compiler: %s | variant: %s | fp-contract: %s | sanitizers: %s | jobs: %s\n' \ "$COMPILER" "$VARIANT" "$FP_CONTRACT" "${SANITIZERS:-off}" "$JOBS"