| 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 "") |
|
|