Skip to content

Repository files navigation

rpi_rust_template

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.md describing how to build and deploy that specific application.

What you get

A ready-to-use Rust binary project with:

  • Cross-compilation for aarch64-unknown-linux-gnu via cross + Docker
  • Build scriptsbuild.sh (Linux/macOS) and build.ps1 (Windows)
  • Deploy scriptsdeploy.sh / deploy.ps1 that SCP the binary to your Pi
  • Release profile tuned for small binaries (opt-level="s", LTO, strip)
  • env_logger starter in src/main.rs
  • Optional SLINT GUI — when enabled, includes a ui/main.slint starter, 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

Prerequisites (for using this template)

cargo install cargo-generate
cargo install cross --git https://github.com/cross-rs/cross
# Docker must be installed and running

Usage

From a local path

cargo generate --path /path/to/rpi_rust_template --vcs none

From GitHub

cargo generate --git https://github.com/FrenchPOC/rpi_rust_template --vcs none

You'll be prompted for the values below. You can also pass them with -d key=value in --silent mode.

Placeholders

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.

Template layout

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

How the two-README mechanism works

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.

How the SLINT conditional works

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).

Customizing the cross image

The default cross Docker image depends on whether SLINT is included:

  • Without SLINT: ghcr.io/cross-rs/aarch64-unknown-linux-gnu:edge (the :edge tag 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).

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages