Skip to content

Build System & CI

CMake build configuration, CI/CD pipeline, and release process for QS-Bridge.


CMake Build System

The bridge uses CMake 3.20+ with C++17. The build produces a single shared library from 5 static library layers.

Build Layers

# Layer 1 — BSATN codec (no dependencies)
add_library(bsatn_core STATIC
    # Header-only, but we create a target for dependency tracking
)
target_include_directories(bsatn_core PUBLIC include/)

# Layer 2 — SpacetimeDB client
add_library(stdb_client STATIC
    lib/core/websocket_client.cpp
)
target_link_libraries(stdb_client PUBLIC bsatn_core websockets)

# Layer 3 — Bridge core
add_library(bridge_core STATIC
    lib/core/engine_adapter.cpp
    lib/core/game_interface.cpp
    lib/core/rpc_dispatcher.cpp
    lib/core/class_registry.cpp
    lib/core/game_action.cpp
)
target_link_libraries(bridge_core PUBLIC stdb_client)

# Layer 4 — UE4 engine adapter
add_library(engine_ue4 STATIC
    lib/engines/ue4/entry.cpp
    lib/engines/ue4/introspection.cpp
    lib/engines/ue4/vtable_hook.cpp
    lib/engines/ue4/fname_cache.cpp
)
target_link_libraries(engine_ue4 PUBLIC bridge_core)

# Layer 5 — HumanitZ game module
add_library(game_humanitz STATIC
    games/humanitz/src/hz_game.cpp
    games/humanitz/src/hz_rpcs.cpp
    games/humanitz/src/hz_client_rpcs.cpp
    games/humanitz/src/hz_position_sampler.cpp
    games/humanitz/src/hz_spatial.cpp
    games/humanitz/src/hz_replication.cpp
    games/humanitz/src/hz_actor_registry.cpp
)
target_link_libraries(game_humanitz PUBLIC engine_ue4)

# Final shared library (--whole-archive to preserve LD_PRELOAD constructor)
add_library(qsbridge SHARED)
target_link_libraries(qsbridge PRIVATE
    -Wl,--whole-archive
    game_humanitz engine_ue4 bridge_core stdb_client bsatn_core
    -Wl,--no-whole-archive
)
set_target_properties(qsbridge PROPERTIES OUTPUT_NAME "qsbridge")

Build Commands

# Configure
cmake -B build -DCMAKE_BUILD_TYPE=Release

# Build
cmake --build build -j$(nproc)

# Output: build/libqsbridge.so (8.6 MB)

Build Options

Option Default Description
CMAKE_BUILD_TYPE Debug Debug, Release, RelWithDebInfo
QSB_BUILD_TESTS ON Build test suites
QSB_ENABLE_ASAN OFF Address sanitiser (debug only)
QSB_TARGET_ENGINE ue4 Target engine adapter

Dependencies

Library Version Purpose Install
libwebsockets 4.3+ WebSocket client apt install libwebsockets-dev
OpenSSL 3.0+ TLS, HMAC-SHA256 apt install libssl-dev
Catch2 v3 Test framework Fetched via CMake FetchContent

Test Build

# Build with tests
cmake -B build -DQSB_BUILD_TESTS=ON
cmake --build build -j$(nproc)

# Run all tests
cd build && ctest --output-on-failure

# Run specific suite
./build/test_table_roundtrip
./build/test_integration_pipeline

CI/CD Pipeline

GitHub Actions (.github/workflows/ci.yml)

4 parallel jobs:

jobs:
  bridge-build:
    runs-on: ubuntu-24.04
    steps:
      - uses: actions/checkout@v4
      - run: sudo apt install -y libwebsockets-dev libssl-dev
      - run: cmake -B build -DQSB_BUILD_TESTS=ON
      - run: cmake --build build -j$(nproc)
      - run: cd build && ctest --output-on-failure

  panel-build:
    runs-on: ubuntu-24.04
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: '22' }
      - run: cd panel/ui && npm ci && npm run build

  gateway-build:
    runs-on: ubuntu-24.04
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: '22' }
      - run: cd panel/api && npm ci && npm run typecheck

  panel-lint:
    runs-on: ubuntu-24.04
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: '22' }
      - run: cd panel/ui && npm ci && npx eslint src/

CI Checks

Job Time Checks
bridge-build ~3 min CMake build (0 warnings), 860+ test assertions
panel-build ~1 min Vite production build, TypeScript strict check
gateway-build ~30s TypeScript type check
panel-lint ~30s ESLint rules

Release Process

# 1. Update version in CMakeLists.txt
set(QSB_VERSION "0.2.0")

# 2. Update PLAN.md summary statistics

# 3. Build and test
cmake -B build -DCMAKE_BUILD_TYPE=Release -DQSB_BUILD_TESTS=ON
cmake --build build -j$(nproc)
cd build && ctest --output-on-failure

# 4. Build panel
cd panel/ui && npm ci && npm run build

# 5. Commit, tag, push
git add -A
git commit -m "release: v0.2.0"
git tag v0.2.0
git push && git push --tags

# 6. Deploy
scp build/libqsbridge.so vps:/opt/qs-bridge/
scp -r panel/ui/dist/ vps:/opt/qs-bridge/panel/ui/
ssh vps "sudo systemctl restart qs-gateway"

Codegen

tools/codegen.py (809 lines) generates C++ BSATN types from UE4 property definitions:

# Generate/update schema headers
python3 tools/codegen.py \
  --input games/humanitz/bindings.json \
  --output games/humanitz/schema/

# Output: 218 header files
#   111 reducer headers  (schema/reducers/)
#   58  type headers      (schema/types/)
#   44  table headers     (schema/tables/)
#   5   top-level headers (all_*.h, table_dispatch.h, table_names.h)