One Go feature which I’m using regularly is cross-compiling Go code to other platforms (usually from macOS to linux-amd64).
In Go, this is a built-in feature that “just works”. The following command produces a statically linked ELF binary which can simply be copied and run on a Linux machine:
1 2 3
Rust doesn’t have built-in support for such a feature.
Edit: Rust core-commiter Steve Klabnik pointed out, that actually what I’m showing off here is the built-in Rust support :)
I’ve been looking for a while how to achieve this using Cargo and Rust. And (spoiler-alert!) I’ve found one, which is relatively simple to set up.
Start with installing the required target. In our case (Linux x86_64) this is
x86_64-unknown-linux-musl. The lightweight standard library musl is able to produce statically linked libraries (contrary to the
x86_64-unknown-linux-gnu target, which uses GNU libc.
What’s still missing is the linker. This was always the part where I go into trouble when trying this earlier. Finally, this blog post from Graham Enos guided me to a Homebrew tap by Filippo Valsorda, which provides a complete macOS to Linux cross-compile toolchain.
That was the heavy-lifting. Now just tell Cargo where to find the linker. You can place the following into your projects
.cargo/config or configure it globally in your
Edit: As of rust-1.32.0, it might be required to add a symlink to make it work, which I came accross here
That’s it! You can now cross-compile Linux binaries with Cargo!
You can find the resulting statically linked ELF binary in the
target/x86_64-unknown-linux-musl/release directory. This file can be copied and run on any Linux x86_64 machine, just like the cross-compiled Go binary!