Cross compiling Rust for ARM (e.g. Raspberry Pi) using any OS!

Rust + Vagrant 💖

Everybody knows that Rust is the most beloved language for developers since it appeared! Same goes for Raspberry Pi, the small but mighty computer, that costs just £30 but brings a whole awesomeness on board (I wish Broadcom Engineers were a bit more open with their design and less lazy to implement the whole ARM GIC; but let’s keep this for another time).

Here is a small walkthrough, on how to use Mac OSx, Linux or even Windows (hey not tested but I am sure you can make it work, the tools are the same) to compile your Rust marvellousness and run the binary directly on the Raspberry Pi (2/3/3+).

You can find a few different tutorials describing this process but almost never for Mac OSx.

My solution is very simple: use Vagrant! If you haven’t heard about it is an open-source software product for building and maintaining portable virtual software development environments e.g. for VirtualBox and so on. It really simplifies software configuration management of virtualizations and makes you life sooo much easier and productive 🤗

If you have a Linux based bistro, then you can just skip the steps 1–2.

Preparation 👈🏼

The simple steps for achieving all the above are the following (the first two steps assume Mac OSx; for Windows users you can do something similar but Google on how to install the tools described):

  1. Install Virtualbox on your machine and install Vagrant
brew cask install virtualbox
brew cask install vagrant
brew cask install vagrant-manager

2. Add the Vagrant box you want to use, start it and ssh into it. We’ll use Debian Stretch for the following example

cd ~/workspace/rust
vagrant init debian/stretch64
vagrant up
vagrant ssh
# you can quit the machine with
'vagrant halt'

4. (If you have arrived here from the steps above, yes that was it. Now you ‘re running a Debian, straight into your Mac OSx at the speed of light 😮)

It’s a good idea to update to the current package versions. Do that and then install Rust (nightly 🌌 is recommended)

sudo apt update
sudo apt upgrade
# you may need to 'sudo apt install curl' as well
curl https://sh.rustup.rs -sSf | sh
# Choose 2, Enter, nightly, y. Confirm and press 1 to install.

Now you should be welcomed with

Rust is installed now. Great! 🎉

5. Install the GNU ARM toolchain and their respective Rust crates

source $HOME/.cargo/env
sudo apt-get install -qq gcc-arm-linux-gnueabihf
rustup target add armv7-unknown-linux-gnueabihf

6. Configure Cargo for cross-compilation

mkdir -p ~/.cargo
# > should not be included when pasting
cat >>~/.cargo/config <<EOF
> [target.armv7-unknown-linux-gnueabihf]
> linker = "arm-linux-gnueabihf-gcc"
> EOF

7. That was it! Run a simple test

cargo new --bin hello 
cd hello
cargo build --target=armv7-unknown-linux-gnueabihf

which should happily create an ARMv7 binary[1]! To be sure

[1] For the difference between ARM7 and ARMv7 check here: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka13706.html Thanks @LulzCop for spotting my mistake :)

file target/armv7-unknown-linux-gnueabihf/debug/hello
vagrant@stretch:~/hello$ target/armv7-unknown-linux-gnueabihf/debug/hello: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 3.2.0, BuildID[sha1]=39cfb5d9c8cda29ecac841120a2ef9c170f84399, not stripped
# you can scp and run the executable on the ARM to finalise your test!

Hurray! Now you can cross-compile Rust for ARM-based devices from the comfort of your own OS🤩

As always ping me if you have any questions and please comment in case something doesn’t work as expected!