# Building from Source

This page covers compiling the workspace, running the test suite, and understanding the build-time Cap'n Proto code generation step.

---

## Building the workspace

From the repository root:

```bash
cargo build --workspace
```

This compiles all four crates:

| Crate | Type | Purpose |
|---|---|---|
| `quicproquo-core` | library | Crypto primitives, MLS `GroupMember` state machine, hybrid KEM |
| `quicproquo-proto` | library | Cap'n Proto schemas, generated types, envelope serialisation helpers |
| `quicproquo-server` | binary | Unified Authentication + Delivery Service (`NodeService`) |
| `quicproquo-client` | binary | CLI client with subcommands (`ping`, `register`, `send`, `recv`, etc.) |

For a release build with LTO, symbol stripping, and single codegen unit:

```bash
cargo build --workspace --release
```

The release profile is configured in the workspace `Cargo.toml`:

```toml
[profile.release]
opt-level     = 3
lto           = "thin"
codegen-units = 1
strip         = "symbols"
```

---

## Running the test suite

```bash
cargo test --workspace
```

The test suite includes:

- **`quicproquo-proto`**: Round-trip serialisation tests for Cap'n Proto `Envelope` messages (Ping, Pong, corrupted-input error handling).
- **`quicproquo-core`**: Two-party MLS round-trip (`create_group` / `add_member` / `send_message` / `receive_message`), group ID lifecycle assertions.
- **`quicproquo-client`**: Integration tests for MLS group operations and auth service interactions (require a running server or use in-process mocks).

To run tests for a single crate:

```bash
cargo test -p quicproquo-core
```

---

## Cap'n Proto code generation

The `quicproquo-proto` crate does not contain hand-written Rust types for wire messages. Instead, its `build.rs` script invokes the `capnp` compiler at build time to generate Rust source from the `.capnp` schema files.

### How it works

1. `build.rs` locates the workspace-root `schemas/` directory (two levels above `crates/quicproquo-proto/`).
2. It invokes `capnpc::CompilerCommand` on all four schema files:
   - `schemas/envelope.capnp` -- top-level wire envelope with `MsgType` discriminant
   - `schemas/auth.capnp` -- `AuthenticationService` RPC interface
   - `schemas/delivery.capnp` -- `DeliveryService` RPC interface
   - `schemas/node.capnp` -- `NodeService` RPC interface (unified AS + DS)
3. The generated Rust source is written to `$OUT_DIR` (Cargo's build output directory).
4. `src/lib.rs` includes the generated code via `include!(concat!(env!("OUT_DIR"), "/envelope_capnp.rs"))` and similar macros for each schema.

### Rebuild triggers

The `build.rs` script emits `cargo:rerun-if-changed` directives for each schema file. If you modify a `.capnp` file, the next `cargo build` will automatically re-run code generation.

### Schema include path

The `src_prefix` is set to the `schemas/` directory so that inter-schema imports (e.g., `using Auth = import "auth.capnp".Auth;` inside `node.capnp`) resolve correctly.

### Design constraints of quicproquo-proto

The proto crate is intentionally restricted:

- **No crypto** -- key material never enters this crate.
- **No I/O** -- callers own the transport; this crate only converts bytes to types and back.
- **No async** -- pure synchronous data-layer code.

For details on the wire format, see the [Wire Format Reference](../wire-format/overview.md).

---

## Troubleshooting

### `capnp` binary not found

**Symptom:**

```
Cap'n Proto schema compilation failed.
Is `capnp` installed? (apt-get install capnproto / brew install capnp)
```

**Fix:** Install the Cap'n Proto compiler for your platform. See [Prerequisites](prerequisites.md) for platform-specific instructions.

Verify it is on your `PATH`:

```bash
which capnp
capnp --version
```

### Version mismatch between `capnp` CLI and `capnpc` Rust crate

The workspace uses `capnpc = "0.19"` (the Rust bindings for the Cap'n Proto compiler). If your system `capnp` binary is significantly older or newer, generated code may be incompatible. The recommended approach is to use a `capnp` binary whose major version matches the `capnpc` crate version. On most systems, the package manager version is compatible.

### linker errors on macOS with Apple Silicon

If you see linker errors related to `ring` or `aws-lc-sys` (used transitively by `rustls`), ensure you have Xcode Command Line Tools installed:

```bash
xcode-select --install
```

### Slow first build

The first build downloads and compiles all dependencies (including `openmls`, `quinn`, `rustls`, `capnp-rpc`, etc.). This can take several minutes depending on your hardware. Subsequent builds are incremental and much faster.

---

## Next steps

- [Running the Server](running-the-server.md) -- start the NodeService endpoint
- [Running the Client](running-the-client.md) -- CLI subcommands and usage examples
- [Docker Deployment](docker.md) -- build and run in containers
