- StereoRectifier wrapping cv::stereoRectify + cv::initUndistortRectifyMap (CV_16SC2 maps) - PointCloudBuilder with cv::reprojectImageTo3D and depth/NaN filtering - CloudPointClient high-level facade: connect(), compute_cloud() -> std::expected<PointCloud, Error> - write_ply() ASCII PLY export helper - CLI options 4 (compute-cloud) and 5 (compute-cloud + save PLY) - Fix TcpServer to loop over multiple requests per connection - Expose num_disparities parameter through CloudPointClient and StereoMatcherFactory - Unity C# integration design spec - Sync README, AGENTS, openwiki with stereo pipeline (C++23) - E2E synthetic-scene test with constant-disparity stereo pair TG-9 #ready-for-test TG-4 #ready-for-test TG-2 #in-progress
6.8 KiB
Build & Testing
Build system
The project uses Meson with Ninja and requires a C++23 compiler (GCC or Clang). The root meson.build declares the project and dependencies; src/meson.build and tests/meson.build define build targets.
Dependencies
All dependencies are resolved via Meson wrap files in subprojects/ or system packages:
| Dependency | Wrap file | Purpose |
|---|---|---|
| nlohmann_json | nlohmann_json.wrap |
JSON parsing |
| asio | asio.wrap |
TCP networking (header-only) |
| glog | glog.wrap (CMake subproject) |
Logging |
| yaml-cpp | yaml-cpp.wrap |
Config file parsing |
| aklomp-base64 | aklomp-base64.wrap |
Base64 encode/decode |
| GoogleTest | gtest.wrap |
Unit testing (gtest + gmock) |
The rpc/ directory is a git submodule pointing to json-rpc-cxx, providing jsonrpccxx/ headers used by the client. It is included via include_directories in the root meson.build.
Build targets
Defined in src/meson.build:
Shared libraries:
| Library | Sources | Notes |
|---|---|---|
libcloud_point_rpc |
rpc_coder.cpp, rpc_server.cpp, server_api.cpp, service.cpp |
Core library, installed with install_rpath: '$ORIGIN' |
libcloud_point_rpc_cli |
cli.cpp |
CLI client logic |
test_cloud_point |
test_api.cpp |
Test API library |
Executables:
| Executable | Source | Description |
|---|---|---|
cloud_point_rpc_server |
server_main.cpp |
Standalone mock server |
cloud_point_rpc_cli |
main.cpp |
Interactive CLI client |
minimal_client |
minimal_client.cpp |
Minimal client sending a hardcoded ping |
Linux build
git submodule init && git submodule update
meson setup build
meson compile -C build
Run the server:
./build/src/cloud_point_rpc_server config.yaml
Run the CLI client:
./build/src/cloud_point_rpc_cli config.yaml
Windows build
Windows requires static linking and a Python venv for Meson:
git submodule init
git submodule update
python3 -m venv .\venv
.\venv\Scripts\Activate.ps1
pip install meson cmake
meson setup -Ddefault_library=static build
meson compile -C build
# To get DLLs on PATH:
meson devenv -C build
The root meson.build adds a devenv on Windows that appends subproject DLL directories to PATH when default_library=shared. When building static, the build defines BASE64_STATIC_DEFINE and YAML_CPP_STATIC_DEFINE.
Clean build
meson compile --clean -C build
Configuration
The server reads a YAML config file. Sample: config.yml:
server:
ip: "127.0.0.1"
port: 9095
Full config schema (parsed by ConfigLoader in include/cloud_point_rpc/config.hpp):
| Section | Field | Type | Default | Description |
|---|---|---|---|---|
server.ip |
string | 127.0.0.1 |
Server bind address | |
server.port |
int | 8080 |
Server listen port | |
test_data.intrinsic_params |
list of double | empty (fallback to identity 3×3) | Camera intrinsic parameters | |
test_data.extrinsic_params |
list of double | empty (fallback to identity 4×4) | Camera extrinsic parameters | |
test_data.cloud_point |
list of lists of double | empty (fallback to 3 sample points) | Point cloud data |
The test_data section is only used by the standalone mock server (server_main.cpp). The C API path (crpc_init) loads config for server address but does not use test_data — Unity provides its own handlers.
Docker
The Dockerfile uses Ubuntu 24.04 and builds the CLI client. It installs build dependencies, copies the project, runs meson setup build && meson compile -C build, and starts the CLI by default.
docker build -t cloud-point-rpc .
docker run --network=host -it cloud-point-rpc
Mount a custom config:
docker run --network=host -it -v $(pwd)/my_config.yaml:/app/config.yaml cloud-point-rpc
The server is not configured to run inside Docker — only the CLI client. The
--network=hostflag simplifies connectivity to a server running on the host.
CI
.gitea/workflows/test.yaml defines a Gitea Actions workflow named "Verification" that runs on push to master:
- Install build tools (cmake, make, ninja, gcc)
- Install Meson via pip in a venv
- Checkout with submodules
meson setup build && meson compile -C build -j2meson test -C build
Testing
All tests are in tests/ and compiled into a single unit_tests executable (defined in tests/meson.build) linked against cloud_point_rpc_dep, cloud_point_rpc_cli_dep, cloud_point_rpc_test_dep, and GoogleTest/GMock.
Run tests
meson test -C build # all tests
meson test -C build -v # verbose
meson test -C build unit_tests # explicit
Test suites
| File | Area | Description |
|---|---|---|
test_rpc.cpp |
RPC server | Basic request/response, method dispatch |
test_rpc_edge_cases.cpp |
RPC server | Edge cases: invalid JSON, missing fields, non-object requests |
test_tcp.cpp |
TCP server | TCP connection and message round-trip |
test_tcp_edge_cases.cpp |
TCP server | TCP edge cases |
test_integration.cpp |
Integration | Full server+client stack with mock data, real TCP |
test_cli.cpp |
CLI | CLI client menu and output |
test_c_api.cpp |
C API | crpc_test_* functions, callback registration, auto-call |
test_c_api_edge_cases.cpp |
C API | Multiple methods, removal, scheduling |
test_base64.cpp |
Base64 | Encode/decode round-trip |
test_base64_edge_cases.cpp |
Base64 | Edge cases (empty input, binary with nulls) |
test_serialize.cpp |
Serialization | serialize/deserialize for numeric types, inplace_size_embedding |
test_service.cpp |
Service | Default fallbacks, configured data, empty data |
Test conventions
- All test fixtures initialize Google Logging in
SetUp()withFLAGS_logtostderr = true. - Integration tests (
test_integration.cpp) create a temporaryconfig.yaml, start a realTcpServerin a thread, and connect viaTCPConnector/RpcClient. - C API tests use
crpc_test_init()/crpc_test_deinit()and verify callback invocation viastd::promise/std::future. - The latest commit (
9de6f5a) addedgoogle::InitGoogleLoggingcalls in test files to ensure logging is initialized before glog macros are used.
Linting
The project uses clang-format with LLVM base style and 4-space indent (.clang-format):
ninja -C build clang-format
# or
find src include tests -name "*.cpp" -o -name "*.hpp" | xargs clang-format -i
Source references
meson.build— Root build config, dependency declarationssrc/meson.build— Library and executable targetstests/meson.build— Test executable definitionconfig.yml— Sample configDockerfile— Container build.gitea/workflows/test.yaml— CI pipeline.clang-format— Code formatting config