Skip to content

Configure building Rust project for Raspberry Pi #20

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Mar 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions .github/workflows/run-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ jobs:
defaults:
run:
working-directory: ./pod-operation
env:
TARGET: armv7-unknown-linux-gnueabihf
steps:
- name: Check out repository
uses: actions/checkout@v4
Expand All @@ -75,6 +77,12 @@ jobs:
with:
components: clippy, rustfmt

- name: Add target
run: rustup target add $TARGET

- name: Install target building dependencies
run: sudo apt-get update && sudo apt-get -qq install crossbuild-essential-armhf

- name: Run cargo test
run: cargo test

Expand All @@ -84,5 +92,8 @@ jobs:
- name: Lint pod operation
run: cargo clippy -- -D warnings

- name: Build Pod Operation Program
run: cargo build
- name: Build Pod Operation Program (debug)
run: cargo build --target $TARGET --config target.$TARGET.linker=\"arm-linux-gnueabihf-gcc\"

- name: Build Pod Operation Program (release)
run: cargo build --target $TARGET --config target.$TARGET.linker=\"arm-linux-gnueabihf-gcc\" --release
9 changes: 9 additions & 0 deletions pod-operation/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Configuration to cross-compile for Raspberry Pi
# Uncomment lines as needed

[build]
# target = "armv7-unknown-linux-gnueabihf"

[target.armv7-unknown-linux-gnueabihf]
# linker = "armv7-unknown-linux-gnueabihf-gcc"
# linker = "arm-none-linux-gnueabihf-gcc"
2 changes: 2 additions & 0 deletions pod-operation/Cross.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[build]
default-target = "armv7-unknown-linux-gnueabihf"
90 changes: 86 additions & 4 deletions pod-operation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,102 @@ This Rust package is for the main program to be run on the pod.
The program runs a finite-state machine to operate the pod components
and acts as a Socket.IO server to communicate with the control station.

## Usage

### First-time Setup
## First-time Setup

Install cargo-watch

```shell
cargo install cargo-watch
```

### Local Development
Add the build target for the Raspberry Pi

```shell
rustup target add armv7-unknown-linux-gnueabihf
```

### Cross-Compilation

To compile for the Raspberry Pi target, a specific linker is needed for each operating system,
or [`cross`](https://github.com/cross-rs/cross) can be used to build inside a container.

#### macOS

A Homebrew formula for macOS cross-compiler toolchains is available

```shell
brew tap messense/macos-cross-toolchains
brew install armv7-unknown-linux-gnueabihf
```

#### Windows/Linux

To cross-compile on Windows and Linux, a different compiler toolchain is needed. From the
[Arm GNU Toolchain Downloads](https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads),
download and install the **AArch32 GNU/Linux target with hard float (arm-none-linux-gnueabihf)**
for your operating system.

#### Alternative Building Process With `cross`

An alternative to installing cross-compilers is using `cross` to build and run the Rust project
using containers and emulation. This can be used on any operating system (macOS, Windows, Linux).

**Prerequisites**

First, install [Docker](https://docs.docker.com/). You can either install
Docker Desktop or the more lightweight Docker Engine, which is only available
on Linux distributions.

**Please note that on Linux, non-sudo users need to be in the `docker` group or
use rootless Docker.** You can read more about adding yourself to the group
[here](https://docs.docker.com/engine/install/linux-postinstall/#manage-docker-as-a-non-root-user).

Next, install the `cross` package.

```shell
cargo install cross
```

This is the library that will facilitate cross-compilation with minimal additional configuration.
`cross` requires Docker (or Podman) in order to function and will also emulate the ARM architecture
inside the container using QEMU.

On Linux, if an error appears during build about `GLIBC`, install the `glibc` library.

```shell
# Ubuntu/Debian-based distributions
sudo apt install glibc

# Arch-based distributions
sudo pacman -S glibc
```

## Local Development

To locally run the development server with auto-reload

```shell
cargo watch -x run
```

## Building for Production

Uncomment the arm-linux linker for your operating system in `.cargo/config.toml`.

To build for production, use the `--release` option:

```shell
cargo build --target armv7-unknown-linux-gnueabihf --release
```

Alternatively, use `cross` to compile in a container:

```shell
cross build --release
```

Note: the default target is already specified in `Cross.toml`.

Either approach will compile the project to
`target/armv7-unknown-linux-gnueabihf/release/pod-operation`
which can be run on the Raspberry Pi.