Development Environment Setup
Cadmus uses devenv with Nix to provide a reproducible development environment. This guide covers setup on both Linux and macOS.
Prerequisites
- Install Nix with flakes enabled. The easiest way is using the Determinate Nix Installer.
- Install devenv.
Quick Start
-
Clone the repository and enter the devenv shell:
git clone https://github.com/OGKevin/cadmus.git cd cadmus devenv shell -
Run the one-time setup to build native dependencies:
cadmus-setup-native -
Run the emulator:
./run-emulator.sh
Available Commands
Once inside the devenv shell, these commands are available:
| Command | Description |
|---|---|
cadmus-setup-native | Build MuPDF for native development (run once) |
cargo test | Run the test suite |
./run-emulator.sh | Run the emulator |
cadmus-build-kobo | Build for Kobo device (Linux only) |
cadmus-dev-otel | Run emulator with OpenTelemetry instrumentation |
devenv up | Start observability stack (Grafana, Tempo, Loki) |
cadmus-docs-build | Build documentation portal (mdBook + Cargo docs) |
cadmus-docs-serve | Serve documentation portal locally on port 1111 |
Tasks
The devenv environment uses tasks to manage build dependencies.
Tasks are defined in devenv.nix and can be run with devenv tasks run <task>.
Available Tasks
| Task | Description | Dependencies |
|---|---|---|
docs:build | Build documentation EPUB (only rebuilds if files changed) | None |
docs:zola-build | Build documentation portal with mdBook and Cargo docs | None |
deps:native | Build MuPDF and wrapper for native development | None |
build:kobo | Build for Kobo device (Linux only) | docs:build |
How Tasks Work
Tasks with dependencies automatically run their dependencies first. For example:
# This will first run docs:build (if needed), then build for Kobo
devenv tasks run build:kobo
The docs:build task uses execIfModified to only rebuild when documentation files have actually changed.
Documentation Portal
Cadmus provides a unified documentation portal that combines user guides, API reference, and contribution guides in one place.
Building and Serving Locally
To build the documentation portal:
cadmus-docs-build
This runs the full build pipeline:
- Builds the mdBook user guide (
docs/book/html/) - Generates Rust API documentation (
target/doc/) - Builds the Zola landing page and integrates all documentation
To serve the portal locally with live reload:
cadmus-docs-serve
The portal will be available at http://localhost:1111 with automatic rebuilds when you change documentation files or Rust code.
Documentation Structure
The portal provides three integrated sections:
- Landing Page (
/) - Overview and feature highlights - User Guide (
/guide/) - User-facing documentation from mdBook - API Reference (
/api/) - Auto-generated Rust API documentation
All three sections are deployed as a single artifact to GitHub Pages at https://ogkevin.github.io/cadmus/.
Continuous Integration
Documentation is automatically built and validated on every pull request and deployed on push
to main or master. The CI pipeline checks:
- mdBook documentation compiles
- Rust code documentation is valid
- Zola landing page builds successfully
Running Tests
Tests require the TEST_ROOT_DIR environment variable to be set:
TEST_ROOT_DIR=$(pwd) cargo test
This is automatically configured in CI but must be set manually for local testing.
Platform Support
Linux (Full Support)
Linux provides full development capabilities including:
- Native development (emulator, tests)
- Cross-compilation for Kobo devices using the Linaro ARM toolchain
- Git hooks (actionlint, shellcheck, shfmt, markdownlint, prettier)
The Linaro toolchain is automatically added to PATH and provides arm-linux-gnueabihf-* commands.
macOS (Native Development Only)
macOS supports native development but has some limitations:
| Feature | Status | Notes |
|---|---|---|
| Native builds | Supported | Emulator and tests work |
| Cross-compilation | Not supported | Linaro toolchain is Linux-only |
macOS-Specific Notes
Cross-compilation for Kobo: The Linaro ARM cross-compilation toolchain consists of x86_64 Linux ELF binaries that cannot run on macOS. To build for Kobo devices on macOS, use Docker with a Linux container or a Linux VM.
MuPDF build: On macOS, the native setup script manually gathers pkg-config CFLAGS for system libraries because MuPDF’s build system doesn’t properly detect them on Darwin.
Observability Stack
The devenv includes a full observability stack for development:
# Start all services
devenv up
# In another terminal, run the instrumented emulator
cadmus-dev-otel
Services available after devenv up:
| Service | URL | Purpose |
|---|---|---|
| Grafana | http://localhost:3000 | Dashboards and exploration |
| Tempo | http://localhost:3200 | Distributed tracing |
| Loki | http://localhost:3100 | Log aggregation |
| Prometheus | http://localhost:9090 | Metrics |
| OTLP Collector | http://localhost:4318 | Telemetry ingestion |
For more details on telemetry, see OpenTelemetry Integration.
Troubleshooting
Shell takes a long time to start
The first devenv shell invocation downloads and builds dependencies, which can take several
minutes. Subsequent invocations are cached and should be fast.
Tests fail with “TEST_ROOT_DIR must be set”
Set the environment variable before running tests:
TEST_ROOT_DIR=$(pwd) cargo test
Local Configuration
Create devenv.local.nix to override settings without modifying the tracked configuration:
{ pkgs, ... }:
{
env = {
# Example: Set TEST_ROOT_DIR automatically
TEST_ROOT_DIR = builtins.getEnv "PWD";
};
}
This file is gitignored and won’t affect other contributors.