docs: add build/manual-testing guide, fix stale M0 stub claims in headers
- docs/building.md: explains what each CMake preset (dev, m1-dev, m2-dev,
server-release) is actually for, and how to build voicecat-server + vccli
for manual testing. Linked from CLAUDE.md's doc index.
- core/include/voicecat.h, core/src/voicecat.cpp, core/src/protocol/protocol.h,
server/src/main.cpp: doc-header comments still claimed M0-skeleton/stub
behavior (VC_ERR_NOT_IMPLEMENTED everywhere, "prints what it would do",
protobuf codegen "commented") that M1-M3 made real. Updated to describe
current behavior, with the dev-preset stub fallback noted explicitly where
it still applies.
2026-06-16 16:30:07 +02:00
# Building & Manual Testing
This doc explains what each CMake preset in [`CMakePresets.json` ](../CMakePresets.json ) is
*for*, which one to actually use day-to-day, and the commands to stand up a real server +
`vccli` clients against each other for manual testing. For the one-paragraph quick-start see
[`CLAUDE.md` ](../CLAUDE.md ); for `ctest` targets see [`AGENTS.md` ](../AGENTS.md ). This doc is
build(cmake): clean up presets, add release/apple presets, cross-platform triplets
Rationalize the preset set to match the project's actual state (past M5):
- Rename dev->skeleton (no-deps stub smoke), m1-dev->dev (default dev preset)
- Drop m2-dev (cache-identical to m1-dev)
- Add release preset (optimized + tests on, symbols kept)
- Strip server-release binaries (-s linker flag)
- Add apple-dev/apple-ios/apple-ios-sim scaffolding presets for XCFramework
Add cmake/voicecat-toolchain.cmake wrapper that auto-resolves the vcpkg
triplet from the host platform (x64-mingw-static/x64-linux/arm64-osx) so
the main presets work on Windows/Linux/macOS without per-OS variants.
Update all docs (building.md, CLAUDE.md, README.md, AGENTS.md, deployment.md,
tech-stack.md, client READMEs) and stale preset-name references in code
comments. No C++ behavior changes — the core was already portable.
2026-06-18 03:16:01 +02:00
the missing middle: *how the presets relate to each other* , *which platform each targets* ,
and *how to drive the binaries by hand* .
docs: add build/manual-testing guide, fix stale M0 stub claims in headers
- docs/building.md: explains what each CMake preset (dev, m1-dev, m2-dev,
server-release) is actually for, and how to build voicecat-server + vccli
for manual testing. Linked from CLAUDE.md's doc index.
- core/include/voicecat.h, core/src/voicecat.cpp, core/src/protocol/protocol.h,
server/src/main.cpp: doc-header comments still claimed M0-skeleton/stub
behavior (VC_ERR_NOT_IMPLEMENTED everywhere, "prints what it would do",
protobuf codegen "commented") that M1-M3 made real. Updated to describe
current behavior, with the dev-preset stub fallback noted explicitly where
it still applies.
2026-06-16 16:30:07 +02:00
2026-06-18 17:36:47 +02:00
**Quick navigation:**
| What you want to build | Section | Key command |
|------------------------|---------|-------------|
| Server + `vccli` + tests (all platforms) | [§3 ](#3-build--test-the-loop-youll-run-constantly ) | `cmake --preset dev && cmake --build --preset dev && ctest --preset dev` |
| Production server (stripped, no tests) | [§5 ](#5-server-release-production-shaped-build ) | `cmake --preset server-release && cmake --build --preset server-release` |
| Windows client (C# / WinForms) | [§7 ](#7-windows-client-c--winforms ) | `dotnet build clients/windows/VoiceCat.slnx` |
2026-06-19 02:19:38 +02:00
| macOS client (AppKit) | [§8 ](#8-macos-client-appkit ) | `scripts/build-macos-client.sh` |
| iOS client (SwiftUI / simulator) | [§9 ](#9-ios-client-swiftui ) | `scripts/build-ios-client.sh` |
| Launch iOS app on simulator | [§9 ](#9-ios-client-swiftui ) | `scripts/run-ios-simulator.sh` |
2026-06-18 17:36:47 +02:00
| Swift core + tests | [§8 ](#8-macos-client-appkit ) | `cd clients/apple && swift test` |
docs: add build/manual-testing guide, fix stale M0 stub claims in headers
- docs/building.md: explains what each CMake preset (dev, m1-dev, m2-dev,
server-release) is actually for, and how to build voicecat-server + vccli
for manual testing. Linked from CLAUDE.md's doc index.
- core/include/voicecat.h, core/src/voicecat.cpp, core/src/protocol/protocol.h,
server/src/main.cpp: doc-header comments still claimed M0-skeleton/stub
behavior (VC_ERR_NOT_IMPLEMENTED everywhere, "prints what it would do",
protobuf codegen "commented") that M1-M3 made real. Updated to describe
current behavior, with the dev-preset stub fallback noted explicitly where
it still applies.
2026-06-16 16:30:07 +02:00
## 1. What each preset is for
build(cmake): clean up presets, add release/apple presets, cross-platform triplets
Rationalize the preset set to match the project's actual state (past M5):
- Rename dev->skeleton (no-deps stub smoke), m1-dev->dev (default dev preset)
- Drop m2-dev (cache-identical to m1-dev)
- Add release preset (optimized + tests on, symbols kept)
- Strip server-release binaries (-s linker flag)
- Add apple-dev/apple-ios/apple-ios-sim scaffolding presets for XCFramework
Add cmake/voicecat-toolchain.cmake wrapper that auto-resolves the vcpkg
triplet from the host platform (x64-mingw-static/x64-linux/arm64-osx) so
the main presets work on Windows/Linux/macOS without per-OS variants.
Update all docs (building.md, CLAUDE.md, README.md, AGENTS.md, deployment.md,
tech-stack.md, client READMEs) and stale preset-name references in code
comments. No C++ behavior changes — the core was already portable.
2026-06-18 03:16:01 +02:00
| Preset | Binary dir | Deps | Build type | Server | Tools | Tests | Strip | Platform | What it's for |
|--------|-----------|------|------------|--------|-------|-------|-------|----------|---------------|
| `vcpkg-common` | — | vcpkg | — | — | — | — | — | all | Hidden base. Sets the vcpkg toolchain wrapper ([`cmake/voicecat-toolchain.cmake` ](../cmake/voicecat-toolchain.cmake )) which auto-resolves the triplet from the host platform. Not used directly. |
| `skeleton` | `build/skeleton` | none | Debug | ON | ON | ON | no | all | The M0 skeleton. Compiles with just a C++20 compiler — no `VCPKG_ROOT` needed. Subsystems are stubs (`VC_ERR_NOT_IMPLEMENTED` ). Good for "does the repo even build" sanity checks. Runs 2 tests (smoke + frame_codec). |
| `dev` | `build/dev` | vcpkg | Debug | ON | ON | ON | no | all | **The one you actually want.** Day-to-day development: real protocol, crypto, voice, server — everything. Builds server + tools + tests (21 tests). Works on Windows, Linux, and macOS (triplet auto-resolved). |
| `release` | `build/release` | vcpkg | Release | ON | ON | ON | no | all | Optimized build with the full test suite. Use to run tests against optimized code, profile, or catch optimizer-sensitive bugs. Symbols kept (not stripped) so stack traces and profiling remain useful. |
| `server-release` | `build/server-release` | vcpkg | Release | ON | ON | OFF | **yes** | all | Production-shaped build for deployment. Optimized + stripped binaries (`-s` ), no tests. This is what you'd ship/run — see [docs/deployment.md ](deployment.md ). |
| `windows-client` | `build/windows-client` | vcpkg | Release | OFF | OFF | OFF | no | Windows | Produces a redistributable `voicecat.dll` for the C# WinForms client (M4). Static MinGW runtime — no `libgcc_s_seh-1.dll` etc. See [clients/windows/README.md ](../clients/windows/README.md ). |
feat(macos): validate dev + apple-dev presets on macOS, fix 3 cross-platform bugs
macOS port groundwork — core, server, tools, and tests now build and run on
macOS 26.5 / Apple Silicon. ctest --preset dev green 21/21 (2 consecutive runs).
apple-dev produces valid arm64 libvoicecat.a + XCFramework for the Swift Package.
Three real cross-platform bugs found and fixed (all latent on Windows/Linux):
1. test_m2_voice.cpp POSIX branch missing <netdb.h> — Linux glibc transitively
includes it, macOS doesn't. Would fail on any strict POSIX system.
2. SIGPIPE killing processes on macOS — writing to a closed TCP socket raises
SIGPIPE by default (doesn't exist on Windows, benign on Linux). Fixed by
ignoring SIGPIPE in both core client init and server startup (POSIX-only,
#ifndef _WIN32). Production fix, not just tests.
3. Use-after-free of Asio's kqueue reactor on server shutdown — the
deterministic test_tofu_flow segfault. TcpServerConn's tls_read_loop runs on
a blocking-I/O thread; when Server::run() returned, io_context was destroyed
while those threads were still running. On macOS kqueue the reactor pointer
is null'd immediately -> segfault in socket.close(). Latent on Windows IOCP
and Linux epoll. Fix: TcpAcceptor now tracks connections; new shutdown()
closes all + joins threads before io is destroyed; Server::stop() now closes
acceptor + media_relay too (was just io.stop()).
Verified: dev + apple-dev presets build green, 21/21 tests pass, server starts
+ two vccli text chat over TLS (M1 on Mac), vccli --voice starts MIC stream via
CoreAudio (M2 protocol-level), vccli --list-devices enumerates CoreAudio
devices, xcodebuild -create-xcframework produces valid VoiceCatCore.xcframework.
No ABI or proto changes. Docs updated: building.md, clients/apple/README.md,
PROGRESS.md, CLAUDE.md status line.
2026-06-18 13:24:42 +02:00
| `apple-dev` | `build/apple-dev` | vcpkg | Release | OFF | OFF | OFF | no | macOS | Static `libvoicecat.a` for the Swift Package / XCFramework (macOS slice). Validated on macOS 26.5 / Apple Silicon — builds green, produces valid arm64 `.a` + XCFramework. See [clients/apple/README.md ](../clients/apple/README.md ). |
build(cmake): clean up presets, add release/apple presets, cross-platform triplets
Rationalize the preset set to match the project's actual state (past M5):
- Rename dev->skeleton (no-deps stub smoke), m1-dev->dev (default dev preset)
- Drop m2-dev (cache-identical to m1-dev)
- Add release preset (optimized + tests on, symbols kept)
- Strip server-release binaries (-s linker flag)
- Add apple-dev/apple-ios/apple-ios-sim scaffolding presets for XCFramework
Add cmake/voicecat-toolchain.cmake wrapper that auto-resolves the vcpkg
triplet from the host platform (x64-mingw-static/x64-linux/arm64-osx) so
the main presets work on Windows/Linux/macOS without per-OS variants.
Update all docs (building.md, CLAUDE.md, README.md, AGENTS.md, deployment.md,
tech-stack.md, client READMEs) and stale preset-name references in code
comments. No C++ behavior changes — the core was already portable.
2026-06-18 03:16:01 +02:00
| `apple-ios` | `build/apple-ios` | vcpkg | Release | OFF | OFF | OFF | no | macOS→iOS | **Scaffolding** — cross-compiled static `libvoicecat.a` for iOS device (`arm64-ios` ). One XCFramework slice. Not yet CI-validated. |
| `apple-ios-sim` | `build/apple-ios-sim` | vcpkg | Release | OFF | OFF | OFF | no | macOS→iOS sim | **Scaffolding** — cross-compiled static `libvoicecat.a` for iOS simulator (`arm64-ios-sim` ). One XCFramework slice. Not yet CI-validated. |
So in practice there are three presets that matter for day-to-day work:
- **`dev` ** — everything: real protocol, real voice, real manual testing. This is the loop you run constantly.
- **`release` ** — same suite, optimized. Run it when you want to check optimized behavior or profile.
- **`skeleton` ** — fast no-deps build to confirm the stub path still compiles (CI smoke check).
The rest are purpose-specific: `server-release` for deployment, `windows-client` for the DLL,
`apple-*` for Apple platform slices.
### Platform matrix
The vcpkg presets (`dev` , `release` , `server-release` , `windows-client` , `apple-*` ) auto-resolve
the vcpkg triplet via [`cmake/voicecat-toolchain.cmake` ](../cmake/voicecat-toolchain.cmake ):
| Host platform | Auto-resolved triplet | Notes |
|---------------|----------------------|-------|
| Windows (MinGW/MSYS2) | `x64-mingw-static` | The project's Windows toolchain. MSVC users must set `VCPKG_TARGET_TRIPLET=x64-windows` explicitly. |
| Linux x64 | `x64-linux` | Server's primary deployment target (Docker, systemd). |
| Linux arm64 | `arm64-linux` | Raspberry Pi / ARM VPS. |
| macOS (Apple Silicon) | `arm64-osx` | `apple-dev` uses this automatically. |
| macOS (Intel) | `x64-osx` | `apple-dev` uses this automatically. |
Cross-compile presets (`apple-ios` , `apple-ios-sim` ) override `VCPKG_TARGET_TRIPLET` explicitly;
`VCPKG_HOST_TRIPLET` stays the host's (e.g. `arm64-osx` when building iOS on Apple Silicon).
### Preset history
The preset set was cleaned up on 2026-06-18 (see `PROGRESS.md` ). The old names map as follows:
| Old name | New name | Notes |
|----------|----------|-------|
| `dev` | `skeleton` | Renamed to reflect its actual purpose (no-deps stub smoke check). |
| `m1-dev` | `dev` | Renamed — the project is past M5, so milestone-named presets were misleading. This is now the default development preset. |
| `m2-dev` | *(dropped)* | Was cache-identical to `m1-dev` (same flags, same triplet, only the binary dir differed). Removed. |
| `server-release` | `server-release` | Unchanged name; now stripped (`-s` ) and auto-triplet. |
| *(new)* | `release` | New: optimized build with tests on, symbols kept. |
| `windows-client` | `windows-client` | Unchanged name; triplet now auto-resolved. |
| *(new)* | `apple-dev` , `apple-ios` , `apple-ios-sim` | New: Apple platform scaffolding. |
If you see `m1-dev` or `m2-dev` in old scripts, commits, or `PROGRESS.md` history entries,
use `dev` instead. Historical `PROGRESS.md` entries are left intact as a true record of what
was run.
docs: add build/manual-testing guide, fix stale M0 stub claims in headers
- docs/building.md: explains what each CMake preset (dev, m1-dev, m2-dev,
server-release) is actually for, and how to build voicecat-server + vccli
for manual testing. Linked from CLAUDE.md's doc index.
- core/include/voicecat.h, core/src/voicecat.cpp, core/src/protocol/protocol.h,
server/src/main.cpp: doc-header comments still claimed M0-skeleton/stub
behavior (VC_ERR_NOT_IMPLEMENTED everywhere, "prints what it would do",
protobuf codegen "commented") that M1-M3 made real. Updated to describe
current behavior, with the dev-preset stub fallback noted explicitly where
it still applies.
2026-06-16 16:30:07 +02:00
## 2. One-time setup for the real-deps presets
build(cmake): clean up presets, add release/apple presets, cross-platform triplets
Rationalize the preset set to match the project's actual state (past M5):
- Rename dev->skeleton (no-deps stub smoke), m1-dev->dev (default dev preset)
- Drop m2-dev (cache-identical to m1-dev)
- Add release preset (optimized + tests on, symbols kept)
- Strip server-release binaries (-s linker flag)
- Add apple-dev/apple-ios/apple-ios-sim scaffolding presets for XCFramework
Add cmake/voicecat-toolchain.cmake wrapper that auto-resolves the vcpkg
triplet from the host platform (x64-mingw-static/x64-linux/arm64-osx) so
the main presets work on Windows/Linux/macOS without per-OS variants.
Update all docs (building.md, CLAUDE.md, README.md, AGENTS.md, deployment.md,
tech-stack.md, client READMEs) and stale preset-name references in code
comments. No C++ behavior changes — the core was already portable.
2026-06-18 03:16:01 +02:00
`dev` , `release` , `server-release` , `windows-client` , and `apple-*` all need `VCPKG_ROOT`
pointing at a bootstrapped vcpkg checkout:
docs: add build/manual-testing guide, fix stale M0 stub claims in headers
- docs/building.md: explains what each CMake preset (dev, m1-dev, m2-dev,
server-release) is actually for, and how to build voicecat-server + vccli
for manual testing. Linked from CLAUDE.md's doc index.
- core/include/voicecat.h, core/src/voicecat.cpp, core/src/protocol/protocol.h,
server/src/main.cpp: doc-header comments still claimed M0-skeleton/stub
behavior (VC_ERR_NOT_IMPLEMENTED everywhere, "prints what it would do",
protobuf codegen "commented") that M1-M3 made real. Updated to describe
current behavior, with the dev-preset stub fallback noted explicitly where
it still applies.
2026-06-16 16:30:07 +02:00
```bash
# once:
git clone https://github.com/microsoft/vcpkg
./vcpkg/bootstrap-vcpkg.sh # .bat on Windows
# every shell session (PowerShell):
$env:VCPKG_ROOT = "D:\path\to\vcpkg"
build(cmake): clean up presets, add release/apple presets, cross-platform triplets
Rationalize the preset set to match the project's actual state (past M5):
- Rename dev->skeleton (no-deps stub smoke), m1-dev->dev (default dev preset)
- Drop m2-dev (cache-identical to m1-dev)
- Add release preset (optimized + tests on, symbols kept)
- Strip server-release binaries (-s linker flag)
- Add apple-dev/apple-ios/apple-ios-sim scaffolding presets for XCFramework
Add cmake/voicecat-toolchain.cmake wrapper that auto-resolves the vcpkg
triplet from the host platform (x64-mingw-static/x64-linux/arm64-osx) so
the main presets work on Windows/Linux/macOS without per-OS variants.
Update all docs (building.md, CLAUDE.md, README.md, AGENTS.md, deployment.md,
tech-stack.md, client READMEs) and stale preset-name references in code
comments. No C++ behavior changes — the core was already portable.
2026-06-18 03:16:01 +02:00
# or on Linux/macOS:
export VCPKG_ROOT=/path/to/vcpkg
docs: add build/manual-testing guide, fix stale M0 stub claims in headers
- docs/building.md: explains what each CMake preset (dev, m1-dev, m2-dev,
server-release) is actually for, and how to build voicecat-server + vccli
for manual testing. Linked from CLAUDE.md's doc index.
- core/include/voicecat.h, core/src/voicecat.cpp, core/src/protocol/protocol.h,
server/src/main.cpp: doc-header comments still claimed M0-skeleton/stub
behavior (VC_ERR_NOT_IMPLEMENTED everywhere, "prints what it would do",
protobuf codegen "commented") that M1-M3 made real. Updated to describe
current behavior, with the dev-preset stub fallback noted explicitly where
it still applies.
2026-06-16 16:30:07 +02:00
```
`vcpkg.json` (manifest mode) pins every dependency (protobuf, mbedTLS, libsodium, asio,
build(cmake): clean up presets, add release/apple presets, cross-platform triplets
Rationalize the preset set to match the project's actual state (past M5):
- Rename dev->skeleton (no-deps stub smoke), m1-dev->dev (default dev preset)
- Drop m2-dev (cache-identical to m1-dev)
- Add release preset (optimized + tests on, symbols kept)
- Strip server-release binaries (-s linker flag)
- Add apple-dev/apple-ios/apple-ios-sim scaffolding presets for XCFramework
Add cmake/voicecat-toolchain.cmake wrapper that auto-resolves the vcpkg
triplet from the host platform (x64-mingw-static/x64-linux/arm64-osx) so
the main presets work on Windows/Linux/macOS without per-OS variants.
Update all docs (building.md, CLAUDE.md, README.md, AGENTS.md, deployment.md,
tech-stack.md, client READMEs) and stale preset-name references in code
comments. No C++ behavior changes — the core was already portable.
2026-06-18 03:16:01 +02:00
sqlite3, spdlog, opus, miniaudio) — `cmake --preset dev` resolves and builds them
docs: add build/manual-testing guide, fix stale M0 stub claims in headers
- docs/building.md: explains what each CMake preset (dev, m1-dev, m2-dev,
server-release) is actually for, and how to build voicecat-server + vccli
for manual testing. Linked from CLAUDE.md's doc index.
- core/include/voicecat.h, core/src/voicecat.cpp, core/src/protocol/protocol.h,
server/src/main.cpp: doc-header comments still claimed M0-skeleton/stub
behavior (VC_ERR_NOT_IMPLEMENTED everywhere, "prints what it would do",
protobuf codegen "commented") that M1-M3 made real. Updated to describe
current behavior, with the dev-preset stub fallback noted explicitly where
it still applies.
2026-06-16 16:30:07 +02:00
automatically on first configure. That first configure is slow (vcpkg building from source);
subsequent ones are cached.
## 3. Build + test (the loop you'll run constantly)
```bash
build(cmake): clean up presets, add release/apple presets, cross-platform triplets
Rationalize the preset set to match the project's actual state (past M5):
- Rename dev->skeleton (no-deps stub smoke), m1-dev->dev (default dev preset)
- Drop m2-dev (cache-identical to m1-dev)
- Add release preset (optimized + tests on, symbols kept)
- Strip server-release binaries (-s linker flag)
- Add apple-dev/apple-ios/apple-ios-sim scaffolding presets for XCFramework
Add cmake/voicecat-toolchain.cmake wrapper that auto-resolves the vcpkg
triplet from the host platform (x64-mingw-static/x64-linux/arm64-osx) so
the main presets work on Windows/Linux/macOS without per-OS variants.
Update all docs (building.md, CLAUDE.md, README.md, AGENTS.md, deployment.md,
tech-stack.md, client READMEs) and stale preset-name references in code
comments. No C++ behavior changes — the core was already portable.
2026-06-18 03:16:01 +02:00
cmake --preset dev
cmake --build --preset dev
ctest --preset dev
docs: add build/manual-testing guide, fix stale M0 stub claims in headers
- docs/building.md: explains what each CMake preset (dev, m1-dev, m2-dev,
server-release) is actually for, and how to build voicecat-server + vccli
for manual testing. Linked from CLAUDE.md's doc index.
- core/include/voicecat.h, core/src/voicecat.cpp, core/src/protocol/protocol.h,
server/src/main.cpp: doc-header comments still claimed M0-skeleton/stub
behavior (VC_ERR_NOT_IMPLEMENTED everywhere, "prints what it would do",
protobuf codegen "commented") that M1-M3 made real. Updated to describe
current behavior, with the dev-preset stub fallback noted explicitly where
it still applies.
2026-06-16 16:30:07 +02:00
```
build(cmake): clean up presets, add release/apple presets, cross-platform triplets
Rationalize the preset set to match the project's actual state (past M5):
- Rename dev->skeleton (no-deps stub smoke), m1-dev->dev (default dev preset)
- Drop m2-dev (cache-identical to m1-dev)
- Add release preset (optimized + tests on, symbols kept)
- Strip server-release binaries (-s linker flag)
- Add apple-dev/apple-ios/apple-ios-sim scaffolding presets for XCFramework
Add cmake/voicecat-toolchain.cmake wrapper that auto-resolves the vcpkg
triplet from the host platform (x64-mingw-static/x64-linux/arm64-osx) so
the main presets work on Windows/Linux/macOS without per-OS variants.
Update all docs (building.md, CLAUDE.md, README.md, AGENTS.md, deployment.md,
tech-stack.md, client READMEs) and stale preset-name references in code
comments. No C++ behavior changes — the core was already portable.
2026-06-18 03:16:01 +02:00
Binaries land in `build/dev/bin/` (`.exe` suffix on Windows):
- `build/dev/bin/voicecat-server`
- `build/dev/bin/vccli`
- `build/dev/bin/voicecat-admin`
docs: add build/manual-testing guide, fix stale M0 stub claims in headers
- docs/building.md: explains what each CMake preset (dev, m1-dev, m2-dev,
server-release) is actually for, and how to build voicecat-server + vccli
for manual testing. Linked from CLAUDE.md's doc index.
- core/include/voicecat.h, core/src/voicecat.cpp, core/src/protocol/protocol.h,
server/src/main.cpp: doc-header comments still claimed M0-skeleton/stub
behavior (VC_ERR_NOT_IMPLEMENTED everywhere, "prints what it would do",
protobuf codegen "commented") that M1-M3 made real. Updated to describe
current behavior, with the dev-preset stub fallback noted explicitly where
it still applies.
2026-06-16 16:30:07 +02:00
build(cmake): clean up presets, add release/apple presets, cross-platform triplets
Rationalize the preset set to match the project's actual state (past M5):
- Rename dev->skeleton (no-deps stub smoke), m1-dev->dev (default dev preset)
- Drop m2-dev (cache-identical to m1-dev)
- Add release preset (optimized + tests on, symbols kept)
- Strip server-release binaries (-s linker flag)
- Add apple-dev/apple-ios/apple-ios-sim scaffolding presets for XCFramework
Add cmake/voicecat-toolchain.cmake wrapper that auto-resolves the vcpkg
triplet from the host platform (x64-mingw-static/x64-linux/arm64-osx) so
the main presets work on Windows/Linux/macOS without per-OS variants.
Update all docs (building.md, CLAUDE.md, README.md, AGENTS.md, deployment.md,
tech-stack.md, client READMEs) and stale preset-name references in code
comments. No C++ behavior changes — the core was already portable.
2026-06-18 03:16:01 +02:00
To run the same suite against optimized code:
```bash
cmake --preset release
cmake --build --preset release
ctest --preset release
```
docs: add build/manual-testing guide, fix stale M0 stub claims in headers
- docs/building.md: explains what each CMake preset (dev, m1-dev, m2-dev,
server-release) is actually for, and how to build voicecat-server + vccli
for manual testing. Linked from CLAUDE.md's doc index.
- core/include/voicecat.h, core/src/voicecat.cpp, core/src/protocol/protocol.h,
server/src/main.cpp: doc-header comments still claimed M0-skeleton/stub
behavior (VC_ERR_NOT_IMPLEMENTED everywhere, "prints what it would do",
protobuf codegen "commented") that M1-M3 made real. Updated to describe
current behavior, with the dev-preset stub fallback noted explicitly where
it still applies.
2026-06-16 16:30:07 +02:00
## 4. Manual testing: server + two clients
### Start the server
```bash
build(cmake): clean up presets, add release/apple presets, cross-platform triplets
Rationalize the preset set to match the project's actual state (past M5):
- Rename dev->skeleton (no-deps stub smoke), m1-dev->dev (default dev preset)
- Drop m2-dev (cache-identical to m1-dev)
- Add release preset (optimized + tests on, symbols kept)
- Strip server-release binaries (-s linker flag)
- Add apple-dev/apple-ios/apple-ios-sim scaffolding presets for XCFramework
Add cmake/voicecat-toolchain.cmake wrapper that auto-resolves the vcpkg
triplet from the host platform (x64-mingw-static/x64-linux/arm64-osx) so
the main presets work on Windows/Linux/macOS without per-OS variants.
Update all docs (building.md, CLAUDE.md, README.md, AGENTS.md, deployment.md,
tech-stack.md, client READMEs) and stale preset-name references in code
comments. No C++ behavior changes — the core was already portable.
2026-06-18 03:16:01 +02:00
./build/dev/bin/voicecat-server --name "Test Server" --data-dir ./voicecat-data
docs: add build/manual-testing guide, fix stale M0 stub claims in headers
- docs/building.md: explains what each CMake preset (dev, m1-dev, m2-dev,
server-release) is actually for, and how to build voicecat-server + vccli
for manual testing. Linked from CLAUDE.md's doc index.
- core/include/voicecat.h, core/src/voicecat.cpp, core/src/protocol/protocol.h,
server/src/main.cpp: doc-header comments still claimed M0-skeleton/stub
behavior (VC_ERR_NOT_IMPLEMENTED everywhere, "prints what it would do",
protobuf codegen "commented") that M1-M3 made real. Updated to describe
current behavior, with the dev-preset stub fallback noted explicitly where
it still applies.
2026-06-16 16:30:07 +02:00
```
First run generates an Ed25519 identity + self-signed cert under `--data-dir` , creates the
SQLite store, and creates a default "Lobby" channel. Other server flags:
```
--port < n > control+media port (default 8384)
--data-dir < path > data directory (default ./voicecat-data)
--name < name > server name
--no-guests disable guest access (then provision accounts via voicecat-admin)
--print-config print effective config and exit
--version print version and exit
```
### Drive it with `vccli`
`vccli` is the headless client used to exercise the protocol by hand. Full flag list:
```
vccli [--host H] [--port P] [--nick NAME] [--channel ID]
[--voice] [--mute] [--text MSG] [--list-devices]
[--input-device ID] [--input-mode vad|ptt] [--share-screen-audio]
--host H server host (default 127.0.0.1)
--port P server TCP port (default 8384)
--nick NAME guest nickname (default vccli-test)
--channel ID channel to join after auth (default 1, Lobby)
--voice start a MIC stream and stay connected until Ctrl+C
--mute start with the mic muted (only meaningful with --voice)
--text MSG send MSG to the channel, then exit
--list-devices print input/output devices (vc_list_devices) and exit
--input-device ID use device ID (from --list-devices) for the MIC stream
--input-mode vad|ptt send-side input gate mode (default vad)
--share-screen-audio also start a SCREEN_AUDIO stream (WASAPI loopback on Windows)
```
While `--voice` is running, stdin accepts `ptt on` , `ptt off` , `mode vad` , `mode ptt` to
toggle the input gate live.
**Smoke test — two clients talking:**
```bash
# terminal A
build(cmake): clean up presets, add release/apple presets, cross-platform triplets
Rationalize the preset set to match the project's actual state (past M5):
- Rename dev->skeleton (no-deps stub smoke), m1-dev->dev (default dev preset)
- Drop m2-dev (cache-identical to m1-dev)
- Add release preset (optimized + tests on, symbols kept)
- Strip server-release binaries (-s linker flag)
- Add apple-dev/apple-ios/apple-ios-sim scaffolding presets for XCFramework
Add cmake/voicecat-toolchain.cmake wrapper that auto-resolves the vcpkg
triplet from the host platform (x64-mingw-static/x64-linux/arm64-osx) so
the main presets work on Windows/Linux/macOS without per-OS variants.
Update all docs (building.md, CLAUDE.md, README.md, AGENTS.md, deployment.md,
tech-stack.md, client READMEs) and stale preset-name references in code
comments. No C++ behavior changes — the core was already portable.
2026-06-18 03:16:01 +02:00
./build/dev/bin/vccli --nick Alice --text "hello from Alice"
docs: add build/manual-testing guide, fix stale M0 stub claims in headers
- docs/building.md: explains what each CMake preset (dev, m1-dev, m2-dev,
server-release) is actually for, and how to build voicecat-server + vccli
for manual testing. Linked from CLAUDE.md's doc index.
- core/include/voicecat.h, core/src/voicecat.cpp, core/src/protocol/protocol.h,
server/src/main.cpp: doc-header comments still claimed M0-skeleton/stub
behavior (VC_ERR_NOT_IMPLEMENTED everywhere, "prints what it would do",
protobuf codegen "commented") that M1-M3 made real. Updated to describe
current behavior, with the dev-preset stub fallback noted explicitly where
it still applies.
2026-06-16 16:30:07 +02:00
# terminal B (separate window, after A confirms it sent)
build(cmake): clean up presets, add release/apple presets, cross-platform triplets
Rationalize the preset set to match the project's actual state (past M5):
- Rename dev->skeleton (no-deps stub smoke), m1-dev->dev (default dev preset)
- Drop m2-dev (cache-identical to m1-dev)
- Add release preset (optimized + tests on, symbols kept)
- Strip server-release binaries (-s linker flag)
- Add apple-dev/apple-ios/apple-ios-sim scaffolding presets for XCFramework
Add cmake/voicecat-toolchain.cmake wrapper that auto-resolves the vcpkg
triplet from the host platform (x64-mingw-static/x64-linux/arm64-osx) so
the main presets work on Windows/Linux/macOS without per-OS variants.
Update all docs (building.md, CLAUDE.md, README.md, AGENTS.md, deployment.md,
tech-stack.md, client READMEs) and stale preset-name references in code
comments. No C++ behavior changes — the core was already portable.
2026-06-18 03:16:01 +02:00
./build/dev/bin/vccli --nick Bob --text "hello from Bob"
docs: add build/manual-testing guide, fix stale M0 stub claims in headers
- docs/building.md: explains what each CMake preset (dev, m1-dev, m2-dev,
server-release) is actually for, and how to build voicecat-server + vccli
for manual testing. Linked from CLAUDE.md's doc index.
- core/include/voicecat.h, core/src/voicecat.cpp, core/src/protocol/protocol.h,
server/src/main.cpp: doc-header comments still claimed M0-skeleton/stub
behavior (VC_ERR_NOT_IMPLEMENTED everywhere, "prints what it would do",
protobuf codegen "commented") that M1-M3 made real. Updated to describe
current behavior, with the dev-preset stub fallback noted explicitly where
it still applies.
2026-06-16 16:30:07 +02:00
```
**Real voice between two clients (needs working mic/speakers, two terminals):**
```bash
# terminal A
build(cmake): clean up presets, add release/apple presets, cross-platform triplets
Rationalize the preset set to match the project's actual state (past M5):
- Rename dev->skeleton (no-deps stub smoke), m1-dev->dev (default dev preset)
- Drop m2-dev (cache-identical to m1-dev)
- Add release preset (optimized + tests on, symbols kept)
- Strip server-release binaries (-s linker flag)
- Add apple-dev/apple-ios/apple-ios-sim scaffolding presets for XCFramework
Add cmake/voicecat-toolchain.cmake wrapper that auto-resolves the vcpkg
triplet from the host platform (x64-mingw-static/x64-linux/arm64-osx) so
the main presets work on Windows/Linux/macOS without per-OS variants.
Update all docs (building.md, CLAUDE.md, README.md, AGENTS.md, deployment.md,
tech-stack.md, client READMEs) and stale preset-name references in code
comments. No C++ behavior changes — the core was already portable.
2026-06-18 03:16:01 +02:00
./build/dev/bin/vccli --nick Alice --voice
docs: add build/manual-testing guide, fix stale M0 stub claims in headers
- docs/building.md: explains what each CMake preset (dev, m1-dev, m2-dev,
server-release) is actually for, and how to build voicecat-server + vccli
for manual testing. Linked from CLAUDE.md's doc index.
- core/include/voicecat.h, core/src/voicecat.cpp, core/src/protocol/protocol.h,
server/src/main.cpp: doc-header comments still claimed M0-skeleton/stub
behavior (VC_ERR_NOT_IMPLEMENTED everywhere, "prints what it would do",
protobuf codegen "commented") that M1-M3 made real. Updated to describe
current behavior, with the dev-preset stub fallback noted explicitly where
it still applies.
2026-06-16 16:30:07 +02:00
# terminal B
build(cmake): clean up presets, add release/apple presets, cross-platform triplets
Rationalize the preset set to match the project's actual state (past M5):
- Rename dev->skeleton (no-deps stub smoke), m1-dev->dev (default dev preset)
- Drop m2-dev (cache-identical to m1-dev)
- Add release preset (optimized + tests on, symbols kept)
- Strip server-release binaries (-s linker flag)
- Add apple-dev/apple-ios/apple-ios-sim scaffolding presets for XCFramework
Add cmake/voicecat-toolchain.cmake wrapper that auto-resolves the vcpkg
triplet from the host platform (x64-mingw-static/x64-linux/arm64-osx) so
the main presets work on Windows/Linux/macOS without per-OS variants.
Update all docs (building.md, CLAUDE.md, README.md, AGENTS.md, deployment.md,
tech-stack.md, client READMEs) and stale preset-name references in code
comments. No C++ behavior changes — the core was already portable.
2026-06-18 03:16:01 +02:00
./build/dev/bin/vccli --nick Bob --voice
docs: add build/manual-testing guide, fix stale M0 stub claims in headers
- docs/building.md: explains what each CMake preset (dev, m1-dev, m2-dev,
server-release) is actually for, and how to build voicecat-server + vccli
for manual testing. Linked from CLAUDE.md's doc index.
- core/include/voicecat.h, core/src/voicecat.cpp, core/src/protocol/protocol.h,
server/src/main.cpp: doc-header comments still claimed M0-skeleton/stub
behavior (VC_ERR_NOT_IMPLEMENTED everywhere, "prints what it would do",
protobuf codegen "commented") that M1-M3 made real. Updated to describe
current behavior, with the dev-preset stub fallback noted explicitly where
it still applies.
2026-06-16 16:30:07 +02:00
```
Speak into the mic on one side; you should hear it on the other. Ctrl+C to disconnect.
**Enumerate audio devices before picking one:**
```bash
build(cmake): clean up presets, add release/apple presets, cross-platform triplets
Rationalize the preset set to match the project's actual state (past M5):
- Rename dev->skeleton (no-deps stub smoke), m1-dev->dev (default dev preset)
- Drop m2-dev (cache-identical to m1-dev)
- Add release preset (optimized + tests on, symbols kept)
- Strip server-release binaries (-s linker flag)
- Add apple-dev/apple-ios/apple-ios-sim scaffolding presets for XCFramework
Add cmake/voicecat-toolchain.cmake wrapper that auto-resolves the vcpkg
triplet from the host platform (x64-mingw-static/x64-linux/arm64-osx) so
the main presets work on Windows/Linux/macOS without per-OS variants.
Update all docs (building.md, CLAUDE.md, README.md, AGENTS.md, deployment.md,
tech-stack.md, client READMEs) and stale preset-name references in code
comments. No C++ behavior changes — the core was already portable.
2026-06-18 03:16:01 +02:00
./build/dev/bin/vccli --list-devices
./build/dev/bin/vccli --nick Alice --voice --input-device < ID > --input-mode ptt
docs: add build/manual-testing guide, fix stale M0 stub claims in headers
- docs/building.md: explains what each CMake preset (dev, m1-dev, m2-dev,
server-release) is actually for, and how to build voicecat-server + vccli
for manual testing. Linked from CLAUDE.md's doc index.
- core/include/voicecat.h, core/src/voicecat.cpp, core/src/protocol/protocol.h,
server/src/main.cpp: doc-header comments still claimed M0-skeleton/stub
behavior (VC_ERR_NOT_IMPLEMENTED everywhere, "prints what it would do",
protobuf codegen "commented") that M1-M3 made real. Updated to describe
current behavior, with the dev-preset stub fallback noted explicitly where
it still applies.
2026-06-16 16:30:07 +02:00
```
**Provisioning a non-guest account** (if the server was started with `--no-guests` ):
```bash
build(cmake): clean up presets, add release/apple presets, cross-platform triplets
Rationalize the preset set to match the project's actual state (past M5):
- Rename dev->skeleton (no-deps stub smoke), m1-dev->dev (default dev preset)
- Drop m2-dev (cache-identical to m1-dev)
- Add release preset (optimized + tests on, symbols kept)
- Strip server-release binaries (-s linker flag)
- Add apple-dev/apple-ios/apple-ios-sim scaffolding presets for XCFramework
Add cmake/voicecat-toolchain.cmake wrapper that auto-resolves the vcpkg
triplet from the host platform (x64-mingw-static/x64-linux/arm64-osx) so
the main presets work on Windows/Linux/macOS without per-OS variants.
Update all docs (building.md, CLAUDE.md, README.md, AGENTS.md, deployment.md,
tech-stack.md, client READMEs) and stale preset-name references in code
comments. No C++ behavior changes — the core was already portable.
2026-06-18 03:16:01 +02:00
./build/dev/bin/voicecat-admin --data-dir ./voicecat-data account add alice --password secret
./build/dev/bin/voicecat-admin --data-dir ./voicecat-data account list
docs: add build/manual-testing guide, fix stale M0 stub claims in headers
- docs/building.md: explains what each CMake preset (dev, m1-dev, m2-dev,
server-release) is actually for, and how to build voicecat-server + vccli
for manual testing. Linked from CLAUDE.md's doc index.
- core/include/voicecat.h, core/src/voicecat.cpp, core/src/protocol/protocol.h,
server/src/main.cpp: doc-header comments still claimed M0-skeleton/stub
behavior (VC_ERR_NOT_IMPLEMENTED everywhere, "prints what it would do",
protobuf codegen "commented") that M1-M3 made real. Updated to describe
current behavior, with the dev-preset stub fallback noted explicitly where
it still applies.
2026-06-16 16:30:07 +02:00
```
## 5. `server-release` (production-shaped build)
build(cmake): clean up presets, add release/apple presets, cross-platform triplets
Rationalize the preset set to match the project's actual state (past M5):
- Rename dev->skeleton (no-deps stub smoke), m1-dev->dev (default dev preset)
- Drop m2-dev (cache-identical to m1-dev)
- Add release preset (optimized + tests on, symbols kept)
- Strip server-release binaries (-s linker flag)
- Add apple-dev/apple-ios/apple-ios-sim scaffolding presets for XCFramework
Add cmake/voicecat-toolchain.cmake wrapper that auto-resolves the vcpkg
triplet from the host platform (x64-mingw-static/x64-linux/arm64-osx) so
the main presets work on Windows/Linux/macOS without per-OS variants.
Update all docs (building.md, CLAUDE.md, README.md, AGENTS.md, deployment.md,
tech-stack.md, client READMEs) and stale preset-name references in code
comments. No C++ behavior changes — the core was already portable.
2026-06-18 03:16:01 +02:00
Same dependency story, but `Release` build type, stripped binaries, and no tests — this is the
closest local analogue to what [docs/deployment.md ](deployment.md )'s "from source" path
produces:
docs: add build/manual-testing guide, fix stale M0 stub claims in headers
- docs/building.md: explains what each CMake preset (dev, m1-dev, m2-dev,
server-release) is actually for, and how to build voicecat-server + vccli
for manual testing. Linked from CLAUDE.md's doc index.
- core/include/voicecat.h, core/src/voicecat.cpp, core/src/protocol/protocol.h,
server/src/main.cpp: doc-header comments still claimed M0-skeleton/stub
behavior (VC_ERR_NOT_IMPLEMENTED everywhere, "prints what it would do",
protobuf codegen "commented") that M1-M3 made real. Updated to describe
current behavior, with the dev-preset stub fallback noted explicitly where
it still applies.
2026-06-16 16:30:07 +02:00
```bash
cmake --preset server-release
cmake --build --preset server-release
./build/server-release/bin/voicecat-server
```
Use this to sanity-check release-mode behavior (e.g. perf, optimized codepaths) — not for
build(cmake): clean up presets, add release/apple presets, cross-platform triplets
Rationalize the preset set to match the project's actual state (past M5):
- Rename dev->skeleton (no-deps stub smoke), m1-dev->dev (default dev preset)
- Drop m2-dev (cache-identical to m1-dev)
- Add release preset (optimized + tests on, symbols kept)
- Strip server-release binaries (-s linker flag)
- Add apple-dev/apple-ios/apple-ios-sim scaffolding presets for XCFramework
Add cmake/voicecat-toolchain.cmake wrapper that auto-resolves the vcpkg
triplet from the host platform (x64-mingw-static/x64-linux/arm64-osx) so
the main presets work on Windows/Linux/macOS without per-OS variants.
Update all docs (building.md, CLAUDE.md, README.md, AGENTS.md, deployment.md,
tech-stack.md, client READMEs) and stale preset-name references in code
comments. No C++ behavior changes — the core was already portable.
2026-06-18 03:16:01 +02:00
day-to-day development, since it has no test target wired up. The `-s` linker flag strips
symbol tables from the binaries, producing smaller executables suitable for distribution.
2026-06-19 02:19:38 +02:00
## 6. Apple platform builds
build(cmake): clean up presets, add release/apple presets, cross-platform triplets
Rationalize the preset set to match the project's actual state (past M5):
- Rename dev->skeleton (no-deps stub smoke), m1-dev->dev (default dev preset)
- Drop m2-dev (cache-identical to m1-dev)
- Add release preset (optimized + tests on, symbols kept)
- Strip server-release binaries (-s linker flag)
- Add apple-dev/apple-ios/apple-ios-sim scaffolding presets for XCFramework
Add cmake/voicecat-toolchain.cmake wrapper that auto-resolves the vcpkg
triplet from the host platform (x64-mingw-static/x64-linux/arm64-osx) so
the main presets work on Windows/Linux/macOS without per-OS variants.
Update all docs (building.md, CLAUDE.md, README.md, AGENTS.md, deployment.md,
tech-stack.md, client READMEs) and stale preset-name references in code
comments. No C++ behavior changes — the core was already portable.
2026-06-18 03:16:01 +02:00
The `apple-dev` , `apple-ios` , and `apple-ios-sim` presets produce static `libvoicecat.a`
2026-06-19 02:19:38 +02:00
slices for the Swift Package / XCFramework. All three are validated on macOS 26.5 / Apple
Silicon. Build on macOS:
build(cmake): clean up presets, add release/apple presets, cross-platform triplets
Rationalize the preset set to match the project's actual state (past M5):
- Rename dev->skeleton (no-deps stub smoke), m1-dev->dev (default dev preset)
- Drop m2-dev (cache-identical to m1-dev)
- Add release preset (optimized + tests on, symbols kept)
- Strip server-release binaries (-s linker flag)
- Add apple-dev/apple-ios/apple-ios-sim scaffolding presets for XCFramework
Add cmake/voicecat-toolchain.cmake wrapper that auto-resolves the vcpkg
triplet from the host platform (x64-mingw-static/x64-linux/arm64-osx) so
the main presets work on Windows/Linux/macOS without per-OS variants.
Update all docs (building.md, CLAUDE.md, README.md, AGENTS.md, deployment.md,
tech-stack.md, client READMEs) and stale preset-name references in code
comments. No C++ behavior changes — the core was already portable.
2026-06-18 03:16:01 +02:00
```bash
# macOS slice (arm64-osx on Apple Silicon, x64-osx on Intel)
cmake --preset apple-dev
cmake --build --preset apple-dev
# → build/apple-dev/lib/libvoicecat.a
2026-06-19 02:19:38 +02:00
# iOS device slice (arm64-ios)
build(cmake): clean up presets, add release/apple presets, cross-platform triplets
Rationalize the preset set to match the project's actual state (past M5):
- Rename dev->skeleton (no-deps stub smoke), m1-dev->dev (default dev preset)
- Drop m2-dev (cache-identical to m1-dev)
- Add release preset (optimized + tests on, symbols kept)
- Strip server-release binaries (-s linker flag)
- Add apple-dev/apple-ios/apple-ios-sim scaffolding presets for XCFramework
Add cmake/voicecat-toolchain.cmake wrapper that auto-resolves the vcpkg
triplet from the host platform (x64-mingw-static/x64-linux/arm64-osx) so
the main presets work on Windows/Linux/macOS without per-OS variants.
Update all docs (building.md, CLAUDE.md, README.md, AGENTS.md, deployment.md,
tech-stack.md, client READMEs) and stale preset-name references in code
comments. No C++ behavior changes — the core was already portable.
2026-06-18 03:16:01 +02:00
cmake --preset apple-ios
cmake --build --preset apple-ios
# → build/apple-ios/lib/libvoicecat.a
2026-06-19 02:19:38 +02:00
# iOS simulator slice (arm64-ios-simulator)
build(cmake): clean up presets, add release/apple presets, cross-platform triplets
Rationalize the preset set to match the project's actual state (past M5):
- Rename dev->skeleton (no-deps stub smoke), m1-dev->dev (default dev preset)
- Drop m2-dev (cache-identical to m1-dev)
- Add release preset (optimized + tests on, symbols kept)
- Strip server-release binaries (-s linker flag)
- Add apple-dev/apple-ios/apple-ios-sim scaffolding presets for XCFramework
Add cmake/voicecat-toolchain.cmake wrapper that auto-resolves the vcpkg
triplet from the host platform (x64-mingw-static/x64-linux/arm64-osx) so
the main presets work on Windows/Linux/macOS without per-OS variants.
Update all docs (building.md, CLAUDE.md, README.md, AGENTS.md, deployment.md,
tech-stack.md, client READMEs) and stale preset-name references in code
comments. No C++ behavior changes — the core was already portable.
2026-06-18 03:16:01 +02:00
cmake --preset apple-ios-sim
cmake --build --preset apple-ios-sim
# → build/apple-ios-sim/lib/libvoicecat.a
```
2026-06-19 02:19:38 +02:00
You rarely need to run these CMake commands directly. The
`clients/apple/scripts/build-xcframework.sh` script drives them internally and stitches
the result into a self-contained `VoiceCatCore.xcframework` :
```bash
# macOS slice only (default — used by macOS AppKit client)
clients/apple/scripts/build-xcframework.sh
# All 3 slices (macOS + iOS device + iOS sim — required for iOS client)
clients/apple/scripts/build-xcframework.sh --all
```
See [clients/apple/README.md ](../clients/apple/README.md ) for the XCFramework internals
(fat static lib merge, module map staging).
2026-06-18 17:36:47 +02:00
## 7. Windows client (C# / WinForms)
The Windows client is a .NET 10 WinForms app that loads `voicecat.dll` (the MinGW-built
shared library from the `windows-client` preset) via P/Invoke. Full details in
[`clients/windows/README.md` ](../clients/windows/README.md ).
**Prerequisites:** .NET SDK 10, MinGW-w64 / MSYS2 UCRT64 (GCC 13+), vcpkg.
### Build the DLL
```powershell
cmake --preset windows-client
cmake --build --preset windows-client
# → build/windows-client/bin/voicecat.dll
```
### Build the C# solution
```powershell
cd clients/windows
dotnet build VoiceCat.slnx
```
`Directory.Build.props` copies `voicecat.dll` into the output directory automatically.
### Run the app
```powershell
# Terminal 1 — start the server (built with the dev preset)
./build/dev/bin/voicecat-server.exe --name "My Server"
# Terminal 2 — launch the client
dotnet run --project clients/windows/VoiceCat.App/VoiceCat.App.csproj
```
### Run the C# interop tests
```powershell
dotnet test clients/windows/VoiceCat.slnx
```
## 8. macOS client (AppKit)
The macOS client is an Xcode project (AppKit / Swift) that links `libvoicecat` via the
`VoiceCatCore` Swift Package, which consumes a binary XCFramework target. Full details in
[`clients/apple/README.md` ](../clients/apple/README.md ).
**Prerequisites:** Xcode, vcpkg (`VCPKG_ROOT` set), macOS 14+ (deployment target).
### Build the XCFramework
The XCFramework is a local build artifact (gitignored, like the Windows DLL). It bundles
`libvoicecat.a` + all vcpkg static deps into a single fat `.a` per slice, plus staged
headers with a module map so Swift gets `import VoiceCatC` .
```bash
# macOS slice only (default, validated)
clients/apple/scripts/build-xcframework.sh
# → clients/apple/VoiceCatCore.xcframework/
# All 3 slices (macOS + iOS device + iOS sim — iOS still scaffolding)
clients/apple/scripts/build-xcframework.sh --all
```
The script runs `cmake --preset apple-dev` + `cmake --build --preset apple-dev` internally,
then merges vcpkg's static deps with `libtool -static` and stitches the XCFramework with
`xcodebuild -create-xcframework` .
### Build the Swift core (SPM)
```bash
cd clients/apple
swift build # builds VoiceCatCore library
swift test # 6 smoke tests against a real voicecat-server
```
`swift test` requires the `dev` CMake preset to be built
(`build/dev/bin/voicecat-server` + `voicecat-admin` ).
### Build the macOS app (Xcode)
```bash
xcodebuild -project clients/apple/macOS/VoiceCatMac.xcodeproj \
-scheme VoiceCatMac -configuration Debug build
# → ~/Library/Developer/Xcode/DerivedData/VoiceCatMac-*/Build/Products/Debug/VoiceCatMac.app
```
Or open the project in Xcode and build from the UI:
```bash
open clients/apple/macOS/VoiceCatMac.xcodeproj
```
### Run the app
```bash
# Terminal 1 — start the server (built with the dev preset)
./build/dev/bin/voicecat-server --name "My Server"
# Terminal 2 — launch the client
open ~/Library/Developer/Xcode/DerivedData/VoiceCatMac-*/Build/Products/Debug/VoiceCatMac.app
```
2026-06-19 02:19:38 +02:00
Or use the per-artifact script which builds and stages to `dist/macos-client/` :
```bash
scripts/build-macos-client.sh
```
## 9. iOS client (SwiftUI)
The iOS client is an Xcode project (`clients/apple/iOS/VoiceCatiOS.xcodeproj` ) that
links `libvoicecat` via the same `VoiceCatCore` Swift Package as the macOS client.
Full details in [`clients/apple/README.md` ](../clients/apple/README.md ).
**Prerequisites:** Xcode, vcpkg (`VCPKG_ROOT` set), iOS Simulator runtime installed
(Xcode > Settings > Platforms > iOS). iOS deployment target: 17.0.
### Build the XCFramework (all slices)
The iOS build requires the `ios-arm64-simulator` slice in the XCFramework — not just the
macOS slice. Use the `--all` flag to produce all three slices:
```bash
clients/apple/scripts/build-xcframework.sh --all
# → clients/apple/VoiceCatCore.xcframework/
# ├── macos-arm64/
# ├── ios-arm64/
# └── ios-arm64-simulator/
```
### Build the iOS simulator app
```bash
# Via the convenience script (recommended):
scripts/build-ios-client.sh
# → clients/apple/iOS/build/Debug-iphonesimulator/VoiceCatiOS.app
# → dist/ios-client/VoiceCatiOS.app
# Or as a single command (what the script does under the hood):
SIM_SDK="iphonesimulator$(xcrun --sdk iphonesimulator --show-sdk-version)"
BUILD_DIR="$(pwd)/clients/apple/iOS/build"
xcodebuild \
-project clients/apple/iOS/VoiceCatiOS.xcodeproj \
-target VoiceCatiOS \
-sdk "$SIM_SDK" \
-configuration Debug \
CODE_SIGNING_ALLOWED=NO \
ARCHS=arm64 \
ONLY_ACTIVE_ARCH=YES \
SYMROOT="$BUILD_DIR" \
OBJROOT="$BUILD_DIR" \
build
```
**Why `-target` instead of `-scheme -destination` ?** Using `-scheme VoiceCatiOS
-destination 'platform=iOS Simulator,OS=latest'` requires a simulator runtime whose iOS
version exactly matches the SDK version (`iphonesimulatorX.Y` ). If you have an older
runtime installed (common when the SDK ships ahead of runtime availability in Xcode), the
build fails with "Unable to find a destination matching the provided destination specifier."
Using `-target` bypasses destination matching and builds against the SDK directly.
**Why `SYMROOT=OBJROOT=clients/apple/iOS/build` ?** When building with `-target` (not
`-scheme` ), the local Swift Package (`VoiceCatCore` ) resolves its build products relative
to `OBJROOT` . By default, SPM resolves into `clients/apple/build/` , while the app target
looks in `clients/apple/iOS/build/` . Pointing both to the same directory fixes the
"unable to resolve module dependency: 'VoiceCatCore'" error.
### Run on the iOS Simulator
```bash
# Via the script (finds or boots an iPhone simulator, installs, launches):
scripts/run-ios-simulator.sh
# Build and run in one step:
scripts/run-ios-simulator.sh --build
# Stream app logs after launch:
scripts/run-ios-simulator.sh --log
# Target a specific device by name or UDID:
scripts/run-ios-simulator.sh --device "iPhone 16 Pro"
scripts/run-ios-simulator.sh --udid XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
```
Under the hood the script uses `xcrun simctl` commands:
```bash
# Boot a simulator (if not already running):
xcrun simctl boot < UDID >
open -a Simulator
# Install the built .app:
xcrun simctl install < UDID > clients/apple/iOS/build/Debug-iphonesimulator/VoiceCatiOS.app
# Launch the app:
xcrun simctl launch < UDID > cat.voice.VoiceCatiOS
# Stream logs (Ctrl+C to stop — does not kill the app):
xcrun simctl spawn < UDID > log stream --predicate 'subsystem contains "VoiceCat"'
```
### Run the full stack (server + iOS simulator)
```bash
# Terminal 1 — start the server
./build/dev/bin/voicecat-server --name "My Server"
# Terminal 2 — build + launch iOS client on simulator
scripts/run-ios-simulator.sh --build
```
On first connect the app will show a TOFU identity sheet — accept it, then join a channel.
### Open in Xcode
```bash
open clients/apple/iOS/VoiceCatiOS.xcodeproj
```
Xcode can build and run on the simulator directly. The XCFramework must already exist
(`clients/apple/VoiceCatCore.xcframework/` ) — run `build-xcframework.sh --all` once
before opening Xcode.