#!/usr/bin/env bash set -euo pipefail # ============================================================ # build.sh — dstalk cross-platform build script (Linux / macOS) # Mirrors build.bat; installs tools into tools/ if missing, # then runs Conan + CMake + Ninja without modifying system PATH. # ============================================================ ROOT="$(cd "$(dirname "$0")" && pwd)" TOOLS="${ROOT}/tools" BUILD_DIR="${ROOT}/build" BUILD_TYPE="${1:-Release}" echo "[dstalk] Build type: ${BUILD_TYPE}" echo "[dstalk] Project root: ${ROOT}" # ============================================================ # 1. Detect / resolve tool paths (prefer tools/, fallback PATH) # ============================================================ find_tool() { local name="$1" shift for candidate in "$@"; do if [ -x "$candidate" ]; then echo "$candidate" return 0 fi done local sys sys=$(command -v "$name" 2>/dev/null || true) if [ -n "$sys" ]; then echo "$sys" return 0 fi return 1 } CMAKE_EXE=$(find_tool cmake "${TOOLS}/cmake/bin/cmake") || { echo " [ERROR] CMake not found. Run: tools/setup.sh" exit 1 } NINJA_EXE=$(find_tool ninja "${TOOLS}/ninja/ninja") || { echo " [ERROR] Ninja not found. Run: tools/setup.sh" exit 1 } CONAN_EXE=$(find_tool conan "${TOOLS}/.venv/bin/conan") || { echo " [ERROR] Conan2 not found. Run: tools/setup.sh" exit 1 } # Compiler: prefer clang, fallback gcc if [ "$(uname)" = "Darwin" ]; then CC_EXE=$(find_tool clang "${TOOLS}/llvm/bin/clang") || CC_EXE="clang" CXX_EXE=$(find_tool clang++ "${TOOLS}/llvm/bin/clang++") || CXX_EXE="clang++" else CC_EXE=$(find_tool clang "${TOOLS}/llvm/bin/clang") || \ CC_EXE=$(find_tool gcc) || { echo " [ERROR] No C compiler found"; exit 1; } CXX_EXE=$(find_tool clang++ "${TOOLS}/llvm/bin/clang++") || \ CXX_EXE=$(find_tool g++) || { echo " [ERROR] No C++ compiler found"; exit 1; } fi echo "[dstalk] CMake: ${CMAKE_EXE}" echo "[dstalk] Ninja: ${NINJA_EXE}" echo "[dstalk] Conan: ${CONAN_EXE}" echo "[dstalk] CC: ${CC_EXE}" echo "[dstalk] CXX: ${CXX_EXE}" # ============================================================ # 2. Conan install dependencies # ============================================================ echo "[dstalk] Conan: installing dependencies..." "${CONAN_EXE}" install deps/ -of "${BUILD_DIR}" --build=missing \ -s build_type="${BUILD_TYPE}" \ -c tools.cmake.cmaketoolchain:generator=Ninja # Locate the conan toolchain CONAN_TOOLCHAIN="" for candidate in \ "${BUILD_DIR}/build/${BUILD_TYPE}/generators/conan_toolchain.cmake" \ "${BUILD_DIR}/${BUILD_TYPE}/generators/conan_toolchain.cmake" \ "${BUILD_DIR}/${BUILD_TYPE}/conan_toolchain.cmake" \ "${BUILD_DIR}/conan_toolchain.cmake"; do if [ -f "$candidate" ]; then CONAN_TOOLCHAIN="$candidate" break fi done if [ -z "${CONAN_TOOLCHAIN}" ]; then echo " [ERROR] Could not find conan_toolchain.cmake" echo " Searched in: ${BUILD_DIR}/build/${BUILD_TYPE}/generators/" echo " ${BUILD_DIR}/${BUILD_TYPE}/generators/" exit 1 fi echo "[dstalk] Conan toolchain: ${CONAN_TOOLCHAIN}" CONAN_PREFIX_PATH="$(dirname "${CONAN_TOOLCHAIN}")" # Patch conan toolchain if it hardcodes 'cl' (Windows-generated) if grep -q 'set(CMAKE_C_COMPILER "cl")' "${CONAN_TOOLCHAIN}" 2>/dev/null; then echo "[dstalk] Patching conan toolchain: replacing cl -> detected compiler" sed -i.bak \ -e "s|set(CMAKE_C_COMPILER \"cl\")|set(CMAKE_C_COMPILER \"${CC_EXE}\")|" \ -e "s|set(CMAKE_CXX_COMPILER \"cl\")|set(CMAKE_CXX_COMPILER \"${CXX_EXE}\")|" \ "${CONAN_TOOLCHAIN}" fi # ============================================================ # 3. CMake configure + Ninja build # ============================================================ echo "[dstalk] CMake configure..." "${CMAKE_EXE}" -S "${ROOT}" -B "${BUILD_DIR}" -G Ninja \ -DCMAKE_MAKE_PROGRAM="${NINJA_EXE}" \ -DCMAKE_C_COMPILER="${CC_EXE}" \ -DCMAKE_CXX_COMPILER="${CXX_EXE}" \ -DCMAKE_TOOLCHAIN_FILE="${CONAN_TOOLCHAIN}" \ -DCMAKE_PREFIX_PATH="${CONAN_PREFIX_PATH}" \ -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \ -DDSTALK_BUILD_GUI=OFF echo "[dstalk] Building..." "${CMAKE_EXE}" --build "${BUILD_DIR}" echo "" echo "============================================" echo " Build succeeded!" echo " ${BUILD_DIR}/bin/dstalk$([ "$(uname)" = 'Darwin' ] && echo '.dylib' || echo '.so')" echo " ${BUILD_DIR}/bin/dstalk_cli" echo "============================================"