Cross Compiling Rust for RPI4

I really enjoy writing Rust, I own a growing number of Raspberry PIs. The RPI4 is a big step forward in terms of hardware resources on the platform. It is however 64bit not 32 like its predecessors and requires a different tool chain for cross compilation. In this guide I will take you through the setup. If you just want something that works now, you can use the albeego/rust-musl-builder-aarch64:0.0.1 docker image.

docker run --rm -it -v "$(pwd)":/home/rust/src albeego/rust-musl-builder:0.0.1 cargo build --release --target=aarch64-unknown-linux-gnu

Tool Chain

We’re going to need some packages for this, the following apt command will pull them all in:

apt install -y \
    build-essential \
    libssl-dev \
    linux-libc-dev \
    gcc-aarch64-linux-gnu \
    software-properties-common \
    crossbuild-essential-arm64

A note here on linking, you will need to tell rust to use /usr/bin/aarch64-linux-gnu-gcc as the linker for the rust applications you compile. You can do this by including a .cargo/config file in your $HOME directory, the project directory with the following contents

[target.aarch64-unknown-linux-gnu]
linker = "aarch64-linux-gnu-gcc"

Now you need to let rust know about your cross compilation target. You do this by adding the target to rustup:

rustup target add aarch64-unknown-linux-gnu

That’s it for the tool chain

Open SSL

One of the challenges with cross compiling rust applications is getting the dependencies correct for the build. Open SSL is pretty prevalent and if you are going to do anything web related, you will need it. This cannot be the pre-compiled Open SSL binaries that come with your OS, you need to produce a cross compiled binary for linking with your rust application. You don’t want to overwrite that pre-compile binary that came with your OS either. That would cause other issues! So, let’s make a place to store the cross compiled Open SSL binary and its source and open it in our terminal

mkdir /build
cd /build

Grab the Open SSL source from the GitHub release and extract it (1_0_2r) at the time of writing

curl -LO "https://github.com/openssl/openssl/archive/OpenSSL_1_0_2r.tar.gz"
tar xvzf "OpenSSL_1_0_2r.tar.gz
cd "openssl-OpenSSL_1_0_2r"

Now we are ready to build Open SSL, we will configure it without ZLib (we need to provide our own cross compiled ZLib to consumers anyway), it needs to be non shared so we are not linking any of our x86_64 objects, position independent in memory and installed to a custom location

./Configure no-shared \
            no-zlib \
            -fPIC \
            --prefix=/build/openssl-OpenSSL_1_0_2r/target \
            --cross-compile-prefix=aarch64-linux-gnu- \
            linux-aarch64

That’s the build setup, now run it to produce the binary in /build/openssl-OpenSSL_1_0_2r/target/bin

make depend
make
sudo make install

ZLib

We will need to do something similar with the compression library ZLib, again, if you are doing anything web related, you can’t avoid it. Lets keep everything together and drop the source code in to our /build directory

cd /build
ZLIB_VERSION=1.2.11
curl -LO "http://zlib.net/zlib-1.2.11.tar.gz"
tar xzf "zlib-1.2.11.tar.gz"
cd "zlib-1.2.11"

and for the build (making sure we use out aarch64 compiler)

CC=aarch64-linux-gnu-gcc ./configure --static
make
sudo make install

Running the builds

You will need to pass a few signals over to rust to let it know where your pre-compiled binaries are and how to use them. After that it is simply a case of doing a cargo build with the target architecture specified

OPENSSL_DIR=/build/openssl-OpenSSL_$OPENSSL_VERSION/target \
    PKG_CONFIG_ALLOW_CROSS=true \
    LIBZ_SYS_STATIC=1 \
    CC="aarch64-linux-gnu-gcc -static -Os" \
    cargo build --release --target=aarch64-unknown-linux-gnu

Please let me know in the comments if you get any issues. I may have seen them and may be able to help!

I’d like to give a special mention to Eric Kidd from Vermont USA on this one. His repository here https://github.com/emk/rust-musl-builder formed the basis on which I did a lot of this work

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: