New verify.py sanitize tier (Clang address,undefined,float-cast-overflow; GCC address,undefined; -fno-sanitize-recover) runs 19 cases per compiler at LOD0-8 across every generator, passages and the crossing: 0 runtime reports; a planted signed-overflow control is caught by both. A static scan fixed INT_MIN negation in floor division, unbounded signed LOD shifts and coordinate-times-extent overflow in VoxelClipmapDesiredTiles.h and VoxelTypes.h (plugin and standalone), and VoxelWorld.cpp, VoxelContentManager.cpp and VoxelDensityVolume.cpp (plugin only, uncompiled here). Supported-input output unchanged (version 211). fast/medium/full PASS. Research R31 (self-checked): far-LOD 4-8 cut plan. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016dhxM43dnWvUu2B5Ph1iG1
165 lines
5.9 KiB
Bash
Executable File
165 lines
5.9 KiB
Bash
Executable File
#!/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" <<WRAPPER
|
|
#include "CoreNamespacePreamble.h"
|
|
namespace vfcore::detail
|
|
{
|
|
#include "$source_path"
|
|
}
|
|
WRAPPER
|
|
object="$BUILD_DIR/objects/$wrapper_name.o"
|
|
compile_background "$wrapper" "$object"
|
|
CORE_OBJECTS+=("$object")
|
|
|
|
# The same copied compatibility implementations are also needed by the standalone owner
|
|
# loader/mesher host. They are compiled globally for that reference layer, as in Build.ps1.
|
|
legacy_object="$BUILD_DIR/objects/legacy_${wrapper_name}.o"
|
|
compile_background "$source_path" "$legacy_object"
|
|
LEGACY_OBJECTS+=("$legacy_object")
|
|
done < "$ROOT/Core/core_sources.txt"
|
|
|
|
headless_object="$BUILD_DIR/objects/StreamBenchmarkHeadless.o"
|
|
compile_background "$ROOT/Source/StreamBenchmarkHeadless.cpp" "$headless_object"
|
|
LEGACY_OBJECTS+=("$headless_object")
|
|
|
|
for pid in "${PIDS[@]}"; do wait "$pid"; done
|
|
PIDS=()
|
|
|
|
CORE_LIBRARY="$BUILD_DIR/libVoxelForgeCore.a"
|
|
"$(command -v ar)" rcs "$CORE_LIBRARY" "${CORE_OBJECTS[@]}"
|
|
OUTPUT="$BIN_DIR/VoxelForgeCoreHeadless-$VARIANT"
|
|
"$COMPILER" -pthread "${LINK_FLAGS[@]}" "${LEGACY_OBJECTS[@]}" "$CORE_LIBRARY" -o "$OUTPUT"
|
|
CAPTURE_OUTPUT="$BIN_DIR/VoxelForgeOffscreenCapture-$VARIANT"
|
|
"$COMPILER" -std=c++20 -O2 -fno-fast-math -pthread \
|
|
"-DVOXELFORGE_SOURCE_STAMP=\"$SOURCE_STAMP\"" -I"$ROOT/Source" \
|
|
"$ROOT/Source/LinuxOffscreenCapture.cpp" -o "$CAPTURE_OUTPUT" \
|
|
$(pkg-config --cflags --libs egl glesv2 libpng)
|
|
|
|
POST_BUILD_STAMP="$(python3 -B "$STAMP_HELPER" stamp --root "$PROJECT_ROOT" "${STAMP_ARGS[@]}")"
|
|
if [[ "$POST_BUILD_STAMP" != "$SOURCE_STAMP" ]]; then
|
|
printf 'Source changed during build: before=%s after=%s\n' "$SOURCE_STAMP" "$POST_BUILD_STAMP" >&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"
|