Some checks are pending
Fuzz Smoke / libFuzzer smoke (push) Waiting to run
Startup ordering defects were only observable by waiting minutes on a live daemon, and the one that aborted it took a live restart loop to find. Give the startup contracts a deterministic harness that runs in milliseconds. + startup_fuzz_support.h drives the real ServiceManagerFsm and the real DeferralGate with virtual time: legal phase advances, injected failure, shutdown and terminal reset, idle/busy, pressure/calm, starvation deadlines and cancellation + oracles fail closed on shutdown resurrection without reset, failure-to-ready, eligibility disagreeing with fsm.isReady(), admission outside the virtual deadline, and ineligible work touching the admission gate; fuzzed IEEE-754 components must never yield non-finite or out-of-range scores + catch2_startup_replay runs named regressions plus 1024 seeded traces per run and reports the root seed and action offset for replay + fuzz_startup builds the same harness for libFuzzer/AFL, with a seed generator that refuses to overwrite different existing files - the fuzzing lane no longer defaults to TSan: harnesses link -fsanitize=fuzzer,address,undefined and the two runtimes cannot share a process; combining them now fails with an explanation instead of producing a binary that cannot start - documented the lane invocation, target naming and the coverage limits, including that governor call ordering inside the poller is not covered Scope: contract-valid single-owner schedules. Executor interleavings, late callbacks, concurrent FSM instances and filesystem/model faults are not modeled. Signed-off-by: trvon <git@trevon.dev>
1220 lines
45 KiB
Bash
Executable file
1220 lines
45 KiB
Bash
Executable file
#!/bin/bash
|
|
|
|
# Unified build script for YAMS
|
|
#
|
|
# Usage: ./setup.sh [Debug|Release|Profiling|Fuzzing] [--coverage] [--tsan] [--no-tsan] [--asan] [--no-asan]
|
|
# ./setup.sh Release --with-tests [--with-onnx] [--offline] [--system-deps]
|
|
# --with-onnx: Build the deprecated ONNX Runtime integration (off by default)
|
|
# build_type: Release (default), Debug, Profiling, or Fuzzing (TODO)
|
|
# --coverage: Enable code coverage instrumentation (Debug builds only)
|
|
# --tsan: Enable ThreadSanitizer for race detection (default for Debug builds)
|
|
# --no-tsan: Disable ThreadSanitizer (overrides default)
|
|
# --asan: Enable AddressSanitizer for memory error detection
|
|
# --no-asan: Disable AddressSanitizer (overrides default)
|
|
#
|
|
# Environment variables (for CI/advanced use):
|
|
# YAMS_OFFLINE - Disable network access for dependency resolution
|
|
# (Conan cache only, no wrap downloads)
|
|
# YAMS_USE_SYSTEM_DEPS - Skip Conan entirely and resolve dependencies via
|
|
# pkg-config/CMake/system prefixes
|
|
# YAMS_CONAN_HOST_PROFILE - Path to Conan host profile (bypasses auto-detection)
|
|
# YAMS_CONAN_ARCH - Target architecture (x86_64, armv8, etc.)
|
|
# YAMS_BUILD_DIR - Override the Meson/Conan build directory
|
|
# YAMS_EXTRA_MESON_FLAGS - Additional Meson setup flags
|
|
# YAMS_PKG_CONFIG_PATH - Extra host pkg-config search path passed to Meson
|
|
# YAMS_BUILD_PKG_CONFIG_PATH - Extra build-machine pkg-config path for Meson
|
|
# YAMS_CMAKE_PREFIX_PATH - Extra host CMake prefix path passed to Meson
|
|
# YAMS_BUILD_CMAKE_PREFIX_PATH - Extra build-machine CMake prefix path for Meson
|
|
# YAMS_MESON_NATIVE_FILE - Use this Meson native file instead of Conan output
|
|
# YAMS_MESON_CROSS_FILE - Use this Meson cross file instead of Conan output
|
|
# YAMS_MESON_WRAP_MODE - Override Meson wrap mode (default, nofallback,
|
|
# nodownload, forcefallback, nopromote)
|
|
# YAMS_ENABLE_MOBILE_BINDINGS - Build mobile C ABI shared library (true/false)
|
|
# YAMS_DISABLE_RE2 - Disable RE2 dependency and use std::regex fallback (true/false)
|
|
# YAMS_COMPILER - Force compiler (clang or gcc)
|
|
# YAMS_CPPSTD - C++ standard (17, 20, 23)
|
|
# YAMS_ENABLE_MODULES - Enable C++20 modules (true/false, auto-detected if not set)
|
|
# YAMS_LIBCXX_HARDENING - libc++ hardening mode (none, fast, extensive, debug)
|
|
# YAMS_INSTALL_PREFIX - Installation prefix (default: /usr/local or Homebrew)
|
|
# YAMS_ONNX_GPU - GPU provider for ONNX (auto|cuda|coreml|migraphx|none, default: auto)
|
|
# auto: macOS=coreml, Linux+NVIDIA=cuda, Linux+ROCm=migraphx, otherwise=none
|
|
# migraphx: AMD ROCm GPU acceleration (builds ONNX Runtime from source)
|
|
# YAMS_USE_SYSTEM_ONNX - Use system-installed onnxruntime (auto|true|false, default: auto)
|
|
# auto: detect system onnxruntime and use it if found
|
|
# true: require system onnxruntime (fail if not found)
|
|
# false: always download/build via Conan recipe
|
|
# YAMS_ONNX_PREFIX - Override prefix path for system onnxruntime
|
|
# (e.g., /opt/homebrew/opt/onnxruntime)
|
|
# YAMS_ROCM_PATH - ROCm installation path for MIGraphX builds (default: /opt/rocm)
|
|
# YAMS_ROCM_GPU_TARGETS - Semicolon-separated AMD GPU architectures for MIGraphX builds
|
|
# (default: gfx900;gfx906;gfx908;gfx90a;gfx1030;gfx1100)
|
|
# Common targets:
|
|
# gfx900 = Vega 10 (MI25, Vega 56/64)
|
|
# gfx906 = Vega 20 (MI50/60, Radeon VII)
|
|
# gfx908 = CDNA (MI100)
|
|
# gfx90a = CDNA2 (MI200 series: MI210, MI250, MI250X)
|
|
# gfx942 = CDNA3 (MI300 series: MI300A, MI300X, MI325X)
|
|
# gfx1030 = RDNA2 (RX 6800/6900 series)
|
|
# gfx1100 = RDNA3 (RX 7900 series)
|
|
# gfx1101 = RDNA3 (RX 7700/7800 series)
|
|
# gfx1200 = RDNA4 (RX 9070 series)
|
|
#
|
|
# The script prefers Clang when available, falling back to GCC otherwise. It
|
|
# ensures Conan is given a concrete C++ standard so dependencies resolve cleanly
|
|
# and keeps Meson in sync with the generated toolchain file.
|
|
|
|
set -euo pipefail
|
|
|
|
is_true() {
|
|
case "${1:-}" in
|
|
1 | true | TRUE | yes | YES | on | ON)
|
|
return 0
|
|
;;
|
|
*)
|
|
return 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
command_path_or_empty() {
|
|
command -v "$1" 2>/dev/null || true
|
|
}
|
|
|
|
ENABLE_OFFLINE=false
|
|
USE_SYSTEM_DEPS=false
|
|
ENABLE_COVERAGE=false
|
|
ENABLE_TSAN="${ENABLE_TSAN:-}" # Preserve environment variable if set
|
|
ENABLE_ASAN="${ENABLE_ASAN:-}" # Preserve environment variable if set
|
|
BUILD_TYPE_INPUT=""
|
|
ENABLE_RELEASE_TESTS=false
|
|
ENABLE_ONNX=false
|
|
TSAN_EXPLICIT=false
|
|
ASAN_EXPLICIT=false
|
|
|
|
if is_true "${YAMS_OFFLINE:-false}"; then
|
|
ENABLE_OFFLINE=true
|
|
fi
|
|
|
|
if is_true "${YAMS_USE_SYSTEM_DEPS:-false}"; then
|
|
USE_SYSTEM_DEPS=true
|
|
fi
|
|
|
|
INITIAL_MESON_BIN="$(command_path_or_empty meson)"
|
|
INITIAL_NINJA_BIN="$(command_path_or_empty ninja)"
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--coverage)
|
|
ENABLE_COVERAGE=true
|
|
shift
|
|
;;
|
|
--tsan)
|
|
ENABLE_TSAN=true
|
|
TSAN_EXPLICIT=true
|
|
shift
|
|
;;
|
|
--no-tsan)
|
|
ENABLE_TSAN=false
|
|
TSAN_EXPLICIT=true
|
|
shift
|
|
;;
|
|
--asan)
|
|
ENABLE_ASAN=true
|
|
ASAN_EXPLICIT=true
|
|
shift
|
|
;;
|
|
--no-asan)
|
|
ENABLE_ASAN=false
|
|
ASAN_EXPLICIT=true
|
|
shift
|
|
;;
|
|
--with-tests)
|
|
# Force building tests/benchmarks even in Release builds.
|
|
ENABLE_RELEASE_TESTS=true
|
|
shift
|
|
;;
|
|
--with-onnx)
|
|
# ONNX Runtime is deprecated and opt-in: it adds a heavy onnxruntime
|
|
# dependency (built from source for some GPU providers).
|
|
ENABLE_ONNX=true
|
|
shift
|
|
;;
|
|
--offline)
|
|
ENABLE_OFFLINE=true
|
|
shift
|
|
;;
|
|
--system-deps)
|
|
USE_SYSTEM_DEPS=true
|
|
shift
|
|
;;
|
|
Debug | Release | Profiling | Fuzzing | debug | release | profiling | fuzzing)
|
|
if [[ -n "${BUILD_TYPE_INPUT}" ]]; then
|
|
echo "Error: Build type specified multiple times" >&2
|
|
exit 1
|
|
fi
|
|
BUILD_TYPE_INPUT="$1"
|
|
shift
|
|
;;
|
|
*)
|
|
echo "Usage: $0 [Debug|Release|Profiling|Fuzzing] [--coverage] [--tsan] [--no-tsan] [--asan] [--no-asan] [--with-tests] [--with-onnx] [--offline] [--system-deps]" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
BUILD_TYPE_INPUT=${BUILD_TYPE_INPUT:-Release}
|
|
|
|
# ONNX Runtime is deprecated and opt-in (--with-onnx). YAMS_DISABLE_ONNX=true still
|
|
# forces it off for older scripts.
|
|
if [[ "${YAMS_DISABLE_ONNX:-}" == "true" ]]; then
|
|
ENABLE_ONNX=false
|
|
fi
|
|
BUILD_TYPE_INPUT_LOWER=$(echo "${BUILD_TYPE_INPUT}" | tr '[:upper:]' '[:lower:]')
|
|
|
|
case "${BUILD_TYPE_INPUT_LOWER}" in
|
|
debug)
|
|
BUILD_TYPE="Debug"
|
|
;;
|
|
release)
|
|
BUILD_TYPE="Release"
|
|
;;
|
|
profiling)
|
|
# Profile what ships: Release Conan dependencies and the Release Meson
|
|
# configuration (-O3 -g, NDEBUG), plus Tracy and frame pointers. No sanitizers.
|
|
BUILD_TYPE="Release"
|
|
ENABLE_PROFILING=true
|
|
;;
|
|
fuzzing)
|
|
BUILD_TYPE="Debug" # Use Debug as base for Conan/Meson
|
|
ENABLE_FUZZING=true
|
|
echo "Fuzzing build: AFL++/libFuzzer instrumentation enabled"
|
|
;;
|
|
*)
|
|
echo "Unknown build type: ${BUILD_TYPE_INPUT}. Expected Debug, Release, Profiling, or Fuzzing." >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
if [[ "${ENABLE_COVERAGE}" == "true" ]] && [[ "${BUILD_TYPE}" != "Debug" ]]; then
|
|
echo "Error: --coverage flag requires Debug build type" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Select desired C++ standard.
|
|
# Override with YAMS_CPPSTD=20/23.
|
|
# macOS defaults to C++20 to stay aligned with the repo's supported Conan host
|
|
# profiles and current CI dependency graph. Other platforms prefer C++23 when
|
|
# the compiler supports constexpr containers.
|
|
if [[ -z "${YAMS_CPPSTD:-}" ]]; then
|
|
if [[ "$(uname -s)" == "Darwin" ]]; then
|
|
CPPSTD_INPUT="20"
|
|
echo "macOS defaulting to C++20 for Conan/Meson compatibility"
|
|
else
|
|
# Test if compiler supports C++23 with constexpr containers
|
|
if echo '#include <vector>
|
|
#if __cplusplus >= 202302L && defined(__cpp_lib_constexpr_vector) && __cpp_lib_constexpr_vector >= 201907L
|
|
#define HAS_CPP23_CONTAINERS 1
|
|
#else
|
|
#define HAS_CPP23_CONTAINERS 0
|
|
#endif
|
|
#if !HAS_CPP23_CONTAINERS
|
|
#error "No C++23 constexpr containers"
|
|
#endif' | "${CXX:-c++}" -std=c++23 -fsyntax-only -x c++ - >/dev/null 2>&1; then
|
|
CPPSTD_INPUT="23"
|
|
echo "Auto-detected C++23 compiler support (constexpr containers available)"
|
|
else
|
|
CPPSTD_INPUT="20"
|
|
echo "C++23 not fully supported, using C++20"
|
|
fi
|
|
fi
|
|
else
|
|
CPPSTD_INPUT="${YAMS_CPPSTD}"
|
|
fi
|
|
|
|
case "${CPPSTD_INPUT}" in
|
|
17 | 20 | 23)
|
|
CPPSTD="${CPPSTD_INPUT}"
|
|
;;
|
|
c++17 | c++20 | c++23)
|
|
CPPSTD="${CPPSTD_INPUT#c++}"
|
|
;;
|
|
*)
|
|
echo "Unknown C++ standard: ${CPPSTD_INPUT}. Expected 17|20|23 or c++17|c++20|c++23." >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
# Value for Meson project option
|
|
MESON_CPPSTD="c++${CPPSTD}"
|
|
|
|
if [[ -z "${YAMS_ENABLE_MODULES:-}" ]]; then
|
|
ENABLE_MODULES=false
|
|
if echo 'export module test; export int foo() { return 42; }' |
|
|
"${CXX:-c++}" -std=c++20 -fmodules -fsyntax-only -x c++ - >/dev/null 2>&1; then
|
|
ENABLE_MODULES=true
|
|
echo "Auto-detected C++20 module support (Clang -fmodules)"
|
|
elif echo 'export module test; export int foo() { return 42; }' |
|
|
"${CXX:-c++}" -std=c++20 -fmodules-ts -fsyntax-only -x c++ - >/dev/null 2>&1; then
|
|
ENABLE_MODULES=true
|
|
echo "Auto-detected C++20 module support (GCC -fmodules-ts)"
|
|
else
|
|
echo "C++20 modules not fully supported by compiler, disabled"
|
|
fi
|
|
else
|
|
if [[ "${YAMS_ENABLE_MODULES}" == "true" ]]; then
|
|
ENABLE_MODULES=true
|
|
echo "C++20 modules enabled via YAMS_ENABLE_MODULES=true"
|
|
else
|
|
ENABLE_MODULES=false
|
|
echo "C++20 modules disabled via YAMS_ENABLE_MODULES=false"
|
|
fi
|
|
fi
|
|
|
|
# libc++ hardening mode (only applies when using libc++)
|
|
# Options: none, fast, extensive, debug
|
|
# Override with YAMS_LIBCXX_HARDENING=fast|extensive|debug|none
|
|
LIBCXX_HARDENING=${YAMS_LIBCXX_HARDENING:-none}
|
|
|
|
# Check if using explicit Conan profile (CI mode)
|
|
CONAN_HOST_PROFILE=${YAMS_CONAN_HOST_PROFILE:-}
|
|
CONAN_ARCH=${YAMS_CONAN_ARCH:-}
|
|
# Conan names 64-bit ARM "armv8"; callers often pass uname/pacman labels.
|
|
case "${CONAN_ARCH}" in
|
|
aarch64 | arm64) CONAN_ARCH="armv8" ;;
|
|
esac
|
|
CONAN_EXTRA_OPTIONS=${YAMS_CONAN_EXTRA_OPTIONS:-}
|
|
USE_PROFILE=false
|
|
|
|
if [[ -z "${CONAN_HOST_PROFILE}" ]] && [[ "$(uname -s)" == "Darwin" ]]; then
|
|
uname_machine=$(uname -m)
|
|
if [[ "${uname_machine}" == "x86_64" ]]; then
|
|
CONAN_HOST_PROFILE="./conan/profiles/host-macos-apple-clang-x86"
|
|
else
|
|
CONAN_HOST_PROFILE="./conan/profiles/host-macos-apple-clang"
|
|
fi
|
|
fi
|
|
|
|
if [[ -n "${CONAN_HOST_PROFILE}" ]]; then
|
|
if [[ ! -f "${CONAN_HOST_PROFILE}" ]]; then
|
|
echo "ERROR: Conan host profile not found: ${CONAN_HOST_PROFILE}" >&2
|
|
exit 1
|
|
fi
|
|
USE_PROFILE=true
|
|
echo "Using explicit Conan host profile: ${CONAN_HOST_PROFILE}"
|
|
fi
|
|
|
|
CONAN_ARGS=(-s "build_type=${BUILD_TYPE}")
|
|
|
|
if [[ "${ENABLE_OFFLINE}" == "true" ]]; then
|
|
CONAN_ARGS+=(-nr --build=never)
|
|
else
|
|
CONAN_ARGS+=(--update --build=missing)
|
|
fi
|
|
|
|
# Add common Conan options (sqlite3 with FTS5, etc.)
|
|
CONAN_ARGS+=(-o "sqlite3/*:fts5=True")
|
|
|
|
# Fuzzing builds: disable programs in zstd to avoid symlink issues in Docker
|
|
if [[ "${ENABLE_FUZZING:-false}" == "true" ]]; then
|
|
CONAN_ARGS+=(-o "zstd/*:build_programs=False")
|
|
fi
|
|
|
|
# Add extra Conan options from environment (for CI)
|
|
if [[ -n "${CONAN_EXTRA_OPTIONS}" ]]; then
|
|
# shellcheck disable=SC2086
|
|
read -ra EXTRA_OPTS <<<"${CONAN_EXTRA_OPTIONS}"
|
|
CONAN_ARGS+=("${EXTRA_OPTS[@]}")
|
|
echo "Extra Conan options: ${CONAN_EXTRA_OPTIONS}"
|
|
fi
|
|
|
|
detect_version() {
|
|
local bin="$1"
|
|
if command -v "${bin}" >/dev/null 2>&1; then
|
|
if "${bin}" -dumpfullversion >/dev/null 2>&1; then
|
|
"${bin}" -dumpfullversion
|
|
elif "${bin}" -dumpversion >/dev/null 2>&1; then
|
|
"${bin}" -dumpversion
|
|
else
|
|
"${bin}" --version | head -n1 | grep -oE '[0-9]+(\.[0-9]+)*' | head -n1
|
|
fi
|
|
fi
|
|
}
|
|
|
|
COERCE_MAJOR() {
|
|
echo "$1" | cut -d. -f1
|
|
}
|
|
|
|
COMPILER_OVERRIDE=${YAMS_COMPILER:-}
|
|
|
|
# When using explicit profile, skip auto-detection of compiler settings
|
|
if [[ "${USE_PROFILE}" == "true" ]]; then
|
|
echo "Skipping compiler auto-detection (using profile: ${CONAN_HOST_PROFILE})"
|
|
# Still set CC/CXX for Meson if not already set
|
|
if [[ -z "${CC:-}" ]] && command -v clang >/dev/null 2>&1; then
|
|
export CC="clang"
|
|
export CXX="clang++"
|
|
elif [[ -z "${CC:-}" ]] && command -v gcc >/dev/null 2>&1; then
|
|
export CC="gcc"
|
|
export CXX="g++"
|
|
fi
|
|
# Add profile to Conan args
|
|
CONAN_ARGS+=(-pr:h "${CONAN_HOST_PROFILE}" -pr:b default)
|
|
CONAN_ARGS+=(-s:h "build_type=${BUILD_TYPE}")
|
|
CONAN_ARGS+=(-s:h "compiler.cppstd=${CPPSTD}")
|
|
# Add architecture if specified
|
|
if [[ -n "${CONAN_ARCH}" ]]; then
|
|
CONAN_ARGS+=(-s:h "arch=${CONAN_ARCH}")
|
|
echo "Target architecture: ${CONAN_ARCH}"
|
|
fi
|
|
else
|
|
# Auto-detection mode (original behavior)
|
|
if [[ "${COMPILER_OVERRIDE}" == clang ]] || { [[ -z "${COMPILER_OVERRIDE}" ]] && command -v clang >/dev/null 2>&1 && command -v clang++ >/dev/null 2>&1; }; then
|
|
echo "--- Using Clang toolchain ---"
|
|
export CC="clang"
|
|
export CXX="clang++"
|
|
# macOS requires libc++, Linux can use libstdc++11
|
|
if [[ "$(uname -s)" == "Darwin" ]]; then
|
|
LIBCXX="libc++"
|
|
else
|
|
LIBCXX="libstdc++11"
|
|
fi
|
|
CLANG_VERSION=$(detect_version clang++)
|
|
CLANG_MAJOR=$(COERCE_MAJOR "${CLANG_VERSION:-0}")
|
|
if [[ -z "${CLANG_MAJOR}" || "${CLANG_MAJOR}" == 0 ]]; then
|
|
echo "Unable to detect clang version." >&2
|
|
exit 1
|
|
fi
|
|
if [[ "$(uname -s)" == "Darwin" ]]; then
|
|
# On macOS use Conan's apple-clang compiler model
|
|
CONAN_ARGS+=(
|
|
-s "compiler=apple-clang"
|
|
-s "compiler.version=${CLANG_MAJOR}"
|
|
-s "compiler.libcxx=${LIBCXX}"
|
|
-s "compiler.cppstd=${CPPSTD}"
|
|
)
|
|
else
|
|
CONAN_ARGS+=(
|
|
-s "compiler=clang"
|
|
-s "compiler.version=${CLANG_MAJOR}"
|
|
-s "compiler.libcxx=${LIBCXX}"
|
|
-s "compiler.cppstd=${CPPSTD}"
|
|
)
|
|
fi
|
|
else
|
|
echo "--- Using GCC toolchain ---"
|
|
export CC="gcc"
|
|
export CXX="g++"
|
|
if ! command -v g++ >/dev/null 2>&1; then
|
|
echo "g++ not found in PATH." >&2
|
|
exit 1
|
|
fi
|
|
GCC_VERSION=$(detect_version g++)
|
|
GCC_MAJOR=$(COERCE_MAJOR "${GCC_VERSION:-0}")
|
|
if [[ -z "${GCC_MAJOR}" || "${GCC_MAJOR}" == 0 ]]; then
|
|
echo "Unable to detect gcc version." >&2
|
|
exit 1
|
|
fi
|
|
CONAN_ARGS+=(
|
|
-s "compiler=gcc"
|
|
-s "compiler.version=${GCC_MAJOR}"
|
|
-s "compiler.libcxx=libstdc++11"
|
|
-s "compiler.cppstd=${CPPSTD}"
|
|
)
|
|
fi
|
|
fi
|
|
|
|
# Wrap CC/CXX with ccache if available for faster incremental builds.
|
|
# Skip ccache environment wrapping when YAMS_SKIP_CCACHE=1 is set —
|
|
# useful for CI environments where ccache interferes with Conan
|
|
# dependency builds (e.g. OpenBLAS ASM compilation via CMake).
|
|
if [[ "${YAMS_SKIP_CCACHE:-}" == "1" ]]; then
|
|
echo "--- Skipping ccache wrapper (YAMS_SKIP_CCACHE=1) ---"
|
|
elif command -v ccache >/dev/null 2>&1; then
|
|
echo "--- Enabling ccache for faster incremental builds ---"
|
|
# Only wrap if not already wrapped
|
|
if [[ "${CC:-}" != ccache* ]]; then
|
|
export CC="ccache ${CC:-cc}"
|
|
export CXX="ccache ${CXX:-c++}"
|
|
fi
|
|
# Show ccache stats if verbose
|
|
ccache -s 2>/dev/null | head -5 || true
|
|
fi
|
|
|
|
if [[ "${ENABLE_PROFILING:-false}" == "true" ]]; then
|
|
BUILD_DIR="build/profiling"
|
|
CONAN_SUBDIR="build-profiling"
|
|
# Conan writes the Release-based profiling toolchain under a nested build-release directory
|
|
CONAN_ALT_SUBDIR="build-release"
|
|
# Profile optimized code: -O0 zone timings do not predict release hot spots.
|
|
BUILD_TYPE_MESON_LOWER="release"
|
|
elif [[ "${ENABLE_FUZZING:-false}" == "true" ]]; then
|
|
BUILD_DIR="build/fuzzing"
|
|
CONAN_SUBDIR="build-fuzzing"
|
|
# Fuzzing uses Debug as the Conan build type, so Conan writes its toolchain under
|
|
# build-debug (same as Profiling).
|
|
CONAN_ALT_SUBDIR="build-debug"
|
|
BUILD_TYPE_MESON_LOWER="debug"
|
|
elif [[ "${BUILD_TYPE}" == "Debug" ]]; then
|
|
BUILD_DIR="build/debug"
|
|
CONAN_SUBDIR="build-debug"
|
|
BUILD_TYPE_MESON_LOWER="debug"
|
|
else
|
|
BUILD_DIR="build/${BUILD_TYPE_INPUT_LOWER}"
|
|
CONAN_SUBDIR="build-${BUILD_TYPE_INPUT_LOWER}"
|
|
BUILD_TYPE_MESON_LOWER="release"
|
|
fi
|
|
|
|
if [[ -n "${YAMS_BUILD_DIR:-}" ]]; then
|
|
BUILD_DIR="${YAMS_BUILD_DIR}"
|
|
fi
|
|
|
|
# Some Conan generators ignore --output-folder and always emit to build-<build_type>.
|
|
# Remember locations to probe for toolchains and Meson cache files.
|
|
CONAN_GENERATED_DIR="${BUILD_DIR}/build-${BUILD_TYPE_INPUT_LOWER}"
|
|
CONAN_ALT_DIR="${BUILD_DIR}/${CONAN_ALT_SUBDIR:-}"
|
|
|
|
# Detect install prefix based on platform
|
|
if [[ "$(uname -s)" == "Darwin" ]]; then
|
|
# macOS: check for Homebrew installation
|
|
if command -v brew >/dev/null 2>&1; then
|
|
BREW_PREFIX=$(brew --prefix 2>/dev/null || echo "/usr/local")
|
|
INSTALL_PREFIX="${BREW_PREFIX}"
|
|
else
|
|
INSTALL_PREFIX="/usr/local"
|
|
fi
|
|
else
|
|
# Linux: use standard prefix
|
|
INSTALL_PREFIX="/usr/local"
|
|
fi
|
|
|
|
# Allow override via environment
|
|
INSTALL_PREFIX="${YAMS_INSTALL_PREFIX:-${INSTALL_PREFIX}}"
|
|
|
|
echo "Build Type: ${BUILD_TYPE_INPUT}"
|
|
if [[ "${ENABLE_PROFILING:-false}" == "true" ]]; then
|
|
echo "Profiling: Tracy enabled"
|
|
fi
|
|
if [[ "${ENABLE_FUZZING:-false}" == "true" ]]; then
|
|
echo "Fuzzing: AFL++/libFuzzer enabled"
|
|
fi
|
|
echo "Build Dir: ${BUILD_DIR}"
|
|
echo "Install Prefix: ${INSTALL_PREFIX}"
|
|
echo "C++ Std: ${MESON_CPPSTD} (Conan: ${CPPSTD})"
|
|
echo "Offline Mode: ${ENABLE_OFFLINE}"
|
|
echo "System Deps: ${USE_SYSTEM_DEPS}"
|
|
if [[ "${LIBCXX_HARDENING}" != "none" ]]; then
|
|
echo "libc++ Hardening: ${LIBCXX_HARDENING}"
|
|
fi
|
|
if [[ "${ENABLE_RELEASE_TESTS}" == "true" ]]; then
|
|
echo "Release Tests: enabled (--with-tests)"
|
|
fi
|
|
|
|
if [[ "${USE_SYSTEM_DEPS}" != "true" ]]; then
|
|
echo "--- Exporting custom Conan recipes... ---"
|
|
|
|
# Export custom onnxruntime recipe if it exists
|
|
if [[ "${ENABLE_ONNX}" != "true" ]]; then
|
|
echo "Skipping onnxruntime recipe export (ONNX disabled)"
|
|
elif [[ -f "conan/onnxruntime/conanfile.py" ]]; then
|
|
# Avoid sporadic Conan cache race/collision errors by retrying export once.
|
|
echo "Exporting onnxruntime/1.23.0 from conan/onnxruntime/"
|
|
if ! conan export conan/onnxruntime --name=onnxruntime --version=1.23.0; then
|
|
echo "Retrying conan export onnxruntime/1.23.0..."
|
|
conan export conan/onnxruntime --name=onnxruntime --version=1.23.0
|
|
fi
|
|
fi
|
|
|
|
echo "--- Running conan install... ---"
|
|
# Add policy toolchain for legacy recipes if in Docker or CI
|
|
POLICY_TC=""
|
|
if [[ -n "${DOCKERFILE_CONF_REV:-}" ]] || [[ -n "${CI:-}" ]]; then
|
|
POLICY_TC="/tmp/yams_policy_toolchain.cmake"
|
|
echo 'cmake_policy(VERSION 3.5)' >"$POLICY_TC"
|
|
CONAN_ARGS+=(-c "tools.cmake.cmaketoolchain:user_toolchain+=${POLICY_TC}")
|
|
fi
|
|
fi
|
|
|
|
# Enable tests for Debug builds in Conan (needed for Catch2/gtest dependencies)
|
|
if [[ "${BUILD_TYPE}" == "Debug" ]] || [[ "${ENABLE_PROFILING:-false}" == "true" ]] || [[ "${ENABLE_FUZZING:-false}" == "true" ]]; then
|
|
CONAN_ARGS+=(-o "&:build_tests=True")
|
|
fi
|
|
|
|
# Optionally enable tests in Conan for Release builds.
|
|
if [[ "${BUILD_TYPE}" == "Release" ]] && [[ "${ENABLE_RELEASE_TESTS}" == "true" ]]; then
|
|
CONAN_ARGS+=(-o "&:build_tests=True")
|
|
fi
|
|
|
|
# Enable Tracy profiling for profiling builds
|
|
if [[ "${ENABLE_PROFILING:-false}" == "true" ]]; then
|
|
echo "Tracy profiling enabled"
|
|
CONAN_ARGS+=(-o "yams/*:enable_profiling=True")
|
|
CONAN_ARGS+=(-o "tracy/*:enable=True")
|
|
fi
|
|
|
|
if [[ "${ENABLE_ONNX}" != "true" ]]; then
|
|
echo "ONNX support disabled (deprecated; pass --with-onnx to build it)"
|
|
CONAN_ARGS+=(-o "yams/*:enable_onnx=False")
|
|
else
|
|
CONAN_ARGS+=(-o "yams/*:enable_onnx=True")
|
|
# --- Detect system-installed onnxruntime ---
|
|
# Override with YAMS_USE_SYSTEM_ONNX=true|false|auto (default: auto)
|
|
# When auto, we detect system onnxruntime and use it if found.
|
|
# Set YAMS_ONNX_PREFIX to override the detected prefix path.
|
|
USE_SYSTEM_ONNX="${YAMS_USE_SYSTEM_ONNX:-auto}"
|
|
SYSTEM_ONNX_PREFIX="${YAMS_ONNX_PREFIX:-}"
|
|
|
|
if [[ "${USE_SYSTEM_ONNX}" == "auto" ]]; then
|
|
# Auto-detect: check pkg-config, Homebrew, common paths
|
|
DETECTED_ONNX_PREFIX=""
|
|
|
|
# 1) pkg-config
|
|
if command -v pkg-config >/dev/null 2>&1 && pkg-config --exists onnxruntime 2>/dev/null; then
|
|
DETECTED_ONNX_PREFIX=$(pkg-config --variable=prefix onnxruntime 2>/dev/null || true)
|
|
if [[ -n "${DETECTED_ONNX_PREFIX}" && -d "${DETECTED_ONNX_PREFIX}" ]]; then
|
|
echo "System onnxruntime detected via pkg-config: ${DETECTED_ONNX_PREFIX}"
|
|
else
|
|
DETECTED_ONNX_PREFIX=""
|
|
fi
|
|
fi
|
|
|
|
# 2) Homebrew (macOS)
|
|
if [[ -z "${DETECTED_ONNX_PREFIX}" && "$(uname -s)" == "Darwin" ]]; then
|
|
if command -v brew >/dev/null 2>&1; then
|
|
BREW_ONNX_PREFIX=$(brew --prefix onnxruntime 2>/dev/null || true)
|
|
if [[ -n "${BREW_ONNX_PREFIX}" && -d "${BREW_ONNX_PREFIX}/lib" && -d "${BREW_ONNX_PREFIX}/include" ]]; then
|
|
# Verify it's actually installed (brew --prefix returns cellar path even if not installed)
|
|
if ls "${BREW_ONNX_PREFIX}"/lib/libonnxruntime* >/dev/null 2>&1; then
|
|
DETECTED_ONNX_PREFIX="${BREW_ONNX_PREFIX}"
|
|
echo "System onnxruntime detected via Homebrew: ${DETECTED_ONNX_PREFIX}"
|
|
fi
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# 3) Common system paths
|
|
if [[ -z "${DETECTED_ONNX_PREFIX}" ]]; then
|
|
for candidate_prefix in /opt/homebrew /usr/local /usr; do
|
|
if ls "${candidate_prefix}"/lib/libonnxruntime* >/dev/null 2>&1; then
|
|
# Check all known header layouts:
|
|
# Flat: include/onnxruntime_c_api.h (prebuilt archives)
|
|
# Homebrew: include/onnxruntime/onnxruntime_c_api.h (brew)
|
|
# Source: include/onnxruntime/core/session/onnxruntime_c_api.h (apt/manual)
|
|
if [[ -f "${candidate_prefix}/include/onnxruntime_c_api.h" ]] ||
|
|
[[ -f "${candidate_prefix}/include/onnxruntime/onnxruntime_c_api.h" ]] ||
|
|
[[ -f "${candidate_prefix}/include/onnxruntime/core/session/onnxruntime_c_api.h" ]]; then
|
|
DETECTED_ONNX_PREFIX="${candidate_prefix}"
|
|
echo "System onnxruntime detected at: ${DETECTED_ONNX_PREFIX}"
|
|
break
|
|
fi
|
|
fi
|
|
done
|
|
fi
|
|
|
|
if [[ -n "${DETECTED_ONNX_PREFIX}" ]]; then
|
|
USE_SYSTEM_ONNX="true"
|
|
SYSTEM_ONNX_PREFIX="${SYSTEM_ONNX_PREFIX:-${DETECTED_ONNX_PREFIX}}"
|
|
else
|
|
USE_SYSTEM_ONNX="false"
|
|
fi
|
|
fi
|
|
|
|
if [[ "${USE_SYSTEM_ONNX}" == "true" ]]; then
|
|
echo "Using system onnxruntime from: ${SYSTEM_ONNX_PREFIX}"
|
|
CONAN_ARGS+=(-o "onnxruntime/*:use_system=True")
|
|
if [[ -n "${SYSTEM_ONNX_PREFIX}" ]]; then
|
|
CONAN_ARGS+=(-o "onnxruntime/*:system_prefix=${SYSTEM_ONNX_PREFIX}")
|
|
fi
|
|
# Detect system onnxruntime version for informational purposes
|
|
if command -v pkg-config >/dev/null 2>&1 && pkg-config --exists onnxruntime 2>/dev/null; then
|
|
SYS_ONNX_VERSION=$(pkg-config --modversion onnxruntime 2>/dev/null || true)
|
|
if [[ -n "${SYS_ONNX_VERSION}" ]]; then
|
|
echo "System onnxruntime version: ${SYS_ONNX_VERSION}"
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# Auto-detect GPU for ONNX acceleration (skip when using system onnxruntime)
|
|
# Override with YAMS_ONNX_GPU=cuda|coreml|migraphx|none
|
|
if [[ "${USE_SYSTEM_ONNX}" == "true" ]]; then
|
|
echo "Skipping GPU auto-detection (using system onnxruntime)"
|
|
ONNX_GPU="none" # System build has its own GPU support baked in
|
|
else
|
|
ONNX_GPU="${YAMS_ONNX_GPU:-auto}"
|
|
if [[ "${ONNX_GPU}" == "auto" ]]; then
|
|
if [[ "$(uname -s)" == "Darwin" ]]; then
|
|
# macOS: CoreML is included in standard ONNX Runtime builds
|
|
ONNX_GPU="coreml"
|
|
echo "macOS detected: enabling CoreML GPU acceleration (Neural Engine + GPU)"
|
|
elif command -v nvidia-smi >/dev/null 2>&1 && nvidia-smi >/dev/null 2>&1; then
|
|
# NVIDIA GPU detected - now validate CUDA toolkit is actually available
|
|
# nvidia-smi presence alone doesn't guarantee CUDA runtime is usable
|
|
if command -v nvcc >/dev/null 2>&1; then
|
|
# nvcc is available (CUDA toolkit installed via package manager or CUDA SDK)
|
|
ONNX_GPU="cuda"
|
|
echo "NVIDIA GPU + CUDA toolkit (nvcc) detected: enabling CUDA acceleration"
|
|
elif [[ -f /usr/local/cuda/lib64/libcudart.so ]] ||
|
|
[[ -f /usr/local/cuda/lib/libcudart.so ]] ||
|
|
ldconfig -p 2>/dev/null | grep -q libcudart; then
|
|
# CUDA runtime library found (sufficient for inference, even without nvcc)
|
|
ONNX_GPU="cuda"
|
|
echo "NVIDIA GPU + CUDA runtime (libcudart) detected: enabling CUDA acceleration"
|
|
else
|
|
# GPU present but CUDA toolkit/runtime missing - use CPU to avoid runtime failures
|
|
ONNX_GPU="none"
|
|
echo "NVIDIA GPU detected but CUDA toolkit missing: using CPU-only ONNX Runtime"
|
|
echo " Install CUDA toolkit for GPU acceleration: https://developer.nvidia.com/cuda-downloads"
|
|
fi
|
|
elif [[ -d /opt/rocm ]] || command -v rocm-smi >/dev/null 2>&1; then
|
|
# ROCm detected - use MIGraphX (builds ONNX Runtime from source)
|
|
# Detect ROCm path
|
|
if [[ -d /opt/rocm ]]; then
|
|
ROCM_PATH="/opt/rocm"
|
|
elif command -v rocm-smi >/dev/null 2>&1; then
|
|
ROCM_PATH="$(dirname "$(dirname "$(command -v rocm-smi)")")"
|
|
fi
|
|
# Check if MIGraphX is installed (ROCm 7.x uses lib/migraphx/lib/)
|
|
if [[ -f "${ROCM_PATH}/lib/libmigraphx.so" ]] || [[ -f "${ROCM_PATH}/lib/migraphx/lib/libmigraphx.so" ]] || [[ -f "${ROCM_PATH}/lib/libmigraphx_c.so" ]]; then
|
|
ONNX_GPU="migraphx"
|
|
echo "ROCm + MIGraphX detected at ${ROCM_PATH}: enabling AMD GPU acceleration"
|
|
echo " Note: ONNX Runtime will be built from source (takes ~20-30 minutes)"
|
|
|
|
# Auto-detect GPU architecture using rocminfo (with timeout in case of permission issues)
|
|
if [[ -z "${YAMS_ROCM_GPU_TARGETS:-}" ]] && command -v rocminfo >/dev/null 2>&1; then
|
|
DETECTED_TARGETS=$(timeout 5 rocminfo 2>/dev/null | grep -oP 'gfx[0-9a-z]+' | sort -u | tr '\n' ';' | sed 's/;$//' || true)
|
|
if [[ -n "${DETECTED_TARGETS}" ]]; then
|
|
export YAMS_ROCM_GPU_TARGETS="${DETECTED_TARGETS}"
|
|
echo " Auto-detected GPU target(s): ${DETECTED_TARGETS}"
|
|
else
|
|
echo " Could not auto-detect GPU targets (rocminfo failed or no permission)"
|
|
echo " Set YAMS_ROCM_GPU_TARGETS manually if needed (e.g., gfx1100 for RX 7900)"
|
|
fi
|
|
fi
|
|
else
|
|
ONNX_GPU="none"
|
|
echo "ROCm detected at ${ROCM_PATH} but MIGraphX not found"
|
|
echo " Using CPU-only ONNX Runtime"
|
|
echo " Install MIGraphX for GPU acceleration: https://github.com/ROCm/AMDMIGraphX"
|
|
fi
|
|
else
|
|
ONNX_GPU="none"
|
|
echo "No GPU detected: using CPU-only ONNX Runtime"
|
|
fi
|
|
fi
|
|
fi # end: skip GPU detection for system onnxruntime
|
|
|
|
# Handle MIGraphX-specific options (only for non-system builds)
|
|
if [[ "${USE_SYSTEM_ONNX}" != "true" ]] && [[ "${ONNX_GPU}" == "migraphx" ]]; then
|
|
# Set ROCm path for conan (use detected path or environment override)
|
|
ROCM_PATH="${YAMS_ROCM_PATH:-${ROCM_PATH:-/opt/rocm}}"
|
|
if [[ ! -d "${ROCM_PATH}" ]]; then
|
|
echo "ERROR: ROCm not found at ${ROCM_PATH}" >&2
|
|
echo " Set YAMS_ROCM_PATH to your ROCm installation path" >&2
|
|
exit 1
|
|
fi
|
|
CONAN_ARGS+=(-o "onnxruntime/*:rocm_path=${ROCM_PATH}")
|
|
echo "ROCm path: ${ROCM_PATH}"
|
|
|
|
# Pass GPU targets if specified
|
|
if [[ -n "${YAMS_ROCM_GPU_TARGETS:-}" ]]; then
|
|
echo "ROCm GPU targets: ${YAMS_ROCM_GPU_TARGETS}"
|
|
fi
|
|
fi
|
|
|
|
if [[ "${USE_SYSTEM_ONNX}" != "true" ]] && [[ "${ONNX_GPU}" != "none" ]]; then
|
|
CONAN_ARGS+=(-o "onnxruntime/*:with_gpu=${ONNX_GPU}")
|
|
echo "ONNX GPU provider: ${ONNX_GPU}"
|
|
fi
|
|
fi
|
|
|
|
if [[ "${YAMS_DISABLE_RE2:-}" == "true" ]]; then
|
|
echo "RE2 disabled (YAMS_DISABLE_RE2=true)"
|
|
CONAN_ARGS+=(-o "yams/*:enable_re2=False")
|
|
fi
|
|
|
|
MESON_TOOLCHAIN_ARG=""
|
|
MESON_TOOLCHAIN_FILE=""
|
|
MESON_NATIVE_FILE_OVERRIDE="${YAMS_MESON_NATIVE_FILE:-}"
|
|
MESON_CROSS_FILE_OVERRIDE="${YAMS_MESON_CROSS_FILE:-}"
|
|
MESON_EXTRA_NATIVE_FILES=()
|
|
|
|
if [[ -n "${YAMS_EXTRA_MESON_NATIVE_FILES:-}" ]]; then
|
|
IFS=':' read -r -a RAW_EXTRA_NATIVE_FILES <<<"${YAMS_EXTRA_MESON_NATIVE_FILES}"
|
|
for extra_native_file in "${RAW_EXTRA_NATIVE_FILES[@]}"; do
|
|
[[ -z "${extra_native_file}" ]] && continue
|
|
if [[ ! -f "${extra_native_file}" ]]; then
|
|
echo "Error: Extra Meson native file not found: ${extra_native_file}" >&2
|
|
exit 1
|
|
fi
|
|
MESON_EXTRA_NATIVE_FILES+=("${extra_native_file}")
|
|
done
|
|
fi
|
|
|
|
if [[ -n "${MESON_NATIVE_FILE_OVERRIDE}" && -n "${MESON_CROSS_FILE_OVERRIDE}" ]]; then
|
|
echo "Error: Set only one of YAMS_MESON_NATIVE_FILE or YAMS_MESON_CROSS_FILE." >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [[ -n "${MESON_NATIVE_FILE_OVERRIDE}" ]]; then
|
|
if [[ ! -f "${MESON_NATIVE_FILE_OVERRIDE}" ]]; then
|
|
echo "Error: Meson native file not found: ${MESON_NATIVE_FILE_OVERRIDE}" >&2
|
|
exit 1
|
|
fi
|
|
MESON_TOOLCHAIN_ARG="--native-file"
|
|
MESON_TOOLCHAIN_FILE="${MESON_NATIVE_FILE_OVERRIDE}"
|
|
elif [[ -n "${MESON_CROSS_FILE_OVERRIDE}" ]]; then
|
|
if [[ ! -f "${MESON_CROSS_FILE_OVERRIDE}" ]]; then
|
|
echo "Error: Meson cross file not found: ${MESON_CROSS_FILE_OVERRIDE}" >&2
|
|
exit 1
|
|
fi
|
|
MESON_TOOLCHAIN_ARG="--cross-file"
|
|
MESON_TOOLCHAIN_FILE="${MESON_CROSS_FILE_OVERRIDE}"
|
|
fi
|
|
|
|
if [[ "${USE_SYSTEM_DEPS}" == "true" ]]; then
|
|
echo "--- Skipping Conan install (system dependency mode) ---"
|
|
else
|
|
# Use runtime_deploy to copy shared libraries next to executables (mainly for Windows, no-op on Unix with RPATH)
|
|
conan install . -of "${BUILD_DIR}" "${CONAN_ARGS[@]}" --deployer=runtime_deploy --deployer-folder="${BUILD_DIR}" -c tools.deployer:symlinks=False
|
|
|
|
# Check for either native or cross file (Conan generates cross file for cross-compilation)
|
|
# Conan 2.x sometimes nests generator output under build-<type>/conan even when -of points at
|
|
# ${BUILD_DIR}. Probe primary, then CONAN_GENERATED_DIR, then the legacy root, then CONAN_ALT_DIR.
|
|
NATIVE_FILE_PRIMARY="${BUILD_DIR}/${CONAN_SUBDIR}/conan/conan_meson_native.ini"
|
|
CROSS_FILE_PRIMARY="${BUILD_DIR}/${CONAN_SUBDIR}/conan/conan_meson_cross.ini"
|
|
NATIVE_FILE_SECONDARY="${CONAN_GENERATED_DIR}/conan/conan_meson_native.ini"
|
|
CROSS_FILE_SECONDARY="${CONAN_GENERATED_DIR}/conan/conan_meson_cross.ini"
|
|
NATIVE_FILE_TERTIARY="${BUILD_DIR}/conan/conan_meson_native.ini"
|
|
CROSS_FILE_TERTIARY="${BUILD_DIR}/conan/conan_meson_cross.ini"
|
|
NATIVE_FILE_QUAT="${CONAN_ALT_DIR}/conan/conan_meson_native.ini"
|
|
CROSS_FILE_QUAT="${CONAN_ALT_DIR}/conan/conan_meson_cross.ini"
|
|
|
|
if [[ -z "${MESON_TOOLCHAIN_ARG}" && -f "${NATIVE_FILE_PRIMARY}" ]]; then
|
|
MESON_TOOLCHAIN_ARG="--native-file"
|
|
MESON_TOOLCHAIN_FILE="${NATIVE_FILE_PRIMARY}"
|
|
elif [[ -z "${MESON_TOOLCHAIN_ARG}" && -f "${CROSS_FILE_PRIMARY}" ]]; then
|
|
MESON_TOOLCHAIN_ARG="--cross-file"
|
|
MESON_TOOLCHAIN_FILE="${CROSS_FILE_PRIMARY}"
|
|
elif [[ -z "${MESON_TOOLCHAIN_ARG}" && -f "${NATIVE_FILE_SECONDARY}" ]]; then
|
|
MESON_TOOLCHAIN_ARG="--native-file"
|
|
MESON_TOOLCHAIN_FILE="${NATIVE_FILE_SECONDARY}"
|
|
elif [[ -z "${MESON_TOOLCHAIN_ARG}" && -f "${CROSS_FILE_SECONDARY}" ]]; then
|
|
MESON_TOOLCHAIN_ARG="--cross-file"
|
|
MESON_TOOLCHAIN_FILE="${CROSS_FILE_SECONDARY}"
|
|
elif [[ -z "${MESON_TOOLCHAIN_ARG}" && -f "${NATIVE_FILE_TERTIARY}" ]]; then
|
|
MESON_TOOLCHAIN_ARG="--native-file"
|
|
MESON_TOOLCHAIN_FILE="${NATIVE_FILE_TERTIARY}"
|
|
elif [[ -z "${MESON_TOOLCHAIN_ARG}" && -f "${CROSS_FILE_TERTIARY}" ]]; then
|
|
MESON_TOOLCHAIN_ARG="--cross-file"
|
|
MESON_TOOLCHAIN_FILE="${CROSS_FILE_TERTIARY}"
|
|
elif [[ -z "${MESON_TOOLCHAIN_ARG}" && -n "${CONAN_ALT_DIR}" && -f "${NATIVE_FILE_QUAT}" ]]; then
|
|
MESON_TOOLCHAIN_ARG="--native-file"
|
|
MESON_TOOLCHAIN_FILE="${NATIVE_FILE_QUAT}"
|
|
elif [[ -z "${MESON_TOOLCHAIN_ARG}" && -n "${CONAN_ALT_DIR}" && -f "${CROSS_FILE_QUAT}" ]]; then
|
|
MESON_TOOLCHAIN_ARG="--cross-file"
|
|
MESON_TOOLCHAIN_FILE="${CROSS_FILE_QUAT}"
|
|
fi
|
|
|
|
if [[ -z "${MESON_TOOLCHAIN_ARG}" ]]; then
|
|
echo "Error: Conan meson toolchain file not found" >&2
|
|
echo "Checked: ${NATIVE_FILE_PRIMARY}" >&2
|
|
echo " and: ${CROSS_FILE_PRIMARY}" >&2
|
|
echo " and: ${NATIVE_FILE_SECONDARY}" >&2
|
|
echo " and: ${CROSS_FILE_SECONDARY}" >&2
|
|
echo " and: ${NATIVE_FILE_TERTIARY}" >&2
|
|
echo " and: ${CROSS_FILE_TERTIARY}" >&2
|
|
if [[ -n "${CONAN_ALT_DIR}" ]]; then
|
|
echo " and: ${NATIVE_FILE_QUAT}" >&2
|
|
echo " and: ${CROSS_FILE_QUAT}" >&2
|
|
fi
|
|
echo "Please check the output path from 'conan install'." >&2
|
|
exit 1
|
|
fi
|
|
|
|
CONAN_TOOLCHAIN_DIR="$(cd "$(dirname "${MESON_TOOLCHAIN_FILE}")" && pwd)"
|
|
CONAN_BUILD_ENV="${CONAN_TOOLCHAIN_DIR}/conanbuild.sh"
|
|
if [[ -f "${CONAN_BUILD_ENV}" ]]; then
|
|
# Activate Conan's build-machine tools before Meson configure so cross-build
|
|
# generators resolve native utilities like protoc from the Conan graph.
|
|
# Conan-generated env scripts may reference variables (e.g. ACLOCAL_PATH)
|
|
# that are unset in minimal environments like Docker; disable nounset temporarily.
|
|
for maybe_unset_var in ACLOCAL_PATH PKG_CONFIG_PATH LD_LIBRARY_PATH DYLD_LIBRARY_PATH \
|
|
DYLD_FALLBACK_LIBRARY_PATH LIBRARY_PATH CMAKE_PREFIX_PATH MANPATH; do
|
|
if [[ -z "${!maybe_unset_var+x}" ]]; then
|
|
export "${maybe_unset_var}="
|
|
fi
|
|
done
|
|
# shellcheck disable=SC1090
|
|
set +u
|
|
source "${CONAN_BUILD_ENV}"
|
|
set -u
|
|
fi
|
|
|
|
# Export BOOST_ROOT so meson's auto-detect Boost dep finds the Conan-installed
|
|
# Boost on platforms with no system Boost (Windows). Read prefix= directly
|
|
# from Conan's boost.pc — that file's location is the same dir holding
|
|
# CONAN_BUILD_ENV.
|
|
if [[ -z "${BOOST_ROOT:-}" ]]; then
|
|
BOOST_PC="${CONAN_TOOLCHAIN_DIR:-}/boost.pc"
|
|
if [[ -f "${BOOST_PC}" ]]; then
|
|
BOOST_ROOT_CANDIDATE=$(awk -F= '/^prefix[[:space:]]*=/ { print $2; exit }' "${BOOST_PC}")
|
|
if [[ -n "${BOOST_ROOT_CANDIDATE}" && -d "${BOOST_ROOT_CANDIDATE}/include/boost" ]]; then
|
|
export BOOST_ROOT="${BOOST_ROOT_CANDIDATE}"
|
|
echo "BOOST_ROOT set to: ${BOOST_ROOT}"
|
|
fi
|
|
fi
|
|
fi
|
|
fi
|
|
YAMS_PROTOC_PATH="${YAMS_PROTOC_PATH:-}"
|
|
|
|
MESON_WRAPPER_PATH=""
|
|
ACTIVE_MESON_BIN="$(command_path_or_empty meson)"
|
|
ACTIVE_NINJA_BIN="$(command_path_or_empty ninja)"
|
|
CONAN_TOOLS_OVERRIDE=false
|
|
if [[ -f "${CONAN_BUILD_ENV:-}" ]]; then
|
|
MESON_WRAPPER_PATH="${BUILD_DIR}/mesonw"
|
|
CONAN_BUILD_ENV_ESCAPED=$(printf '%q' "${CONAN_BUILD_ENV}")
|
|
cat >"${MESON_WRAPPER_PATH}" <<EOF
|
|
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
CONAN_BUILD_ENV=${CONAN_BUILD_ENV_ESCAPED}
|
|
for maybe_unset_var in ACLOCAL_PATH PKG_CONFIG_PATH LD_LIBRARY_PATH DYLD_LIBRARY_PATH \
|
|
DYLD_FALLBACK_LIBRARY_PATH LIBRARY_PATH CMAKE_PREFIX_PATH MANPATH; do
|
|
if [[ -z "\${!maybe_unset_var+x}" ]]; then
|
|
export "\${maybe_unset_var}="
|
|
fi
|
|
done
|
|
if [[ -f "\${CONAN_BUILD_ENV}" ]]; then
|
|
set +u
|
|
# shellcheck disable=SC1090
|
|
source "\${CONAN_BUILD_ENV}"
|
|
set -u
|
|
fi
|
|
exec meson "\$@"
|
|
EOF
|
|
chmod +x "${MESON_WRAPPER_PATH}"
|
|
|
|
if [[ "${ACTIVE_MESON_BIN}" != "${INITIAL_MESON_BIN}" || "${ACTIVE_NINJA_BIN}" != "${INITIAL_NINJA_BIN}" ]]; then
|
|
CONAN_TOOLS_OVERRIDE=true
|
|
fi
|
|
fi
|
|
|
|
MESON_ARGS=(
|
|
"${BUILD_DIR}"
|
|
"--prefix" "${INSTALL_PREFIX}"
|
|
"--buildtype" "${BUILD_TYPE_MESON_LOWER}"
|
|
)
|
|
|
|
if [[ -n "${MESON_TOOLCHAIN_ARG}" ]]; then
|
|
MESON_ARGS+=("${MESON_TOOLCHAIN_ARG}" "${MESON_TOOLCHAIN_FILE}")
|
|
fi
|
|
|
|
if [[ ${#MESON_EXTRA_NATIVE_FILES[@]} -gt 0 ]]; then
|
|
for extra_native_file in "${MESON_EXTRA_NATIVE_FILES[@]}"; do
|
|
MESON_ARGS+=("--native-file" "${extra_native_file}")
|
|
done
|
|
fi
|
|
|
|
MESON_WRAP_MODE="${YAMS_MESON_WRAP_MODE:-}"
|
|
if [[ -z "${MESON_WRAP_MODE}" ]]; then
|
|
if [[ "${USE_SYSTEM_DEPS}" == "true" ]]; then
|
|
MESON_WRAP_MODE="nofallback"
|
|
elif [[ "${ENABLE_OFFLINE}" == "true" ]]; then
|
|
MESON_WRAP_MODE="nodownload"
|
|
else
|
|
MESON_WRAP_MODE="default"
|
|
fi
|
|
fi
|
|
|
|
if [[ "${MESON_WRAP_MODE}" != "default" ]]; then
|
|
MESON_ARGS+=("--wrap-mode" "${MESON_WRAP_MODE}")
|
|
fi
|
|
|
|
if [[ -n "${YAMS_PKG_CONFIG_PATH:-}" ]]; then
|
|
MESON_ARGS+=("--pkg-config-path" "${YAMS_PKG_CONFIG_PATH}")
|
|
fi
|
|
|
|
if [[ -n "${YAMS_BUILD_PKG_CONFIG_PATH:-}" ]]; then
|
|
MESON_ARGS+=("--build.pkg-config-path" "${YAMS_BUILD_PKG_CONFIG_PATH}")
|
|
fi
|
|
|
|
if [[ -n "${YAMS_CMAKE_PREFIX_PATH:-}" ]]; then
|
|
MESON_ARGS+=("--cmake-prefix-path" "${YAMS_CMAKE_PREFIX_PATH}")
|
|
fi
|
|
|
|
if [[ -n "${YAMS_BUILD_CMAKE_PREFIX_PATH:-}" ]]; then
|
|
MESON_ARGS+=("--build.cmake-prefix-path" "${YAMS_BUILD_CMAKE_PREFIX_PATH}")
|
|
fi
|
|
|
|
# Detect previous configured cpp_std to decide on reconfigure vs wipe
|
|
PREV_CPPSTD=""
|
|
INTRO_OPTS_JSON="${BUILD_DIR}/meson-info/intro-buildoptions.json"
|
|
if [[ -f "${INTRO_OPTS_JSON}" ]]; then
|
|
PREV_CPPSTD=$(awk '/"name"\s*:\s*"cpp_std"/{flag=1} flag && /"value"/{gsub(/.*"value"\s*:\s*"|".*/,"",$0); print; exit}' "${INTRO_OPTS_JSON}" || true)
|
|
fi
|
|
|
|
MESON_OPTIONS=("-Dbuild-cli=true" "-Dcpp_std=${MESON_CPPSTD}" "-Denable-modules=${ENABLE_MODULES}")
|
|
if [[ -n "${YAMS_PROTOC_PATH}" ]]; then
|
|
MESON_OPTIONS+=("-Dprotoc-path=${YAMS_PROTOC_PATH}")
|
|
fi
|
|
|
|
# Add libc++ hardening mode if specified
|
|
if [[ "${LIBCXX_HARDENING}" != "none" ]]; then
|
|
MESON_OPTIONS+=("-Dlibcxx-hardening=${LIBCXX_HARDENING}")
|
|
fi
|
|
|
|
# Handle optional feature flags for Meson (must match Conan options)
|
|
if [[ "${ENABLE_ONNX}" == "true" ]]; then
|
|
MESON_OPTIONS+=("-Denable-onnx=enabled")
|
|
else
|
|
MESON_OPTIONS+=("-Denable-onnx=disabled")
|
|
MESON_OPTIONS+=("-Dplugin-onnx=false")
|
|
fi
|
|
|
|
if [[ "${YAMS_DISABLE_RE2:-}" == "true" ]]; then
|
|
MESON_OPTIONS+=("-Denable-re2=disabled")
|
|
fi
|
|
|
|
# Release/Profiling: -O3 with NDEBUG, PIE, and -g kept so packaging can split the
|
|
# debug info into separate symbol files (scripts/split-debug-symbols.sh) instead
|
|
# of shipping it. Debug/Fuzzing keep -O0 -g with assertions.
|
|
MESON_OPTIONS+=("-Db_pie=true")
|
|
if [[ "${BUILD_TYPE_MESON_LOWER}" == "release" || "${BUILD_TYPE_MESON_LOWER}" == "debugoptimized" ]]; then
|
|
MESON_OPTIONS+=("-Db_ndebug=true" "-Ddebug=true")
|
|
else
|
|
MESON_OPTIONS+=("-Db_ndebug=false")
|
|
fi
|
|
|
|
# libSQL backend: default to libsql but fall back to sqlite on Linux when unavailable
|
|
LIBSQL_BACKEND_INPUT=${YAMS_DATABASE_BACKEND:-libsql}
|
|
LIBSQL_BACKEND_LOWER=$(echo "${LIBSQL_BACKEND_INPUT}" | tr '[:upper:]' '[:lower:]')
|
|
if [[ "${LIBSQL_BACKEND_LOWER}" != "libsql" && "${LIBSQL_BACKEND_LOWER}" != "sqlite" ]]; then
|
|
echo "Error: Unknown database backend: ${LIBSQL_BACKEND_INPUT}. Expected libsql or sqlite." >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [[ "${LIBSQL_BACKEND_LOWER}" == "libsql" && "${USE_SYSTEM_DEPS}" == "true" ]]; then
|
|
LIBSQL_PKG_FOUND=false
|
|
if command -v pkg-config >/dev/null 2>&1; then
|
|
if pkg-config --exists libsql || pkg-config --exists libsql-sqlite3; then
|
|
LIBSQL_PKG_FOUND=true
|
|
fi
|
|
fi
|
|
|
|
if [[ "${LIBSQL_PKG_FOUND}" != "true" ]]; then
|
|
echo "System dependency mode: libSQL not found via pkg-config; falling back to sqlite" >&2
|
|
LIBSQL_BACKEND_LOWER="sqlite"
|
|
fi
|
|
elif [[ "${LIBSQL_BACKEND_LOWER}" == "libsql" && "$(uname -s)" != "Darwin" ]]; then
|
|
LIBSQL_PKG_FOUND=false
|
|
if command -v pkg-config >/dev/null 2>&1; then
|
|
if pkg-config --exists libsql || pkg-config --exists libsql-sqlite3; then
|
|
LIBSQL_PKG_FOUND=true
|
|
fi
|
|
fi
|
|
|
|
if [[ "${LIBSQL_PKG_FOUND}" != "true" ]]; then
|
|
if [[ -d "subprojects/libsql" ]]; then
|
|
echo "libSQL subproject detected at subprojects/libsql; keeping libsql backend"
|
|
elif ! command -v cargo >/dev/null 2>&1; then
|
|
echo "libSQL not detected on Linux (pkg-config/cargo missing); falling back to sqlite" >&2
|
|
LIBSQL_BACKEND_LOWER="sqlite"
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
if [[ "${LIBSQL_BACKEND_LOWER}" == "libsql" ]]; then
|
|
echo "Database backend: libsql"
|
|
if [[ -f "subprojects/libsql.wrap" && ! -d "subprojects/libsql" ]]; then
|
|
if [[ "${USE_SYSTEM_DEPS}" == "true" ]]; then
|
|
echo "libSQL not found via system dependencies; falling back to sqlite" >&2
|
|
LIBSQL_BACKEND_LOWER="sqlite"
|
|
elif [[ "${ENABLE_OFFLINE}" == "true" ]]; then
|
|
echo "Offline mode: not fetching libSQL subproject; falling back to sqlite" >&2
|
|
LIBSQL_BACKEND_LOWER="sqlite"
|
|
elif command -v meson >/dev/null 2>&1; then
|
|
echo "Fetching libSQL subproject (meson wrap)..."
|
|
if ! meson subprojects download libsql; then
|
|
echo "Failed to fetch libSQL subproject; falling back to sqlite" >&2
|
|
LIBSQL_BACKEND_LOWER="sqlite"
|
|
fi
|
|
else
|
|
echo "Meson not found; cannot fetch libSQL subproject. Falling back to sqlite" >&2
|
|
LIBSQL_BACKEND_LOWER="sqlite"
|
|
fi
|
|
fi
|
|
else
|
|
echo "Database backend: sqlite"
|
|
fi
|
|
|
|
MESON_OPTIONS+=("-Ddatabase-backend=${LIBSQL_BACKEND_LOWER}")
|
|
|
|
# Mobile bindings are off by default; allow CI/users to opt-in.
|
|
if [[ "${YAMS_ENABLE_MOBILE_BINDINGS:-}" == "true" ]]; then
|
|
MESON_OPTIONS+=("-Denable-mobile-bindings=true")
|
|
echo "Mobile bindings enabled (YAMS_ENABLE_MOBILE_BINDINGS=true)"
|
|
elif [[ "${YAMS_ENABLE_MOBILE_BINDINGS:-}" == "false" ]]; then
|
|
MESON_OPTIONS+=("-Denable-mobile-bindings=false")
|
|
echo "Mobile bindings disabled (YAMS_ENABLE_MOBILE_BINDINGS=false)"
|
|
fi
|
|
|
|
# ThreadSanitizer: default enabled for Debug builds, can be overridden with --tsan/--no-tsan
|
|
if [[ -z "${ENABLE_TSAN}" ]]; then
|
|
# Profiling stays uninstrumented so Tracy timings are not TSAN-distorted (opt in with --tsan).
|
|
# Fuzzing stays uninstrumented too: the fuzz harnesses link -fsanitize=fuzzer,address,undefined
|
|
# and ASan cannot share a process with TSan.
|
|
if [[ "${ENABLE_PROFILING:-false}" == "true" ]] || [[ "${ENABLE_FUZZING:-false}" == "true" ]]; then
|
|
ENABLE_TSAN=false
|
|
elif [[ "${BUILD_TYPE}" == "Debug" ]]; then
|
|
ENABLE_TSAN=true
|
|
else
|
|
ENABLE_TSAN=false
|
|
fi
|
|
fi
|
|
|
|
# AddressSanitizer: default disabled; enable with --asan or ENABLE_ASAN=true
|
|
if [[ -z "${ENABLE_ASAN}" ]]; then
|
|
ENABLE_ASAN=false
|
|
fi
|
|
|
|
# If ASAN was explicitly requested and TSAN wasn't explicitly chosen, prefer ASAN for this build.
|
|
if [[ "${ENABLE_ASAN}" == "true" ]] && [[ "${ASAN_EXPLICIT}" == "true" ]] && [[ "${TSAN_EXPLICIT}" == "false" ]]; then
|
|
ENABLE_TSAN=false
|
|
fi
|
|
|
|
if [[ "${ENABLE_TSAN}" == "true" ]] && [[ "${ENABLE_ASAN}" == "true" ]]; then
|
|
echo "Error: TSAN and ASAN cannot be enabled in the same build directory." >&2
|
|
echo "Use separate invocations, e.g.:" >&2
|
|
echo " ./setup.sh Debug --tsan --no-asan" >&2
|
|
echo " ./setup.sh Debug --asan --no-tsan" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Fuzz harnesses link -fsanitize=fuzzer,address,undefined, so TSan cannot share the binary.
|
|
if [[ "${ENABLE_FUZZING:-false}" == "true" ]] && [[ "${ENABLE_TSAN}" == "true" ]]; then
|
|
echo "Error: Fuzzing builds link ASan/UBSan via the fuzz harnesses and cannot use TSAN." >&2
|
|
echo "Drop --tsan, or configure a separate directory without -Dbuild-fuzzers=true." >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [[ "${BUILD_TYPE}" == "Debug" ]] || [[ "${ENABLE_PROFILING:-false}" == "true" ]] || [[ "${ENABLE_FUZZING:-false}" == "true" ]]; then
|
|
MESON_OPTIONS+=(
|
|
"-Dbuild-tests=true"
|
|
"-Denable-bench-tests=true"
|
|
"-Denable-vector-tests=true"
|
|
"-Dbuild-benchmarks=true"
|
|
)
|
|
echo "Vector/embedding tests and benchmarks enabled for ${BUILD_TYPE} build"
|
|
fi
|
|
|
|
# Optionally enable tests in Release builds for benchmark executables.
|
|
if [[ "${BUILD_TYPE}" == "Release" ]] && [[ "${ENABLE_RELEASE_TESTS}" == "true" ]]; then
|
|
MESON_OPTIONS+=(
|
|
"-Dbuild-tests=true"
|
|
)
|
|
echo "Tests enabled for Release build (benchmarks under tests/benchmarks will be built)"
|
|
fi
|
|
|
|
# Sanitizers are selected through Meson's b_sanitize; enable-tsan/enable-asan only
|
|
# mirror that choice for third_party/symspell.
|
|
MESON_OPTIONS+=("-Denable-tsan=${ENABLE_TSAN}")
|
|
MESON_OPTIONS+=("-Denable-asan=${ENABLE_ASAN}")
|
|
if [[ "${ENABLE_TSAN}" == "true" ]]; then
|
|
MESON_OPTIONS+=("-Db_sanitize=thread")
|
|
cc_tool="${CC##* }"
|
|
cxx_tool="${CXX##* }"
|
|
if [[ "${cc_tool}" == clang* ]] || [[ "${cxx_tool}" == clang++* ]]; then
|
|
MESON_OPTIONS+=("-Db_lundef=false")
|
|
echo "ThreadSanitizer on Clang: forcing b_lundef=false to avoid Meson link warnings"
|
|
fi
|
|
echo "ThreadSanitizer enabled (race detection)"
|
|
elif [[ "${ENABLE_ASAN}" == "true" ]]; then
|
|
MESON_OPTIONS+=("-Db_sanitize=address,undefined")
|
|
echo "AddressSanitizer enabled (memory safety checks)"
|
|
else
|
|
# Ensure any previous sanitizer setting doesn't persist across reconfigure.
|
|
# Users can override via YAMS_EXTRA_MESON_FLAGS. Only reset explicit sanitizer
|
|
# state when reconfiguring an existing builddir; clean builds do not need it.
|
|
if [[ -f "${INTRO_OPTS_JSON}" ]]; then
|
|
MESON_OPTIONS+=("-Db_sanitize=none")
|
|
fi
|
|
fi
|
|
|
|
if [[ "${ENABLE_PROFILING:-false}" == "true" ]]; then
|
|
MESON_OPTIONS+=(
|
|
"-Denable-profiling=true"
|
|
)
|
|
echo "Tracy profiling enabled for Meson build"
|
|
fi
|
|
|
|
if [[ "${ENABLE_FUZZING:-false}" == "true" ]]; then
|
|
MESON_OPTIONS+=(
|
|
"-Dbuild-fuzzers=true"
|
|
# Sanitizer and SanitizerCoverage symbols in shared libraries resolve against the
|
|
# fuzzer executable, so shared objects must not be linked with --no-undefined.
|
|
"-Db_lundef=false"
|
|
)
|
|
echo "Fuzzing targets enabled for Meson build"
|
|
fi
|
|
|
|
if [[ "${ENABLE_COVERAGE}" == "true" ]]; then
|
|
MESON_OPTIONS+=("-Db_coverage=true")
|
|
echo "Coverage instrumentation enabled"
|
|
fi
|
|
|
|
# Add extra Meson flags from environment (for CI)
|
|
if [[ -n "${YAMS_EXTRA_MESON_FLAGS:-}" ]]; then
|
|
# shellcheck disable=SC2086
|
|
read -ra EXTRA_FLAGS <<<"${YAMS_EXTRA_MESON_FLAGS}"
|
|
MESON_OPTIONS+=("${EXTRA_FLAGS[@]}")
|
|
echo "Extra Meson flags: ${YAMS_EXTRA_MESON_FLAGS}"
|
|
fi
|
|
|
|
# Auto-enable zyp plugin if Zig 0.15.2+ is installed
|
|
if command -v zig >/dev/null 2>&1; then
|
|
ZIG_VERSION=$(zig version 2>/dev/null || echo "0.0.0")
|
|
# Parse major.minor.patch
|
|
ZIG_MAJOR=$(echo "${ZIG_VERSION}" | cut -d. -f1)
|
|
ZIG_MINOR=$(echo "${ZIG_VERSION}" | cut -d. -f2)
|
|
ZIG_PATCH=$(echo "${ZIG_VERSION}" | cut -d. -f3 | cut -d- -f1) # Handle -dev suffix
|
|
# Check if >= 0.15.2
|
|
if [[ "${ZIG_MAJOR:-0}" -gt 0 ]] ||
|
|
{ [[ "${ZIG_MAJOR:-0}" -eq 0 ]] && [[ "${ZIG_MINOR:-0}" -gt 15 ]]; } ||
|
|
{ [[ "${ZIG_MAJOR:-0}" -eq 0 ]] && [[ "${ZIG_MINOR:-0}" -eq 15 ]] && [[ "${ZIG_PATCH:-0}" -ge 2 ]]; }; then
|
|
echo "Zig ${ZIG_VERSION} detected, enabling zyp PDF plugin"
|
|
MESON_OPTIONS+=("-Dplugin-zyp=true")
|
|
else
|
|
echo "Zig ${ZIG_VERSION} found but requires 0.15.2+ for zyp plugin"
|
|
fi
|
|
fi
|
|
|
|
# Glint NL entity extractor plugin (GLiNER-based) requires ONNX Runtime.
|
|
if [[ "${ENABLE_ONNX}" == "true" ]]; then
|
|
echo "Enabling Glint NL entity extractor plugin"
|
|
MESON_OPTIONS+=("-Dplugin-glint=true")
|
|
fi
|
|
|
|
echo "--- Running meson setup... ---"
|
|
if [[ -n "${PREV_CPPSTD}" ]]; then
|
|
if [[ "${PREV_CPPSTD}" != "${MESON_CPPSTD}" ]]; then
|
|
echo "cpp_std changed (${PREV_CPPSTD} -> ${MESON_CPPSTD}); wiping build directory configuration..."
|
|
meson setup "${MESON_ARGS[@]}" "${MESON_OPTIONS[@]}" --wipe
|
|
else
|
|
meson setup "${MESON_ARGS[@]}" "${MESON_OPTIONS[@]}" --reconfigure
|
|
fi
|
|
else
|
|
meson setup "${MESON_ARGS[@]}" "${MESON_OPTIONS[@]}"
|
|
fi
|
|
|
|
echo
|
|
echo "--- Setup complete! ---"
|
|
if [[ "${CONAN_TOOLS_OVERRIDE}" == "true" ]]; then
|
|
echo "Conan provided Meson/Ninja for this build directory."
|
|
echo "To compile, run: ${MESON_WRAPPER_PATH} compile -C ${BUILD_DIR}"
|
|
echo "To install, run: ${MESON_WRAPPER_PATH} install -C ${BUILD_DIR}"
|
|
elif [[ -n "${MESON_WRAPPER_PATH}" ]]; then
|
|
echo "To compile, run: meson compile -C ${BUILD_DIR}"
|
|
echo "To install, run: meson install -C ${BUILD_DIR}"
|
|
echo "Fallback wrapper (replays Conan build env if needed): ${MESON_WRAPPER_PATH}"
|
|
else
|
|
echo "To compile, run: meson compile -C ${BUILD_DIR}"
|
|
echo "To install, run: meson install -C ${BUILD_DIR}"
|
|
fi
|