clawdforge/clients/cpp/CMakeLists.txt
Kayos 1f6606d3b9 clients/cpp: v0.2 multi-turn Session API
- Session move-only RAII; destructor best-effort close
- Client::create_session / list_sessions / get_session
- TurnResult.text() helper
- All post-parse json::get<T>() wrapped via with_protocol_guard (no nlohmann leak)
- tests/test_session.cpp: ~12 tests covering RAII/idempotency/move/list/state/404/protocol-error/regression
- ASan + UBSan clean
- README "Multi-turn / Sessions (v0.2)" section

v0.1 surface unchanged. C++17 preserved. cpp-httplib 0.20.1 preserved.

Spec: memory/spec-clawdforge-v0.2.md
Server core: 940861f
2026-04-29 07:10:50 -07:00

217 lines
7 KiB
CMake

# SPDX-License-Identifier: MIT
cmake_minimum_required(VERSION 3.20)
project(clawdforge
VERSION 0.1.0
DESCRIPTION "C++ SDK for the clawdforge HTTP API"
LANGUAGES CXX
)
# ---- options ----------------------------------------------------------------
option(CLAWDFORGE_BUILD_TESTS "Build unit tests" ON)
option(CLAWDFORGE_BUILD_EXAMPLES "Build examples" ON)
option(CLAWDFORGE_WARNINGS_AS_ERRORS "Treat warnings as errors" ON)
# When consumed via add_subdirectory, default the extras off unless the user
# explicitly opts in. Top-level builds (the SDK's own CI / dev loop) keep them
# on so we exercise them.
if(NOT CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
set(CLAWDFORGE_BUILD_TESTS OFF)
set(CLAWDFORGE_BUILD_EXAMPLES OFF)
endif()
# ---- standard / flags -------------------------------------------------------
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
set(CMAKE_BUILD_TYPE Release CACHE STRING "" FORCE)
endif()
include(CMakePackageConfigHelpers)
include(GNUInstallDirs)
include(FetchContent)
# ---- dependencies -----------------------------------------------------------
# nlohmann/json — try find_package first, fall back to FetchContent.
find_package(nlohmann_json 3.10 QUIET)
if(NOT nlohmann_json_FOUND)
message(STATUS "clawdforge: nlohmann_json not installed, fetching v3.11.3")
FetchContent_Declare(nlohmann_json
GIT_REPOSITORY https://github.com/nlohmann/json.git
GIT_TAG v3.11.3
GIT_SHALLOW TRUE
)
set(JSON_BuildTests OFF CACHE INTERNAL "")
set(JSON_Install ON CACHE INTERNAL "")
FetchContent_MakeAvailable(nlohmann_json)
endif()
# libcurl — system-installed.
find_package(CURL REQUIRED)
# ---- library target ---------------------------------------------------------
add_library(clawdforge)
add_library(clawdforge::clawdforge ALIAS clawdforge)
target_sources(clawdforge
PRIVATE
src/client.cpp
src/http.cpp
)
target_include_directories(clawdforge
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src
)
target_link_libraries(clawdforge
PUBLIC
nlohmann_json::nlohmann_json
PRIVATE
CURL::libcurl
)
target_compile_features(clawdforge PUBLIC cxx_std_17)
set_target_properties(clawdforge PROPERTIES
CXX_VISIBILITY_PRESET hidden
VISIBILITY_INLINES_HIDDEN ON
POSITION_INDEPENDENT_CODE ON
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}
EXPORT_NAME clawdforge
)
# Warnings -- private so consumers don't inherit our flags.
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
target_compile_options(clawdforge PRIVATE
-Wall -Wextra -Wpedantic
-Wshadow -Wconversion -Wsign-conversion
-Wnon-virtual-dtor -Wold-style-cast
)
if(CLAWDFORGE_WARNINGS_AS_ERRORS)
target_compile_options(clawdforge PRIVATE -Werror)
endif()
elseif(MSVC)
target_compile_options(clawdforge PRIVATE /W4 /permissive-)
if(CLAWDFORGE_WARNINGS_AS_ERRORS)
target_compile_options(clawdforge PRIVATE /WX)
endif()
endif()
# ---- install ----------------------------------------------------------------
install(DIRECTORY include/clawdforge
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
FILES_MATCHING PATTERN "*.hpp"
)
install(TARGETS clawdforge
EXPORT clawdforge-targets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
install(EXPORT clawdforge-targets
FILE clawdforge-targets.cmake
NAMESPACE clawdforge::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/clawdforge
)
configure_package_config_file(
cmake/clawdforge-config.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/clawdforge-config.cmake"
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/clawdforge
)
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/clawdforge-config-version.cmake"
VERSION ${PROJECT_VERSION}
COMPATIBILITY SameMajorVersion
)
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/clawdforge-config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/clawdforge-config-version.cmake"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/clawdforge
)
# ---- examples ---------------------------------------------------------------
if(CLAWDFORGE_BUILD_EXAMPLES)
add_executable(clawdforge_basic_example examples/basic.cpp)
target_link_libraries(clawdforge_basic_example PRIVATE clawdforge::clawdforge)
endif()
# ---- tests ------------------------------------------------------------------
if(CLAWDFORGE_BUILD_TESTS)
enable_testing()
# cpp-httplib for an in-process mock server. Prefer system / installed copy.
# Test-only — never linked into the shipped library. Bumped from 0.15.3 to
# 0.20.1 for clean dep graphs (0.15.x has several published advisories;
# the SDK never exposes the mock to a network).
find_package(httplib QUIET CONFIG)
if(NOT httplib_FOUND)
message(STATUS "clawdforge: cpp-httplib not installed, fetching v0.20.1")
# The mock server doesn't need TLS / compression — disable optional
# backends so we don't drag in zstd / brotli / openssl find_package
# requirements for a test-only dep.
set(HTTPLIB_USE_OPENSSL_IF_AVAILABLE OFF CACHE INTERNAL "")
set(HTTPLIB_USE_ZLIB_IF_AVAILABLE OFF CACHE INTERNAL "")
set(HTTPLIB_USE_BROTLI_IF_AVAILABLE OFF CACHE INTERNAL "")
set(HTTPLIB_USE_ZSTD_IF_AVAILABLE OFF CACHE INTERNAL "")
FetchContent_Declare(cpp_httplib
GIT_REPOSITORY https://github.com/yhirose/cpp-httplib.git
GIT_TAG v0.20.1
GIT_SHALLOW TRUE
)
FetchContent_MakeAvailable(cpp_httplib)
endif()
# doctest — single-header, fastest to compile of the popular options.
find_package(doctest QUIET CONFIG)
if(NOT doctest_FOUND)
message(STATUS "clawdforge: doctest not installed, fetching v2.4.11")
FetchContent_Declare(doctest
GIT_REPOSITORY https://github.com/doctest/doctest.git
GIT_TAG v2.4.11
GIT_SHALLOW TRUE
)
FetchContent_MakeAvailable(doctest)
endif()
add_executable(clawdforge_tests
tests/test_client.cpp
tests/test_session.cpp
)
target_link_libraries(clawdforge_tests
PRIVATE
clawdforge::clawdforge
httplib::httplib
doctest::doctest
)
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
target_compile_options(clawdforge_tests PRIVATE
-Wall -Wextra
# Designated initializers in C++20 don't need to set every member.
-Wno-missing-field-initializers
# CHECK_THROWS_AS expands to a discarded-value expression; the
# `[[nodiscard]]` on Client methods makes that legitimately noisy.
-Wno-unused-result
)
endif()
add_test(NAME clawdforge_tests COMMAND clawdforge_tests)
endif()