Why do I care about this
Recently I solved this delta issue, where the maintainer asked to switch from Travis CI to GitHub actions.
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. 😌
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?
“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 anyway..you 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
crates.io 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. 😛
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
tool with the rest of the world in order to avoid this pain to as many people as possible. 😅