Rust makes cross compilation child's play

Why do I care about this

Recently I solved this delta issue, where the maintainer asked to switch from Travis CI to GitHub actions.

These are all the pull requests I’ve done if you want to have a look at this journey: #399, #400, #409, #411, #413, #417 and finally #418.

And yes..As you can see I like small incremental work and early feedback instead of giant pull requests. ๐Ÿ˜

Anyway, the delta project has a lot of compilation targets and the binaries are automatically released in the GitHub releases page every time the project is tagged. Sweet. ๐Ÿ˜Œ

delta releases

From an x86_64 architecture (TLDR: common 64 bit Intel or AMD processors) it is really straightforward to compile for a different operating system with cargo if you are targeting the same architecture. For example if you want to compile for macOS you just need to run:

rustup target add x86_64-apple-darwin
cargo build --target x86_64-apple-darwin

The problems start to arise when you want to compile for a different architecture, such as i686 (32 bit) or ARM processors. In this case, you have to install some dependencies and set some environment variables, which may be painful. For example, in the old continuous integrations scripts of delta, this was the way dependencies were installed. Ugly, I know. As rust developers we are used to great tools, so there must be a better way right?

Meet Cross

โ€œZero setupโ€ cross compilation and โ€œcross testingโ€ of Rust crates.

This is the description of the Cross tool.

The TLDR is that it let you compile and test rust projects for architectures other than i686 and x86_64.

Instead of doing cargo build --target <YOUR_TARGET> you simply do cross build --target <YOUR_TARGET>. Based on the target, in fact, cross will run a docker image that has all the right dependencies already installed and configured by the rust-embedded team itself. ๐Ÿ˜‰ And that’s it..just run cargo install cross and you are ready to cross-compile for all these targets in rust, no other dependency is required, except docker of course!

Obviously this was not an exhaustive overview about cross and I encourage you to have a look at the GitHub page if you are interested.

Cross in GitHub actions

Of course, after a whole morning getting mad trying to setup weird ubuntu dependencies for the delta issue, when I found out about cross I felt very stupid for not knowing it in advance and I tried to integrate it in the Continuous Deployment delta pipeline.

It turns out that this is like the easiest thing in the world! The action-rs/cargo action I was already using had built-in support for cross. Now I even felt more stupid, but just need to set the use-cross variable to true and you are done!

This is the step that builds the whole delta project for all its different targets..easy, right? ๐Ÿ˜€

Cross in Rust GitHub template

You may or (probably) may not be aware of Rust GitHub Template.

Rust GitHub Template is a template for cargo generate that aims to be a starting point suitable for the vast majority of rust projects that will be hosted on GitHub.

Beyond all its nice goodies, this template will setup Continuous Deployment for you, therefore whenever you tag your project, it will be published on and the binaries will be released in the GitHub Releases page, just like in delta. ๐Ÿ˜

Until today, Rust GitHub template only supported x86_64 windows, linux and mac, but after I found out Cross I couldn’t resist and I added support for i686 and aarch64 linux architectures, which are both two tier 1 rust targets. In practice, this means your “old thinkpad” and “raspberry pi” users will thank you a lot. ๐Ÿ˜›

gh template releases

This is an example of the resulting Continuous Deployment step.

And that was it, after I spent a lot of very useful time trying to setup compilation dependencies basically I just wanted to share my love for the cross tool with the rest of the world in order to avoid this pain to as many people as possible. ๐Ÿ˜…

Thanks for reading this far! You can find me on twitter or YouTube, bye! ๐Ÿ‘‹