Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
171 changes: 171 additions & 0 deletions book/src/build/cmake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
# Build with CMake

`a2a-cpp` is a C++20 SDK built and packaged with CMake. The project can be used directly from source with `FetchContent`, installed into a CMake package prefix, or built with dependencies supplied by vcpkg.

## Requirements

- CMake 3.25 or newer.
- A C++20 compiler.
- Protobuf and gRPC development packages.
- Optional: libcurl for the default buffered outbound HTTP implementation.
- Optional: PostgreSQL client libraries when `A2A_ENABLE_POSTGRES_STORE=ON`.

On Ubuntu-like systems, the repository helper installs the dependencies used by CI:

```bash
./scripts/install_build_deps.sh
```

On macOS, install equivalent packages with Homebrew:

```bash
brew install cmake ninja protobuf grpc re2 abseil curl
```

## Configure from source

The default source build enables tests, keeps the curated example apps out of the top-level build, and enables libcurl-backed HTTP support when CMake can find `CURL::libcurl`.

```bash
cmake -S . -B build \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
-DA2A_ENABLE_TESTING=ON
```

When dependencies are installed outside standard search paths, pass a CMake prefix path:

```bash
cmake -S . -B build \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DCMAKE_PREFIX_PATH="/opt/homebrew;/opt/homebrew/opt/curl"
```

## Build and test

```bash
cmake --build build --parallel
ctest --test-dir build --output-on-failure
```

For the repository's full local code validation flow, run:

```bash
./scripts/verify_changes.sh
```

That script runs the same main gates expected before a code PR: formatting, configure/build, tests, and clang-tidy.

## CMake options

| Option | Default | Description |
| --- | --- | --- |
| `A2A_ENABLE_TESTING` | `ON` | Builds unit and integration tests and enables CTest. |
| `A2A_BUILD_EXAMPLES` | `ON` | Compatibility/message-only option for the root build today; curated examples are built as standalone consumers from `examples/fetch_content_consumer` or `examples/installed_package_consumer`. |
| `A2A_BUILD_BENCHMARKS` | `OFF` | Builds benchmark targets under `benchmarks/`. |
| `A2A_ENABLE_LIBCURL` | `ON` | Enables the default libcurl-backed outbound HTTP implementation when libcurl is found. Disable it to require injected requesters/fetchers. |
| `A2A_ENABLE_POSTGRES_STORE` | `OFF` | Builds PostgreSQL-backed store targets when PostgreSQL dependencies are available. |

## Generated protobuf headers

The SDK generates A2A protocol C++ sources during the build. Primary generated A2A headers are written under `build/generated/a2a/v1/`, and generated Google API annotation headers are written under `build/generated/google/api/`.

Those generated headers are installed with the SDK, so downstream projects should include headers from the installed package rather than copying build-tree generated files.

## Install as a CMake package

Install the SDK to a prefix:

```bash
cmake --install build --prefix /tmp/a2a-cpp-install
```

The install tree includes public headers, generated protobuf headers, libraries, and package configuration files under `lib/cmake/a2a_cpp`.

A downstream project can then consume the installed package:

```cmake
cmake_minimum_required(VERSION 3.25)
project(my_a2a_app LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

find_package(a2a_cpp CONFIG REQUIRED)

add_executable(my_a2a_app main.cpp)
target_link_libraries(my_a2a_app PRIVATE a2a::client a2a::server a2a::core)
```

Configure that downstream project with `CMAKE_PREFIX_PATH` pointing at the install prefix:

```bash
cmake -S path/to/app -B build-app \
-DCMAKE_PREFIX_PATH=/tmp/a2a-cpp-install
cmake --build build-app --parallel
```

## FetchContent consumer

For application projects that prefer source integration, use CMake `FetchContent` and pin `GIT_TAG` to a release tag or reviewed commit:

```cmake
include(FetchContent)

set(A2A_ENABLE_TESTING OFF CACHE BOOL "" FORCE)
set(A2A_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
set(A2A_BUILD_BENCHMARKS OFF CACHE BOOL "" FORCE)
set(A2A_ENABLE_POSTGRES_STORE OFF CACHE BOOL "" FORCE)

FetchContent_Declare(
a2a_cpp
GIT_REPOSITORY https://github.com/MisterVVP/a2a-cpp.git
GIT_TAG v0.2.0
)
FetchContent_MakeAvailable(a2a_cpp)

target_link_libraries(my_a2a_app PRIVATE a2a::client a2a::server a2a::core)
```

See `examples/fetch_content_consumer/` for a minimal runnable consumer.

## Exported targets

Common exported targets include:

- `a2a::core` for shared core types and utilities.
- `a2a::client` for client APIs.
- `a2a::server` for server APIs.
- `a2a::http` for HTTP support internals used by higher-level targets.
- `a2a::proto_generated` for generated protobuf bindings.
- `a2a::store_postgres` when PostgreSQL store support is enabled.

Most applications should link the smallest set they use. The examples link `a2a::client`, `a2a::server`, and `a2a::core` for a combined client/server sample.

## Build the curated examples

Use the FetchContent example when testing source consumption:

```bash
cmake -S examples/fetch_content_consumer -B build-example \
-DA2A_EXAMPLE_APP=hello_agent
cmake --build build-example --parallel
./build-example/a2a_example
```

Use the installed-package example when testing package consumption:

```bash
cmake -S examples/installed_package_consumer -B build-installed-example \
-DCMAKE_PREFIX_PATH=/tmp/a2a-cpp-install \
-DA2A_EXAMPLE_APP=hello_agent
cmake --build build-installed-example --parallel
./build-installed-example/a2a_example
```

## Platform notes

- Linux CI configures with CMake and validates build, tests, examples, clang-format, clang-tidy, coverage, and selected sanitizer/interop flows.
- macOS CI builds with Homebrew-provided dependencies and Ninja.
- Windows CI uses vcpkg manifest dependencies and the Visual Studio 2022 generator. See [vcpkg](vcpkg.md) for manifest, triplet, and overlay details.
184 changes: 184 additions & 0 deletions book/src/build/vcpkg.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
# Build with vcpkg

`a2a-cpp` provides vcpkg metadata for two related workflows:

1. **Manifest dependency mode** for building this repository with vcpkg-supplied third-party dependencies.
2. **Overlay port mode** for consuming `a2a-cpp` itself as a vcpkg package before it is available from a public registry.

The repository root `vcpkg.json` pins the dependency baseline and declares the SDK's third-party dependencies: protobuf, gRPC, and curl.

## Prerequisites

Install or clone vcpkg and bootstrap it:

```bash
git clone https://github.com/microsoft/vcpkg.git "$HOME/vcpkg"
"$HOME/vcpkg/bootstrap-vcpkg.sh"
```

On Windows PowerShell:

```powershell
git clone https://github.com/microsoft/vcpkg.git C:\vcpkg
C:\vcpkg\bootstrap-vcpkg.bat
```

Set `VCPKG_ROOT` for convenience:

```bash
export VCPKG_ROOT="$HOME/vcpkg"
```

```powershell
$env:VCPKG_ROOT = 'C:\vcpkg'
```

## Build this repository with manifest dependencies

From the repository root, let vcpkg install the manifest dependencies and then configure CMake with the vcpkg toolchain file:

```bash
"$VCPKG_ROOT/vcpkg" install
cmake -S . -B build-vcpkg \
-DVCPKG_MANIFEST_MODE=ON \
-DCMAKE_TOOLCHAIN_FILE="$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DA2A_ENABLE_TESTING=ON
cmake --build build-vcpkg --parallel
ctest --test-dir build-vcpkg --output-on-failure
```

On multi-config generators such as Visual Studio, pass the configuration during build and test:

```powershell
& "$env:VCPKG_ROOT\vcpkg.exe" install
cmake -S . -B build-vcpkg -G "Visual Studio 17 2022" -A x64 `
-DVCPKG_MANIFEST_MODE=ON `
-DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_ROOT\scripts\buildsystems\vcpkg.cmake"
cmake --build build-vcpkg --config RelWithDebInfo --parallel
ctest --test-dir build-vcpkg -C RelWithDebInfo --output-on-failure
```

## Use a specific triplet

Pass the same target triplet to vcpkg and CMake. For native builds, use the same value for the host triplet so host tools such as `protoc` and `grpc_cpp_plugin` are resolved consistently:

```bash
"$VCPKG_ROOT/vcpkg" install --triplet x64-linux --host-triplet x64-linux
cmake -S . -B build-vcpkg \
-DCMAKE_TOOLCHAIN_FILE="$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" \
-DVCPKG_TARGET_TRIPLET=x64-linux \
-DVCPKG_HOST_TRIPLET=x64-linux
```

Windows CI uses the repository triplet `triplets/ci-x64-windows-release.cmake` to build release-only dependencies and reduce dependency build time:

```powershell
$env:VCPKG_OVERLAY_TRIPLETS = "$PWD\triplets"
& "$env:VCPKG_ROOT\vcpkg.exe" install --triplet ci-x64-windows-release --host-triplet ci-x64-windows-release
cmake -S . -B build -G "Visual Studio 17 2022" -A x64 `
-DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_ROOT\scripts\buildsystems\vcpkg.cmake" `
-DVCPKG_TARGET_TRIPLET=ci-x64-windows-release `
-DVCPKG_HOST_TRIPLET=ci-x64-windows-release
```

## Consume `a2a-cpp` through the repository overlay port

The repository includes an overlay port at `vcpkg-overlay-ports/a2a-cpp`. A downstream manifest can depend on `a2a-cpp` and point vcpkg at that overlay.

`vcpkg.json`:

```json
{
"name": "my-a2a-app",
"version-string": "0.2.0",
"dependencies": [
"a2a-cpp"
]
}
```

`vcpkg-configuration.json`:

```json
{
"default-registry": {
"kind": "builtin",
"baseline": "3426db05b996481ca31e95fff3734cf23e0f51bc"
},
"overlay-ports": [
"path/to/a2a-cpp/vcpkg-overlay-ports"
]
}
```

Then configure the application with the vcpkg toolchain file on the first CMake configure and use the installed CMake package:

```cmake
find_package(a2a_cpp CONFIG REQUIRED)
target_link_libraries(my_a2a_app PRIVATE a2a::client a2a::server a2a::core)
```

A complete example is available in `examples/installed_package_consumer/`.

## Enable PostgreSQL store support

The overlay port exposes a `postgres-store` feature. Enable it in manifest mode when your application needs PostgreSQL-backed stores:

```json
{
"name": "my-a2a-app",
"version-string": "0.2.0",
"dependencies": [
{
"name": "a2a-cpp",
"features": ["postgres-store"]
}
]
}
```

When the feature is enabled, link the additional target where needed:

```cmake
target_link_libraries(my_a2a_app PRIVATE a2a::store_postgres)
```

## Classic mode smoke install

For a direct overlay smoke test, run classic mode from a directory that does not contain a `vcpkg.json` manifest:

```bash
mkdir -p /tmp/a2a-vcpkg-smoke
cd /tmp/a2a-vcpkg-smoke
"$VCPKG_ROOT/vcpkg" install a2a-cpp --overlay-ports=/path/to/a2a-cpp/vcpkg-overlay-ports
```

Add a triplet if needed:

```bash
"$VCPKG_ROOT/vcpkg" install a2a-cpp:x64-linux --overlay-ports=/path/to/a2a-cpp/vcpkg-overlay-ports
```

## Binary caching

Large dependencies such as gRPC and protobuf can take time to build. Enable binary caching for local and CI runs:

```bash
export VCPKG_BINARY_SOURCES="clear;files,$HOME/.cache/vcpkg-binary-cache,readwrite"
mkdir -p "$HOME/.cache/vcpkg-binary-cache"
```

On Windows PowerShell:

```powershell
$env:VCPKG_BINARY_SOURCES = 'clear;files,C:\vcpkg-binary-cache,readwrite'
New-Item -ItemType Directory -Force C:\vcpkg-binary-cache | Out-Null
```

## Troubleshooting

- **CMake cannot find gRPC or Protobuf**: confirm `CMAKE_TOOLCHAIN_FILE` points to `scripts/buildsystems/vcpkg.cmake` before the first configure. If you configured without it, delete the build directory and configure again.
- **Unexpected manifest behavior in classic mode**: classic `vcpkg install a2a-cpp` should be run outside directories containing `vcpkg.json`, otherwise vcpkg switches to manifest mode.
- **Different host and target triplets**: pass both `VCPKG_TARGET_TRIPLET` and `VCPKG_HOST_TRIPLET` when cross-compiling or when CI uses a custom host triplet.
- **Slow clean builds**: enable binary caching and prefer release-only dependency triplets for CI jobs that only link release configurations.
Loading