- 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.
6.7 KiB
Building & Manual Testing
This doc explains what each CMake preset in 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; for ctest targets see AGENTS.md. This doc is
the missing middle: how the presets relate to each other, and how to drive the binaries by
hand.
1. What each preset is for
| Preset | Binary dir | Deps | What it's actually for |
|---|---|---|---|
dev |
build/dev |
none (VOICECAT_USE_VCPKG_DEPS=OFF) |
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, not for testing real voice/control behavior. |
vcpkg-base |
— | real deps via vcpkg | Hidden base preset, not used directly. Requires VCPKG_ROOT in the environment; every preset below inherits it. |
m1-dev |
build/m1-dev |
real deps | The one you actually want. Despite the name, this is the live development preset for everything from M1 onward — M1, M2, and M3 were all built, tested, and manually verified against build/m1-dev (see PROGRESS.md). Builds tools + tests. |
m2-dev |
build/m2-dev |
real deps | Cache-identical to m1-dev (same VOICECAT_BUILD_TOOLS=ON, VOICECAT_BUILD_TESTS=ON, same triplet) — the only difference is the binary dir. It exists from when the project briefly split a preset per milestone; that convention was dropped in practice. Use it only if you want a second, isolated build tree (e.g. to compare two branches) — there's no behavioral reason to prefer it over m1-dev. |
(no m3-dev) |
— | — | M3 work used m1-dev directly; no separate preset was ever added for it. If you see m3-dev mentioned anywhere, it doesn't exist — use m1-dev. |
server-release |
build/server-release |
real deps, Release |
Production-shaped build (docs/deployment.md "from source" path): CMAKE_BUILD_TYPE=Release, tools on, tests off. This is what you'd actually ship/run, not what you iterate against. |
So in practice there are really only two presets that matter:
dev— fast no-deps build to confirm the skeleton compiles.m1-dev— everything else: real protocol, real voice, real manual testing.
2. One-time setup for the real-deps presets
m1-dev, m2-dev, and server-release all need VCPKG_ROOT pointing at a bootstrapped
vcpkg checkout:
# 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"
vcpkg.json (manifest mode) pins every dependency (protobuf, mbedTLS, libsodium, asio,
sqlite3, spdlog, opus, miniaudio) — cmake --preset m1-dev resolves and builds them
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)
cmake --preset m1-dev
cmake --build --preset m1-dev
ctest --test-dir build/m1-dev --output-on-failure
(ctest --preset m1-dev is equivalent — both are wired up in CMakePresets.json.) Binaries
land in build/m1-dev/bin/ (.exe suffix on Windows):
build/m1-dev/bin/voicecat-serverbuild/m1-dev/bin/vcclibuild/m1-dev/bin/voicecat-admin
4. Manual testing: server + two clients
Start the server
./build/m1-dev/bin/voicecat-server --name "Test Server" --data-dir ./voicecat-data
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:
# terminal A
./build/m1-dev/bin/vccli --nick Alice --text "hello from Alice"
# terminal B (separate window, after A confirms it sent)
./build/m1-dev/bin/vccli --nick Bob --text "hello from Bob"
Real voice between two clients (needs working mic/speakers, two terminals):
# terminal A
./build/m1-dev/bin/vccli --nick Alice --voice
# terminal B
./build/m1-dev/bin/vccli --nick Bob --voice
Speak into the mic on one side; you should hear it on the other. Ctrl+C to disconnect.
Enumerate audio devices before picking one:
./build/m1-dev/bin/vccli --list-devices
./build/m1-dev/bin/vccli --nick Alice --voice --input-device <ID> --input-mode ptt
Provisioning a non-guest account (if the server was started with --no-guests):
./build/m1-dev/bin/voicecat-admin --data-dir ./voicecat-data account add alice --password secret
./build/m1-dev/bin/voicecat-admin --data-dir ./voicecat-data account list
5. server-release (production-shaped build)
Same dependency story, but Release build type and no tests — this is the closest local
analogue to what docs/deployment.md's "from source" path produces:
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 day-to-day development, since it has no test target wired up.