# Cross Compiling Static Rust Binaries for Linux on OS X

2016-09-26

Recently I wrote a small Rust executable for work. I wrote it on my Apple laptop, but wanted to run it on our Linux servers. This note hopes to document how I did it so that I and others may repeat my experience.

Note: I only managed to pull this off because of the helpful folks on the #rust and #rust-internals IRC channels. Thanks everyone!

# Set up

There are plenty of tutorials out there for getting started with Rust, though it’s tough to beat the official book. In order to get a working environment going, I recommend using rustup.

First, create a new binary project with cargo:

cargo init --bin my_proj
cd my_proj


In order to get stuff working later, use the nightly branch of Rust:

rustup override set nightly


Write your project as usual, editing src/main.rs to your heart’s content.

# musl

In order to get your executable to run on the Linux server, you’ll need to compile & link it for that platform. I’ve had luck creating an entirely static executable using musl, a rewrite of the C standard library intended for smaller, embedded targets. To get the necessary tools installed on OS X, use homebrew with this helpful tap.

Once you’ve got the linker & other compilation tools installed (as the above link says, that’ll take a while), you’ll need to let cargo know to use them when compiling for the Linux target. Create a subdirectory to the my_proj directory called .cargo; then in .cargo/config, write the following

[target.x86_64-unknown-linux-musl]


You’ll also need to have rustup specify the target:

rustup target add x86_64-unknown-linux-musl


# Compile & Deploy

To compile your executable for the server, run

cargo build --release --target=x86_64-unknown-linux-musl


Copy it to the server and you’re good to go:

scp target/x86_64-unknown-linux-musl/release/my_proj ⟨your_server_name⟩:


If you’re concerned about the binary size of your new executable, check out UPX. After installing it on my laptop via brew install upx, I ran upx -9 on an executable created with the above instructions. While the executable was an overly simplistic example, upx compressed it down to 34% of the original size. Even if you don’t care about the size of the binary once it’s on the server, it at least made the scp go faster.