# Smartbotic Database Service # Find OpenSSL for encryption find_package(OpenSSL REQUIRED) # PkgConfig is REQUIRED because yyjson (v1.10+) is a hard build dependency. # LZ4 and jemalloc remain optional, but if pkg-config itself is missing we # fail at configure time rather than silently producing a yyjson-free binary # via empty ${yyjson_LIBRARIES} expansion. find_package(PkgConfig REQUIRED) # yyjson — phase A v1.10 hot-path JSON parser. Hard dependency. pkg_check_modules(yyjson REQUIRED yyjson) # Optional LZ4 for compression pkg_check_modules(LZ4 QUIET liblz4) # v1.9.4 — jemalloc replaces glibc malloc for the smartbotic-database # binary. The fragmentation pattern from per-RPC nlohmann::json node # churn (107k 33-byte allocations observed on Zoe) defeats glibc's # malloc_trim because the trailing region of each arena always has a # live chunk; jemalloc's background-thread dirty-page decay sidesteps # the contiguity requirement and reclaims unused pages on a wallclock # timer regardless of allocation activity. Linked as a library so # the binary picks up jemalloc's malloc/free symbols at link time; # no LD_PRELOAD needed. pkg_check_modules(JEMALLOC QUIET jemalloc) # LMDB — v2.0 storage substrate. liblmdb does not ship a pkg-config file on # Debian 13 (`pkg-config --modversion lmdb` fails), so resolve via find_path / # find_library. Hard dependency. find_path(LMDB_INCLUDE_DIR lmdb.h) find_library(LMDB_LIBRARY NAMES lmdb) if(NOT LMDB_INCLUDE_DIR OR NOT LMDB_LIBRARY) message(FATAL_ERROR "LMDB not found. Install liblmdb-dev.") endif() # Source files set(DATABASE_SERVICE_SOURCES src/main.cpp src/database_service.cpp src/database_grpc_impl.cpp src/doc_binary.cpp src/json_parse.cpp src/memory_store.cpp src/persistence/persistence_manager.cpp src/persistence/wal.cpp src/persistence/snapshot.cpp src/persistence/history_store.cpp src/encryption/encryption_manager.cpp src/events/event_manager.cpp src/files/file_manager.cpp src/files/file_store.cpp src/replication/replication_manager.cpp src/replication/sync_protocol.cpp src/replication/conflict_resolver.cpp src/migrations/migration_runner.cpp src/views/projection.cpp src/views/view_manager.cpp src/config/collection_config_manager.cpp src/config/config_loader.cpp src/storage/lmdb_env.cpp ) # Create executable add_executable(smartbotic-database ${DATABASE_SERVICE_SOURCES}) target_include_directories(smartbotic-database PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src ) # Link dependencies if(BUILD_SHARED_LIBS) target_link_libraries(smartbotic-database PRIVATE smartbotic-db-client) else() target_link_libraries(smartbotic-database PRIVATE smartbotic_db_proto) endif() target_link_libraries(smartbotic-database PRIVATE OpenSSL::SSL OpenSSL::Crypto ) if(TARGET nlohmann_json::nlohmann_json) target_link_libraries(smartbotic-database PRIVATE nlohmann_json::nlohmann_json) else() target_include_directories(smartbotic-database PRIVATE ${NLOHMANN_JSON_INCLUDE_DIRS}) endif() if(TARGET spdlog::spdlog) target_link_libraries(smartbotic-database PRIVATE spdlog::spdlog) else() target_link_libraries(smartbotic-database PRIVATE ${SPDLOG_LIBRARIES}) target_include_directories(smartbotic-database PRIVATE ${SPDLOG_INCLUDE_DIRS}) endif() # LZ4 compression support if(LZ4_FOUND) target_compile_definitions(smartbotic-database PRIVATE HAVE_LZ4) target_link_libraries(smartbotic-database PRIVATE ${LZ4_LIBRARIES}) target_include_directories(smartbotic-database PRIVATE ${LZ4_INCLUDE_DIRS}) endif() # yyjson — phase A v1.10 hot-path JSON parser target_link_libraries(smartbotic-database PRIVATE ${yyjson_LIBRARIES}) target_include_directories(smartbotic-database PRIVATE ${yyjson_INCLUDE_DIRS}) # LMDB — v2.0 storage substrate target_link_libraries(smartbotic-database PRIVATE ${LMDB_LIBRARY}) target_include_directories(smartbotic-database PRIVATE ${LMDB_INCLUDE_DIR}) # v1.9.4 — jemalloc allocator (overrides glibc malloc/free) if(JEMALLOC_FOUND) target_compile_definitions(smartbotic-database PRIVATE HAVE_JEMALLOC) target_link_libraries(smartbotic-database PRIVATE ${JEMALLOC_LIBRARIES}) target_include_directories(smartbotic-database PRIVATE ${JEMALLOC_INCLUDE_DIRS}) # Position-sensitive: jemalloc must be linked early so its symbols win # over libc's. -Wl,-no-as-needed forces the linker to record the # dependency even though we don't reference any jemalloc symbol # directly (we just want its malloc to override). target_link_options(smartbotic-database PRIVATE -Wl,-no-as-needed) message(STATUS "Linking with jemalloc (${JEMALLOC_VERSION})") else() message(STATUS "jemalloc not found — falling back to glibc malloc (degraded RSS reclaim under load)") endif() # Systemd support if(SYSTEMD_FOUND) target_compile_definitions(smartbotic-database PRIVATE HAVE_SYSTEMD) target_link_libraries(smartbotic-database PRIVATE ${SYSTEMD_LIBRARIES}) target_include_directories(smartbotic-database PRIVATE ${SYSTEMD_INCLUDE_DIRS}) endif() # Installation install(TARGETS smartbotic-database RUNTIME DESTINATION bin )