Build Cadmus on Native Hosts (Linux / macOS)

SkillProductivity

Build Cadmus on Linux and macOS hosts using xtask. Use when asked how to compile, test, lint, or run the project locally.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Build Cadmus on Native Hosts (Linux / macOS) skill

What this skill tells your AI

The instructions your AI receives, as published by ogkevin/cadmus in .agents/skills/build-cadmus-native/SKILL.md and read by ahel’s review.

Critical prerequisite: generate the documentation EPUB

cadmus-core embeds the user documentation at compile time via rust-embed. The macro points to docs/book/epub/Cadmus Documentation.epub. If that file is missing, every cargo check, cargo build, or cargo test that touches cadmus-core will fail with:

error: #[derive(RustEmbed)] folder '…/docs/book/epub/' does not exist.
error[E0599]: no associated function named `get` found for struct `DocumentationAssets`

Generate the EPUB

cargo xtask docs --mdbook-only

This installs mdBook and mdbook-epub (if missing), builds the mdBook sources, and writes docs/book/epub/Cadmus Documentation.epub. You only need to rerun it when documentation sources change.

One-time setup

Custom SQLite

Required before any native compilelibsqlite3-sys runs before cadmus-core's build.rs, so the UDL-enabled SQLite library must already exist:

cargo xtask setup

Default (no flags) builds for the host and Kobo targets.

Runtime assets

Required for Kobo builds — run both before cargo xtask build-kobo:

cargo xtask download-assets
cargo xtask download-fonts

download-assets pulls Plato runtime directories (bin/, resources/, hyphenation-patterns/). download-fonts assembles the fonts/.

Other native dependencies (MuPDF, libwebp, and the C wrapper) are built automatically by build.rs when you run any Cargo command that compiles cadmus-core. SQLite is the exception — use cargo xtask setup first.

Daily workflow commands

GoalCommand
Check formattingcargo xtask fmt
Run clippycargo xtask clippy
Run tests (emulator features)cargo xtask test --features emulator
Run tests with coveragecadmus-test-coverage --features emulator (devenv)
View coverage (project-wide)cadmus-coverage-show (after test-coverage)
View coverage (patch diff)cadmus-coverage-diff (after test-coverage)
Run tests with telemetrycargo xtask test --features "emulator + profiling + test + tracing"
Run the emulatorcargo xtask run-emulator (builds the EPUB first if missing)
Install the importer CLIcargo xtask install-importer
Build docs portal (full)cargo xtask docs

A device feature is required

cadmus-core emits compile_error!("A device feature must be enabled") (crates/core/src/lib.rs) unless one of emulator, kobo, or deviceless is enabled. The merged cadmus crate has default = [], so plain cargo build, --features default, and cargo xtask test --features default all fail. For native host development use emulator (what run-emulator uses); use kobo only via the build-kobo skill (it cross-compiles for ARM).

Testing locally

The full feature matrix is large and slow. Run the complete matrix only in CI. Locally, test the feature combination you are actively working with — every combination must include a device feature:

# Emulator device feature — fastest, covers most code
cargo xtask test --features emulator

# Add the feature you are modifying on top of a device feature
cargo xtask test --features "emulator + profiling + test + tracing"

[!NOTE] The telemetry feature is excluded from the xtask matrix because it aliases tracing + profiling with no separate cfg branches. Use the expanded form (emulator + profiling + test + tracing) instead.

Use cargo xtask ci matrix to see all available feature combinations if you need to verify a specific one.

Coverage locally

In a devenv shell (cadmus-test-coverage, cadmus-coverage-show, cadmus-coverage-diff):

cadmus-test-coverage
cadmus-coverage-show
cadmus-coverage-diff

Without devenv:

cargo xtask test --coverage --features emulator

This writes target/coverage/lcov.info. Project HTML uses cargo llvm-cov report --html. Patch HTML uses diff-cover (see devenv.nix scripts).

What the xtask wrappers do

  • fmt — runs cargo fmt --check (or --apply in CI) across the workspace
  • clippy — iterates the full feature matrix; use --features to narrow it
  • test — iterates the test feature matrix; --coverage enables llvm-cov instrumentation
  • run-emulator — ensures the documentation EPUB exists, then runs cargo run -p cadmus --features emulator
  • install-importer — runs cargo install --path crates/importer

Common mistakes

MistakeResultFix
Running cargo check before cargo xtask docs --mdbook-onlyRustEmbed folder-not-found errorGenerate the EPUB first
Running bare cargo clippy / cargo test directlyMay miss feature-gated code or use wrong feature combinationsPrefer cargo xtask clippy and cargo xtask test
Running cargo xtask test without --featuresRuns the full (slow) CI matrix locallyPass --features emulator (or kobo/deviceless) plus any specific combo you need
Running cargo build / cargo test without a device featurecompile_error!("A device feature must be enabled") in cadmus-corePass --features emulator (or kobo/deviceless)

Platform notes

  • Linux: Native dependencies are built from source automatically via build.rs; ensure gcc, make, cmake, and standard build tools are installed.
  • macOS: Native dependencies are built from source automatically via build.rs; Xcode Command Line Tools must be installed. Full support including Kobo cross-compilation.
  • The build-kobo command cross-compiles for ARM and is available on both Linux and macOS; it runs inside a containerised CI action in the main workflow.

Signals

GitHub stars
44
Forks
10
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
build-cadmus-native
Source
github.com/ogkevin/cadmus