Cross compiling Rust on OS X for Raspberry Pi 3
8 March 2016I managed to get my hands on Raspberry Pi 3B. I found it to be a great opportunity to mess around with Rust. But some problems appeared right away: how do I run my Rust programs on Raspi? Can I compile them on my Mac or should I compile them on the device?
I didn’t have much experience with compiling stuff for other platforms, but turns out it’s not that dramatic – at least for the simple ones I wrote so far.
The thing that’s complicated on OS X
The process we’re interested in is called cross compilation. To cross compile a program for other platform, we need a suitable toolchain.1 One can find many tutorials on how to cross compile Rust code for Raspberry Pi, but most of them are for Linux users. We could trying building a toolchain by ourselves, though doing that on OS X is a total pain. The amount of outdated information on the Web and the number of hurdles we’d have to go over renders Macs unusable for that.
If you don’t believe me, check out the outdated docs on how to get crosstool-ng to work on OS X. The main issues with OS X are the incompatibility of FreeBSD-based command line tools with their GNU counterparts and the case insensitivity of HFS+.
The solution
Instead, let’s use information gathered in Erik’s rust-on-raspberry-pi repo. While building the cross compiler by hand won’t work for us, schnupperboy dockerized the whole process which makes it a breeze.
I was skeptical at first, as I didn’t use Docker before and thought it’s an overkill. Turns out it’s pretty handy for this use case and saves us a lot of hassle. After installing Docker Toolbox and going through its Getting Started Guide, we should be able to follow instructions from rust-on-raspberry-pi’s DOCKER.md without any issues. Keep in mind that Docker commands have to be run from the Docker Quickstart Terminal session.
I ran into problems with permissions in Docker, but after some digging I found the post called “Web development with Docker on Mac OS X”. The user created inside the Docker image needs to have uid
set to 1000
to access files from the host filesystem. The PR which fixes this has been already merged into the rust-on-raspberry-pi master branch.
It took me a couple of days, but cross compiling finally works on my machine and the compiled programs seem to run well on Raspi. I got reminded once again that with such dynamic technologies, the blogposts written two years ago could as well not exist. It’s the reason I wrote this one and I hope it’ll serve people for another few months. 🎉
Shout out to Arek and all the amazing people at Estimote thanks to whom I was able to experiment with Raspberry Pi!
$ docker run -v /Users/rav/Projects/rust/guessing_game:/home/cross/project rust-1.7.0-raspi build --release
*** Extracting target dependencies ***
*** Cross compiling project ***
Updating registry `https://github.com/rust-lang/crates.io-index`
Downloading rand v0.3.14
Downloading libc v0.2.7
Compiling libc v0.2.7
Compiling rand v0.3.14
Compiling guessing_game v0.1.0 (file:///home/cross/project)
$ scp target/arm-unknown-linux-gnueabihf/release/guessing_game pi@raspberrypi.local:
guessing_game 100% 525KB 525.0KB/s 00:00
$ ssh pi@raspberrypi.local
pi@raspberrypi:~ $ ./guessing_game
Guess the number!
Please input your guess.
-
As Mats Petersson said on SO, a toolchain is a set of tools needed to produce executables for the target platform, like a compiler, a linker, shared libraries and so on. ↩