From 04177bda940d6b247124396608014ad3856b4741 Mon Sep 17 00:00:00 2001 From: Taesung Hwang <44419552+taesungh@users.noreply.github.com> Date: Fri, 1 Mar 2024 14:36:24 -0800 Subject: [PATCH] Configure building Rust project for Raspberry Pi (#20) - Add Cargo config to set build target platform and linker - Include setup instructions in README - Add arm-linux linker installation instructions for macOS, Windows, Linux - Update checks workflow to cross-compile during build - Add instructions for cross-compiling with cross - Specify default target for cross in `Cross.toml` --------- Co-authored-by: Sam Der --- .github/workflows/run-checks.yml | 15 +++++- pod-operation/.cargo/config.toml | 9 ++++ pod-operation/Cross.toml | 2 + pod-operation/README.md | 90 ++++++++++++++++++++++++++++++-- 4 files changed, 110 insertions(+), 6 deletions(-) create mode 100644 pod-operation/.cargo/config.toml create mode 100644 pod-operation/Cross.toml diff --git a/.github/workflows/run-checks.yml b/.github/workflows/run-checks.yml index ed2cb595..cdd6db33 100644 --- a/.github/workflows/run-checks.yml +++ b/.github/workflows/run-checks.yml @@ -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 @@ -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 @@ -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 diff --git a/pod-operation/.cargo/config.toml b/pod-operation/.cargo/config.toml new file mode 100644 index 00000000..b830ab67 --- /dev/null +++ b/pod-operation/.cargo/config.toml @@ -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" diff --git a/pod-operation/Cross.toml b/pod-operation/Cross.toml new file mode 100644 index 00000000..703c6cb1 --- /dev/null +++ b/pod-operation/Cross.toml @@ -0,0 +1,2 @@ +[build] +default-target = "armv7-unknown-linux-gnueabihf" diff --git a/pod-operation/README.md b/pod-operation/README.md index c3b707d1..42db5132 100644 --- a/pod-operation/README.md +++ b/pod-operation/README.md @@ -4,9 +4,7 @@ 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 @@ -14,10 +12,94 @@ Install cargo-watch 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.