The following steps describe the setup required to cross-compile a rust binary on a amd64 platform. These steps setup the cross-compile toolchain on the host itself. After going through these steps manually, I came accross a tool cross that makes the process way easier. It uses docker for the build and does not require any changes to the host. Jump to the section directly if you dont want to make any changes to the host.
sudo apt-get install crossbuild-essential-s390x
The above package installs both the GNU C and C++ compiler for s390x.
dpkg --add-architecture s390x
# replace 'deb' with 'deb [arch=amd64]'
sudo sed 's/^deb http/deb [arch=amd64] http/' -i '/etc/apt/sources.list'
Add a file /etc/apt/sources.list.d/s390x.list
containing the s390x mirror servers.
These will be used to install s390x package for openssl which is required by Kata rust binary.
echo >/etc/apt/sources.list.d/s390x.list <<EOF
deb [arch=s390x] http://ports.ubuntu.com/ focal-security main restricted universe multiverse
deb [arch=s390x] http://ports.ubuntu.com/ focal main restricted universe multiverse
deb [arch=s390x] http://ports.ubuntu.com/ focal-updates main restricted universe multiverse
EOF
sudo apt-get update
sudo apt install libssl-dev:s390x
rustup target add s390x-unknown-linux-gnu
You can now compile with:
export PKG_CONFIG_PATH=/usr/lib/s390x-linux-gnu/pkgconfig
export PKG_CONFIG_ALLOW_CROSS=1
cargo build --target=s390x-unknown-linux-gnu
The kata binary like the kata-agent or kata-ctl should now compile, but it will error out during the linking process. This is because cargo needs to be passed the linker, as it ends up using the host linker otherwise. You can pass the linker to cargo using env variable:
ENV CARGO_TARGET_S390X_UNKNOWN_LINUX_GNU_LINKER="s390x-linux-gnu-gcc"`
Or you can specify the linker as:
RUSTFLAGS="-C linker=s390x-linux-gnu-gcc" cargo build --target=s390x-unknown-linux-gnu
Fortunately, cross-compile support has been added to Kata makefiles. You can avoid the setup for linker and specify the architecture while running make as:
CC="s390x-linux-gnu-gcc" ARCH=s390x make
The project cross is maintained by the cross-rs team and allows you to easily cross-compile Rust projects using Docker, without messing with your system or creating custom Dockerfiles.
It can be installed with:
cargo install -f cross
The list of targets supported can be seen here: https://github.com/cross-rs/cross/tree/main/docker
To build for s390:
cross build --target=s390x-unknown-linux-gnu
cross enables you to add dependencies and run other necessary commands in the image before using it. For adding the libssl dependency required for Kata Containers, add it as a pre-build hook like so:
echo > Cross.toml <<EOF
[target.s390x-unknown-linux-gnu]
pre-build = ["dpkg --add-architecture s390x && apt-get update && apt-get install --assume-yes libssl-dev:s390x"]
EOF
cross build --target=s390x-unknown-linux-gnu
Cross.toml needs to be in the rust project root directory.