cmake_minimum_required(VERSION 3.16) project(bexcli LANGUAGES C CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) # ── Build Options ─────────────────────────────────────────────────────── # Fully static linking is NOT safe as a default for arbitrary apps/platforms. # glibc, Wasmtime, TLS stacks, and system libraries can make static builds # brittle or impossible depending on the target. Keep it opt-in. option(BEX_FORCE_STATIC_EXE "Force fully static bexcli executable on Unix" OFF) # ── Build Configuration ────────────────────────────────────────────────── if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release) endif() # ── Release Optimization Flags ──────────────────────────────────────────── if(CMAKE_BUILD_TYPE STREQUAL "Release") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ffunction-sections -fdata-sections -Os") if(NOT WIN32) set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} -Wl,--gc-sections") endif() endif() # ── Bex Engine Integration ─────────────────────────────────────────────── # Reusable CMake integration for any C/C++ app. # # Requirements: # 1. Build Rust library first: cargo build -p bex-runtime --release # 2. Set BEX_ENGINE_ROOT if cpp-cli/ is copied outside the repo. # # The Rust library exports a pure C ABI via bex_engine.h — no cxx bridge. if(NOT BEX_ENGINE_ROOT) get_filename_component(_BEX_ROOT "${CMAKE_SOURCE_DIR}/.." ABSOLUTE) if(EXISTS "${_BEX_ROOT}/Cargo.toml") set(BEX_ENGINE_ROOT "${_BEX_ROOT}") else() message(FATAL_ERROR "Cannot find Bex Engine root. Set -DBEX_ENGINE_ROOT=/path/to/bex-engine\n" "The bex-engine directory should contain Cargo.toml and crates/." ) endif() endif() message(STATUS "Bex Engine root: ${BEX_ENGINE_ROOT}") if(CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo" OR CMAKE_BUILD_TYPE STREQUAL "MinSizeRel") set(RUST_PROFILE "release") else() set(RUST_PROFILE "debug") endif() set(RUST_TARGET_DIR "${BEX_ENGINE_ROOT}/target/${RUST_PROFILE}") # ── Detect Rust library name ──────────────────────────────────────────── if(WIN32) set(RUST_STATIC_LIB "${RUST_TARGET_DIR}/bex_runtime.lib") set(RUST_SHARED_LIB "${RUST_TARGET_DIR}/bex_runtime.dll") elseif(APPLE) set(RUST_STATIC_LIB "${RUST_TARGET_DIR}/libbex_runtime.a") set(RUST_SHARED_LIB "${RUST_TARGET_DIR}/libbex_runtime.dylib") else() set(RUST_STATIC_LIB "${RUST_TARGET_DIR}/libbex_runtime.a") set(RUST_SHARED_LIB "${RUST_TARGET_DIR}/libbex_runtime.so") endif() # Prefer static Rust archive when present, but do not force a fully static executable. if(EXISTS "${RUST_STATIC_LIB}") set(BEX_LINK_MODE "static-rustlib") set(BEX_LIB_PATH "${RUST_STATIC_LIB}") message(STATUS "Found Rust static library: ${BEX_LIB_PATH}") elseif(EXISTS "${RUST_SHARED_LIB}") set(BEX_LINK_MODE "shared-rustlib") set(BEX_LIB_PATH "${RUST_SHARED_LIB}") message(STATUS "Found Rust shared library: ${BEX_LIB_PATH}") else() message(WARNING "Rust library not found at ${RUST_STATIC_LIB} or ${RUST_SHARED_LIB}\n" "Build it first: cd ${BEX_ENGINE_ROOT} && cargo build -p bex-runtime --release" ) set(BEX_LINK_MODE "static-rustlib") set(BEX_LIB_PATH "${RUST_STATIC_LIB}") endif() # ── C Header Location ─────────────────────────────────────────────────── set(BEX_INCLUDE_DIR "${CMAKE_SOURCE_DIR}") add_library(bex_engine_lib INTERFACE) add_library(bex::engine ALIAS bex_engine_lib) target_include_directories(bex_engine_lib INTERFACE "${BEX_INCLUDE_DIR}") target_link_libraries(bex_engine_lib INTERFACE "${BEX_LIB_PATH}") if(WIN32) target_link_libraries(bex_engine_lib INTERFACE bcrypt userenv ntdll advapi32 ws2_32 user32) elseif(APPLE) target_link_libraries(bex_engine_lib INTERFACE "-framework Security" "-framework CoreFoundation" pthread m ) else() target_link_libraries(bex_engine_lib INTERFACE dl pthread m) target_link_directories(bex_engine_lib INTERFACE "${RUST_TARGET_DIR}/deps") endif() add_executable(bexcli bexcli.cpp) target_include_directories(bexcli PRIVATE "${BEX_INCLUDE_DIR}") target_link_libraries(bexcli PRIVATE bex_engine_lib) # Optional fully-static Unix executable for environments that explicitly want it. if(BEX_FORCE_STATIC_EXE AND NOT WIN32 AND NOT APPLE) target_link_options(bexcli PRIVATE -static) endif() add_custom_target(rustlib COMMAND ${CMAKE_COMMAND} -E env cargo build -p bex-runtime --release WORKING_DIRECTORY ${BEX_ENGINE_ROOT} COMMENT "Building Rust bex-runtime library (pure C ABI)..." VERBATIM ) if(NOT EXISTS "${BEX_LIB_PATH}") add_dependencies(bexcli rustlib) endif() install(TARGETS bexcli RUNTIME DESTINATION bin) install(FILES "${CMAKE_SOURCE_DIR}/bex_engine.h" DESTINATION include/bex) message(STATUS "") message(STATUS "=== Bex CLI Configuration (Pure C ABI) ===") message(STATUS " Build type: ${CMAKE_BUILD_TYPE}") message(STATUS " Rust profile: ${RUST_PROFILE}") message(STATUS " Engine root: ${BEX_ENGINE_ROOT}") message(STATUS " Rust target dir: ${RUST_TARGET_DIR}") message(STATUS " Link mode: ${BEX_LINK_MODE}") message(STATUS " Library path: ${BEX_LIB_PATH}") message(STATUS " Include dir: ${BEX_INCLUDE_DIR}") message(STATUS " Force static exe: ${BEX_FORCE_STATIC_EXE}") message(STATUS " FFI: Pure C ABI (bex_engine.h)") message(STATUS "==========================================") message(STATUS "")