Building from Source

All Rust components live in a single Cargo workspace. You can build everything at once or target individual crates.

Workspace layout

broadcaster/
├── Cargo.toml          ← workspace root (resolver = "2")
├── Cross.toml          ← cross-compilation pre-build hooks
├── crates/
│   ├── protocol/       ← shared protocol types (no binary)
│   ├── shiloh-mixer/   ← JACK mix bus + UDP broadcaster
│   ├── shiloh-broadcaster/ ← PipeWire null-sink sender
│   ├── shiloh-relay/   ← UDP audio receiver (listener)
│   ├── shiloh-web-relay/   ← WebRTC/WHEP browser egress
│   └── shiloh-midi-sender/ ← MIDI → mixer bridge (optional)
└── server/
    └── mixer_web/      ← Phoenix LiveView control UI (Elixir)

Required Rust version

The workspace uses the 2021 edition. Check what rustup is using:

rustup show
# Expected: stable-x86_64-unknown-linux-gnu (default)

Install or update the stable toolchain:

rustup update stable

No nightly features are used. Any stable Rust ≥ 1.75 should work.

Building all crates (release)

cargo build --release

Binaries land in target/release/:

target/release/
├── shiloh-mixer
├── shiloh-broadcaster
├── shiloh-relay
├── shiloh-web-relay
└── shiloh-midi-sender

Building a single crate

cargo build --release -p shiloh-mixer
cargo build --release -p shiloh-broadcaster
cargo build --release -p shiloh-relay
cargo build --release -p shiloh-web-relay

Debug builds

Omit --release for a debug build with faster compile times and no LTO:

cargo build -p shiloh-relay
# Binary at: target/debug/shiloh-relay

Debug builds are suitable for development iteration. Do not use them in production — the release profile enables lto = true, codegen-units = 1, opt-level = 3, and strip = true.

Running tests

cargo test

Run tests for a single crate:

cargo test -p shiloh-relay

Cross-compilation for Raspberry Pi (aarch64)

Use cross, which runs the build inside a Docker container with the correct cross toolchain and ALSA headers pre-installed (configured in Cross.toml):

cargo install cross
cross build --release \
    --target aarch64-unknown-linux-gnu \
    -p shiloh-relay

The Cross.toml automatically installs libasound2-dev:arm64 in the build container. No manual sysroot setup is needed.

Output binary: target/aarch64-unknown-linux-gnu/release/shiloh-relay

Copy to the Pi:

scp target/aarch64-unknown-linux-gnu/release/shiloh-relay \
    pi@raspberrypi.local:~/.local/bin/shiloh-relay

NOTE: shiloh-mixer and shiloh-broadcaster require JACK and PipeWire headers and are not practically cross-compiled for aarch64. Only shiloh-relay is routinely deployed on Pi.

Cross-compilation for Windows (x86_64)

Install the MinGW cross toolchain and the Rust Windows target:

sudo apt install mingw-w64
rustup target add x86_64-pc-windows-gnu
cargo build --release \
    --target x86_64-pc-windows-gnu \
    -p shiloh-relay

Output: target/x86_64-pc-windows-gnu/release/shiloh-relay.exe

NOTE: shiloh-web-relay depends on the opus crate which requires the Opus C library headers. Cross-compiling it for Windows requires a MinGW Opus build in the cross toolchain, which is not set up by default. Build shiloh-web-relay natively on Linux only.

Build profiles summary

Profile Command LTO Strip Use case
debug cargo build No No Development / iteration
release cargo build --release Full (fat) Yes Production deployment

Reproducibility

The workspace uses Cargo.lock (checked in) to pin all dependency versions. A cargo build --release on any machine with the same Rust toolchain version should produce bit-for-bit identical binaries (modulo embedded build timestamps).