crabidy/docs/src/build-features.md

7.9 KiB

Tailored builds

Every provider, Opus decoding, the spectrum bars, the embedded web UI and the TUI's two desktop integrations sit behind a Cargo feature. All of them are on by default, so a plain cargo build gives you the full player. Turning some off gives you a smaller binary that pulls fewer dependencies — useful for a single-purpose box (a Raspberry Pi playing a local flac collection) or a build environment you want to keep lean.

This is the compile-time half of provider selection. The runtime half — the providers list in crabidy-server.toml — still works exactly as before; see Configuration. The two compose in one direction: a provider that is not compiled in cannot be enabled in the config, and if you name one anyway the server logs a warning and carries on.

What this build has

crabidy-server features   # or: cbd features

prints one feature per line — the providers it can mount, then the extras. The same list goes into the server's startup log, so a support question ("why is /tidal missing?") is answerable from the binary and its log.

The features

Feature Turning it off drops
tidal the /tidal provider (tidaldy)
youtube the /youtube provider (ytdy, and with it rustypipe)
fyyd the /fyyd podcast provider
abs the /abs audiobookshelf provider
soundcloud the /soundcloud provider
jamendo the /jamendo provider
rss the /rss podcast-subscription provider
fs local files and persistent state — see below
opus Ogg-Opus decoding (symphonia + libopus)
opus-bundled compiling libopus; links the system copy instead
spectrum the server-side FFT feeding clients' spectrum bars
web-ui the embedded web client (tonic-web + the wasm bundle)

Plus all-providers, which enables the eight provider features at once, and the TUI's two desktop features — notifications and mpris (below). cbd (the bundle) mirrors all of them.

notifications and mpris

Both belong to cbd-tui and both are on by default; both put the client on the session bus, and neither costs the server anything.

Feature Turning it off drops
notifications the desktop "now playing" popups (notify-rust)
mpris the MPRIS player: media keys, status bars

mpris publishes the MPRIS2 interfaces so the XF86Audio* keys and status-bar modules drive the server — see Terminal UI. It costs one crate (mpris-server) and no system library: the zbus underneath it speaks D-Bus in pure Rust, and notify-rust already brought it in. Drop it for a client on a machine with no desktop session; it also stands down by itself when there is no session bus to sit on, so a client over ssh needs no separate build.

fs is more than /fs

The /fs provider, the content store, and everything built on it are all written against the same crate, so they share one feature. With fs off you lose:

  • the /fs mount (your local music folder);
  • /crabidy — saved queues, bookmarks (w) and captures (W);
  • /orphans, which is a view over the store;
  • queue persistence: the queue lives in memory, so a restart starts empty;
  • the scan command (it fails with a message naming the feature);
  • captured-track markers in library listings.

The capture and save-queue RPCs answer Unimplemented on such a server, so clients report an ordinary error instead of hanging.

If you want /fs but not /crabidy, keep the feature and prune the providers list at runtime instead — that is what it is for.

opus and where libopus comes from

symphonia (and so rodio) has no Opus decoder, so Ogg-Opus files are decoded through libopus. Turning opus off removes the crates, the library, and the C build with them.

opus-bundled picks which libopus. It is on by default, so a plain cargo build compiles the vendored source and needs cmake and a C compiler but nothing installed. Drop it — --no-default-features --features …,opus — and the build links the system libopus instead:

# a distribution build: Opus decoding, no vendored C build
cargo build --release -p crabidy-server \
  --no-default-features --features all-providers,opus,spectrum,web-ui

That is what this repo's Nix package does, taking libopus from nixpkgs. The build script emits a bare -lopus and leaves the search path to the linker (the bindings are pregenerated, so no headers are needed); point OPUS_LIB_DIR at the directory holding the library if the linker does not find it on its own, as the dev shell does. The aarch64 cross build keeps opus-bundled, because a static binary needs a static libopus for the target and compiling the vendored copy is the way to get one.

opus-bundled without opus does nothing at all — it only chooses a source for a library the opus feature decides to use.

The opus feature also decides whether scan treats .opus files as playable at all, so a build that cannot decode Opus will not index Opus files either. An Opus file that reaches such a build fails to decode with a message naming the missing feature and is skipped, exactly like any unplayable file.

spectrum and web-ui

spectrum only affects the server: with it off no frames are computed or broadcast, and clients simply show no bars — nothing else changes, and no client needs rebuilding. web-ui drops the embedded browser client; the gRPC service on port 50051 still serves cbd-tui and the CLI.

Examples

A local-files appliance — no network providers, no web UI, no FFT:

cargo build --release -p crabidy-server \
  --no-default-features --features fs,opus

A streaming box with the browser client and the bars, no local library:

cargo build --release -p crabidy-server \
  --no-default-features --features tidal,web-ui,opus,spectrum

The bundle, tailored the same way (its features forward to the server):

cargo build --release -p cbd --no-default-features --features fs,opus

A terminal client with no D-Bus dependency at all — no popups, no media keys:

cargo build --release -p cbd-tui --no-default-features

Or one that keeps the media keys and drops the popups:

cargo build --release -p cbd-tui --no-default-features --features mpris

--no-default-features on its own is legal and compiles: you get a server that starts, serves an empty library and plays nothing. It is the base case the feature matrix checks, not a useful deployment.

What is not behind a feature

  • Authorization. [auth] and its password hashing always ship. A build that ignored configured role hashes would silently run an intended-to-be-locked server open — a fail-open hole not worth a small dependency.
  • Audio output. The server is the player; a server without audio has no purpose.
  • HLS streaming and the spectrum tap. They bring no dependencies of their own, so gating them would add build complexity and save nothing.

Checking combinations

devenv shell -- check-features runs the curated matrix — defaults, no features, each provider alone, each extra dropped, both examples above, and the client crates — and requires every one to be clippy-clean. The two libopus variants are built, not just checked: clippy links nothing, so only a real build can tell a resolvable -lopus from a missing one. Run it after changing anything that sits behind a feature.