Build

Install and compile Sqyre from source. For action types and screenshots, see Features. For using the GUI, see Docs.

The sections below are synced from the Sqyre application repository so build steps stay in one place.

Build (quick start)

Recommended: open the repo in the dev container — Rust, Tesseract/Leptonica, and X11 link deps are preinstalled.

GoalCommand
Linux binary (default)make / make sqyre./bin/sqyre
Run without installingmake run
Release binarymake release
Windows / macOS nativemake windows./bin/sqyre.exe (Docker cross on Linux) · make macos./bin/sqyre
AppImagemake appimage
Testsmake test
README screenshotsmake docs-media
Tesseract data (dev fallback)make tessdata

Override with CARGO_FLAGS=....

More detail — workspace layout, host setup, packaging — is in Developing, docs/RUST.md, and docs/README.md.


Run

After building, launch ./bin/sqyre (Linux) or ./bin/sqyre.exe (Windows). For creating and running macros, see Docs.

Developing (extended)

Developing Sqyre

Open the repository in the dev container (.devcontainer/). It includes Rust 1.92, clang, Tesseract/Leptonica, X11 link deps, AppImage packaging tools (appimage-builder, squashfs-tools), Trunk + wasm32-unknown-unknown (for make wasm), and the Docker CLI (host daemon via socket) so make windows and AppImage Docker fallbacks work inside the container.

Nested docker run -v mounts use the host path via LOCAL_WORKSPACE_FOLDER (${localWorkspaceFolder}). Rebuild the container after pulling that change so the env var is set.

From the repo root:

make            # ./bin/sqyre (debug)
make release    # fmt + check, then ./bin/sqyre (release)
make run        # cargo run -p sqyre-app
make check      # fmt --check + clippy (-D warnings) + cargo deny
make machete    # unused crate deps
make test       # cargo nextest (falls back to cargo test)
make coverage   # llvm-cov HTML + lcov under target/coverage/
make docs-media # regenerate docs/images screenshots
make appimage   # fmt + check, then bin/*.AppImage (Linux)
make windows    # fmt + check, then bin/sqyre.exe (Docker MinGW cross / native on Windows)
make macos      # fmt + check, then bin/sqyre (macOS host)
make wasm       # fmt + check, then bin/wasm/ GUI-only browser editor (Trunk)
make tessdata   # download eng.traineddata into assets/tessdata/

Run make help for the full target list. Workspace layout: RUST.md.

Build caches (all gitignored):

PathRole
target/Incremental compile artifacts (host + docker bind-mount; Windows under target/x86_64-pc-windows-gnu/)
.cargo-home/Optional workspace-local cargo/rustup install
.cache/cargo/Cargo registry/git cache used by CI and docker AppImage / Windows builds
.cache/sccache-windows/sccache rustc cache for make windows (Linux/CI bind mount)
Docker volumes sqyre-windows-*Windows cross cargo/target/sccache when the repo is on a Docker Desktop Windows path
Dev container volume sqyre-cargo-homePersistent /home/vscode/.cargo in the container

make appimage via Docker reuses CARGO_HOME when Make exports .cargo-home, otherwise .cache/cargo. make windows defaults to CARGO_INCREMENTAL=1; on Docker Desktop it stores cargo caches in Linux volumes (bind-mounted target/ on a Windows host path is very slow). CI uses SQYRE_WINDOWS_SCCACHE=1 instead. See scripts/windows/PACKAGING.md.


Make targets

TargetOutput
all / sqyrebin/sqyre (debug) — default
releasebin/sqyre (release)
check-fmtcargo fmt --all -- --check
fmtcargo fmt --all (write)
clippycargo clippy --workspace --all-targets (-D warnings)
denycargo deny check (licenses / advisories / bans / sources)
machetecargo machete (unused dependencies)
checkcheck-fmt + clippy + deny (CI quality gates)
testcargo nextest run --workspace (falls back to cargo test)
coveragellvm-cov HTML + lcov.info under target/coverage/ (no % gate)
runcargo run -p sqyre-app
docs-mediaRegenerate images/sqyre/ screenshots
appimagebin/Sqyre-*.AppImage
windowsbin/sqyre.exe (Docker MinGW cross on Linux; native on Windows)
macosbin/sqyre (release; macOS host only)
wasmGUI-only browser editor → bin/wasm/ (Trunk; no Run/capture/OCR)
tessdataTesseract trained data via scripts/download-tessdata.sh

Set CARGO_FLAGS for extra cargo args. Set RELEASE_VERSION (or write a VERSION file) before make appimage / make release / make windows to stamp the AppImage name and embed SQYRE_VERSION in the binary for auto-update checks. Local builds without either default to 0.0.0-dev (update checks disabled).

WASM editor (make wasm)

Browser-only macro editor (import/export db.yaml). Does not run automation. The dev container already has Trunk and the wasm32-unknown-unknown target — rebuild the container after pulling those Dockerfile changes, then:

make wasm          # → bin/wasm/index.html  (deployable; use this, not trunk serve's dist)
cd crates/sqyre-app && env -u NO_COLOR trunk serve   # local preview + reload only

Serve the release output with any static file server (python3 -m http.server from bin/wasm/, etc.). Do not copy dist/ from a running trunk serve — that injects an unreplaced autoreload WebSocket stub and floods the console. On a bare host (no container), install once:

rustup target add wasm32-unknown-unknown
cargo install --locked trunk

Uses --no-default-features (no global hotkey hooks). Native make / make release are unchanged.

CI and GitHub Releases

Push/PR to main runs tests and a macOS cargo check (capture still stubbed) — not a GitHub Release.

Releases come from .github/workflows/main.yml on schedule or manual dispatch only:

TriggerWhen
CronDaily at 23:00 UTC (0 23 * * *)
ManualActions → Build and Release → Run workflow, or gh workflow run "Build and Release" --ref main

The version job sets should_release=true only when there is no prior v* tag, or main has changed since the latest v* tag excluding docs/** and *.md. Docs-only / markdown-only changes do not publish. If nothing releasable changed, release jobs are skipped.

Tag shape: vYYYY.MM.DD (UTC date). If that tag already exists, CI uses vYYYY.MM.DD.HHMM.

Artifacts: Linux binary + AppImage, Windows .exe (MinGW cross via scripts/windows/), and the WASM editor zip (make wasm). make macos stays native; MSI/DMG packaging is not shipped yet.

Shipped Linux/Windows builds embed SQYRE_VERSION so the in-app updater can compare against GitHub Releases (local 0.0.0-dev builds skip update checks).

CI caches: Linux Docker Buildx (GHA + GHCR), Windows cross-image Buildx + pushed *-windows-cross:latest image, Cargo registry/target (per job), Windows sccache, and tessdata; macOS Homebrew bottles + split Cargo caches.


Native dependencies

ResourcePurpose
.devcontainer/DockerfileRust + Tesseract + AppImage tools + Trunk/wasm32
.devcontainer/devcontainer.jsonDocker-outside-of-Docker (CLI + host socket) for make windows
scripts/windows/DockerfileMinGW cross image for make windows on Linux
crates/sqyre-app/assets/icons/Brand icons (embedded SVG)
assets/tessdata/Optional local eng.traineddata fallback

OCR uses system tessdata when available, or SQYRE_TESSDATA / assets/tessdata when developing.


Manual setup (without dev container)

Prefer the container when possible. Needs Rust ≥ 1.92, clang, Tesseract/Leptonica, and X11 libs (libx11-dev, libxtst-dev, …). See RUST.md.

make            # or: cargo build -p sqyre-app
./bin/sqyre

For AppImage on the host, also install appimage-builder, patchelf, and squashfs-tools.


Tests

make test
# or: cargo test

Headless CI uses Null* backends / stub hotkeys where hooks are unavailable.

README screenshots

In-memory egui goldens live under images/sqyre/ (test: cargo test -p sqyre-app --test docs_screenshots).

make docs-media
# or: SQYRE_UPDATE_SCREENSHOTS=1 ./scripts/generate-docs-media.sh

Needs wgpu (lavapipe in the dev container / CI image).


Packaging

See scripts/linux/packaging/PACKAGING.md for AppImage builds.