A cargo-generate template
for Rust applications cross-compiled for Raspberry Pi 5 (aarch64, 64-bit).
This README documents the template itself. When you generate a project from this template, the generated project gets its own
README.mddescribing how to build and deploy that specific application.
A ready-to-use Rust binary project with:
- Cross-compilation for
aarch64-unknown-linux-gnuviacross+ Docker - Build scripts —
build.sh(Linux/macOS) andbuild.ps1(Windows) - Deploy scripts —
deploy.sh/deploy.ps1that SCP the binary to your Pi - Release profile tuned for small binaries (
opt-level="s", LTO, strip) env_loggerstarter insrc/main.rs- Optional SLINT GUI — when enabled, includes a
ui/main.slintstarter,build.rs, a SLINT-aware cross Docker image, and a pre-build script that installs the LinuxKMS dependencies inside the container - Optional systemd service file for running the app as a background service
- A templated README documenting build, deploy, and service setup
cargo install cargo-generate
cargo install cross --git https://github.com/cross-rs/cross
# Docker must be installed and runningcargo generate --path /path/to/rpi_rust_template --vcs nonecargo generate --git https://github.com/FrenchPOC/rpi_rust_template --vcs noneYou'll be prompted for the values below. You can also pass them with -d key=value
in --silent mode.
| Placeholder | Type | Default | Description |
|---|---|---|---|
deploy_ip |
string (regex) | required | Raspberry Pi host (IP address or hostname, e.g. 192.168.1.50 or poste.local), baked into the deploy scripts |
remote_user |
string | pi |
SSH username on the Pi (also sets the remote path /home/<user>/dev/) |
description |
string | Rust application for Raspberry Pi 5 (aarch64) |
Goes into Cargo.toml [package].description |
cross_image |
string | conditional | Docker image used by cross (written to Cross.toml). Defaults to ghcr.io/cross-rs/aarch64-unknown-linux-gnu:edge without SLINT, or ghcr.io/slint-ui/slint/aarch64-unknown-linux-gnu:latest with SLINT |
include_systemd |
bool | true |
If true, generates a {% raw %}{{crate_name}}{% endraw %}.service file + a systemd section in the README |
include_slint |
bool | false |
If true, adds SLINT dependencies, build.rs, ui/main.slint, the SLINT cross image, and a pre-build script for LinuxKMS deps |
slint_version |
string | 1.16.1 |
SLINT crate version (only prompted when include_slint=true). Sets both [dependencies] and [build-dependencies] |
Builtin placeholders (project-name, crate_name, authors) are provided by
cargo-generate automatically.
rpi_rust_template/
├── cargo-generate.toml # placeholders, hooks, conditional config
├── README.md # this file (template-repo docs)
├── README.md.liquid # generated-project README (overwrites README.md in output)
├── Cargo.toml # crate manifest template (conditional slint deps)
├── Cross.toml # cross Docker image config (conditional pre-build)
├── .cargo/config.toml # aarch64 linker + pkg-config
├── build.sh / build.ps1 # cross-compile scripts
├── deploy.sh / deploy.ps1 # SCP deploy scripts
├── src/main.rs # entry point (env_logger + optional SLINT UI init)
├── build.rs # slint-build compile (ignored when include_slint=false)
├── ui/main.slint # SLINT UI starter (ignored when include_slint=false)
├── scripts/cross-pre-build.sh # installs SLINT cross deps (ignored when include_slint=false)
├── {% raw %}{{crate_name}}{% endraw %}.service # systemd unit (removed when include_systemd=false)
└── post-systemd.rhai # post-hook: removes service file if not wanted
README.md is this file — it stays in the template repo so GitHub renders it
here. README.md.liquid is the generated-project readme; cargo-generate
processes its placeholders and renames it to README.md, overwriting this file
in the generated output. So:
- Template repo (here): you see this README.
- Generated project: the user sees their application-specific README.
When include_slint=false (the default), the files build.rs, ui/, and
scripts/ are listed in a conditional ignore block and are excluded from the
generated output entirely. Cargo.toml, Cross.toml, and src/main.rs use
Liquid {% raw %}{% if include_slint %}{% endraw %} blocks to include or exclude
SLINT-specific dependencies, the pre-build script, and the UI initialization
code. The cross_image placeholder also gets a different default depending on
this choice (see the Placeholders table above).
The default cross Docker image depends on whether SLINT is included:
- Without SLINT:
ghcr.io/cross-rs/aarch64-unknown-linux-gnu:edge(the:edgetag provides newer packages suitable for the Pi 5) - With SLINT:
ghcr.io/slint-ui/slint/aarch64-unknown-linux-gnu:latest(includes the toolchain and libraries needed for SLINT's LinuxKMS backend)
Override it at generation time:
cargo generate --git https://github.com/FrenchPOC/rpi_rust_template -d cross_image=...When SLINT is enabled, a pre-build script (scripts/cross-pre-build.sh)
runs inside the container before each build to install the cross-compiled
LinuxKMS dependencies (libudev, libinput, libdrm, libgbm, libxkbcommon,
libfontconfig1). If you need additional system libraries, add them to that
script (see the cross docs).