Rust based applications become trends nowadays, as it got robustnest and minimal transition from C or any good reason out there, but cross compiling rust application also tricky sometimes, there are many platform out there in this write i will cover 6 of, x86_64 aarch64 arm32 for musl and glibc.
First we need docker rust image and add things on top of it.
FROM rust:1.65-slim-bullseye
RUN apt update && \
apt install -y --no-install-recommends curl git wget build-essential make perl pkg-config curl tar jq && \
apt clean && \
rm -rf /var/lib/apt/lists/*
Then you get image for building x86_64, then how about musl build? add musl-tools package, yes thats it.
FROM rust:1.65-slim-bullseye
RUN apt update && \
apt install -y --no-install-recommends curl git wget build-essential make perl pkg-config curl tar jq musl-tools && \
apt clean && \
rm -rf /var/lib/apt/lists/* And don't forget to add target for x86_64 glibc and x86_64 musl, by default usually only x86_64-unknown-linux-gnu installed, as this image based on libc debian.
RUN rustup target add x86_64-unknown-linux-gnu
RUN rustup target add x86_64-unknown-linux-musl
Now we got target for musl but we don't have compiler for it, then we manually download the musl-gcc
RUN wget --progress=dot:mega -t 10-c https://musl.cc/x86_64-linux-musl-cross.tgz && \
tar zxf ./x86_64-linux-musl-cross.tgz -C /opt && \
rm ./x86_64-linux-musl-cross.tgz
Pretty straightforward i said, for enabling glibc and musl on x86_64, now we are getting into tricky part.
The steps for aarch64 or arm64 build also pretty much look alike with x86_64
RUN dpkg --add-architecture arm64 && \
apt update && \
apt install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc6-arm64-cross libc6-dev-arm64-cross && \
apt clean && \
rm -rf /var/lib/apt/lists/*
Add the aarch64 target
RUN rustup target add aarch64-unknown-linux-gnu
RUN rustup target add aarch64-unknown-linux-musl
Download musl-gcc for aarch64
RUN wget --progress=dot:mega -t 10 -c https://musl.cc/aarch64-linux-musl-cross.tgz && \
tar zxf ./aarch64-linux-musl-cross.tgz -C /opt && \
rm ./aarch64-linux-musl-cross.tgz
And again the arm 32bit part also pretty similiar, add armhf compiler packages and add the target.
RUN dpkg --add-architecture armhf && \
apt update && \
apt install -y gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libc6-armhf-cross libc6-dev-armhf-cross && \
apt clean && \
rm -rf /var/lib/apt/lists/*
add armhf target
RUN rustup target add armv7-unknown-linux-gnueabihf
RUN rustup target add arm-unknown-linux-musleabihf
and again we fetch the armhf musl-gcc
RUN wget --progress=dot:mega -t 10 -c https://musl.cc/armv7l-linux-musleabihf-cross.tgz && \
tar zxf ./armv7l-linux-musleabihf-cross.tgz -C /opt && \
rm ./armv7l-linux-musleabihf-cross.tgz
Lastly, dont forget export our musl-gcc to PATH
ENV PATH="/opt/aarch64-linux-musl-cross/:/opt/aarch64-linux-musl-cross/bin/:/opt/x86_64-linux-musl-cross/:/opt/x86_64-linux-musl-cross/bin/:$PATH"
The other packages is libssl-dev depends on the source itself it may use openssl libssl or rust static libssl, if the rust static libssl then we doesn't need install libssl-dev
If i need to list all env that affect the compilation essentially only 2: OPENSSL and COMPILER PATH
OPENSSL_INCLUDE_DIR=/usr/include/openssl/
OPENSSL_LIB_DIR=/usr/lib/x86_64-linux-gnu/
OPENSSL_LIB_DIR=/usr/lib/arm64-linux-gnu/
OPENSSL_LIB_DIR=/usr/lib/arm-linux-gnueabihf/
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER=aarch64-linux-musl-gcc
CARGO_TARGET_ARMV7_UNKNOWN_LINUX_MUSLEABIHF_LINKER: arm-linux-gnueabihf-gcc
CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_LINKER: arm-linux-gnueabihf-gcc
CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER=x86_64-linux-musl-gcc
Notes:
gnu target, you may don't need to specify linkermusl target must specify linker or it will throw error about musl-gcc not foundSample of building:
OPENSSL_INCLUDE_DIR=/usr/include/openssl/ OPENSSL_LIB_DIR=/usr/lib/x86_64-linux-gnu/ cargo build --target=x86_64-unknown-linux-gnu --releaseCARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc cargo build --target=aarch64-unknown-linux-gnu --release
CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_LINKER: arm-linux-gnueabihf-gcc cargo build --target=aarch64-unknown-linux-gnu --release
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER: aarch64-linux-musl-gcc cargo build --target=aarch64-unknown-linux-gnu --release
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc cargo build --target=aarch64-unknown-linux-gnu --releasegcc and g++, rarely needed.
CXX=/opt/armv7l-linux-musleabihf-cross/bin/armv7l-linux-musleabihf-g++ CC=/opt/armv7l-linux-musleabihf-cross/bin/armv7l-linux-musleabihf-gcc cargo build --target=armv7-unknown-linux-musleabihf --release
the ENV can be set directly or via export method
My personal rust builder image look like this
FROM rust:1.65-slim-bullseye
ENV PATH="/opt/aarch64-linux-musl-cross/:/opt/aarch64-linux-musl-cross/bin/:/opt/x86_64-linux-musl-cross/:/opt/x86_64-linux-musl-cross/bin/:$PATH"
# Install build deps and add sccache
ARG SCCACHE_VERSION
ARG SCCACHE_FILE=sccache-$SCCACHE_VERSION-x86_64-unknown-linux-musl
ARG SCCACHE_URL=https://github.com/mozilla/sccache/releases/download
RUN apt update && \
apt install -y --no-install-recommends curl git wget build-essential make perl pkg-config curl tar jq musl-tools && \
apt clean && \
rm -rf /var/lib/apt/lists/* && \
curl -L $SCCACHE_URL/$SCCACHE_VERSION/$SCCACHE_FILE.tar.gz | tar xz && \
mv $SCCACHE_FILE/sccache /usr/local/bin/sccache && \
chmod +x /usr/local/bin/sccache
### add aarch64 build and aarch64 target
RUN dpkg --add-architecture arm64 && \
apt update && \
apt install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc6-arm64-cross libc6-dev-arm64-cross && \
apt clean && \
rm -rf /var/lib/apt/lists/* && \
rustup target add aarch64-unknown-linux-gnu
### armhf build
#RUN dpkg --add-architecture arm64 && \
# apt update && \
# apt install -y gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libc6-armhf-cross libc6-dev-armhf-cross && \
# apt clean && \
# rm -rf /var/lib/apt/lists/*
### add armhf target
#RUN rustup target add rustup target add armv7-unknown-linux-gnueabihf
### Add musl-gcc aarch64 and x86_64
RUN wget --progress=dot:mega -t 10-c https://musl.cc/x86_64-linux-musl-cross.tgz && \
tar zxf ./x86_64-linux-musl-cross.tgz -C /opt && \
wget --progress=dot:mega -t 10 -c https://musl.cc/aarch64-linux-musl-cross.tgz && \
tar zxf ./aarch64-linux-musl-cross.tgz -C /opt && \
rm ./x86_64-linux-musl-cross.tgz && \
rm ./aarch64-linux-musl-cross.tgz
## Install nodejs, follow lts path
RUN curl -fsSL https://deb.nodesource.com/setup_lts.x | bash - && \
apt update && \
apt install -y --no-install-recommends nodejs && \
apt clean && \
rm -rf /var/lib/apt/lists/* && \
npm install -g npm && \
npm install -g yarn && \
npm install -g pnpm && \
rm -rf $HOME/.config
CMD ["bash"]
Only x86_64 and aarch64
sources: