Update project structure for multiple examples, refactor original example

Anthony J. Martinez 3 months ago
parent 743f6dc060
commit d2fdfcd88c
Signed by: ajmartinez
  1. 48
  2. 7
  3. 31
  4. 22

@ -1,50 +1,14 @@
# Cross Build
Provides a Dockerfile to build a container that supports cross compilation for ARMv7 and i686 targets
Provides example Dockerfiles to build cross-compilation containers for various targets
from x86-64 hosts.
This project was created out of a need to have a single-shot process for building a few Rust projects
with stripped binaries featuring static C-runtimes for:
- `armv7-unknown-linux-gnueabihf`
- `i686-unknown-linux-gnu`
### Examples
While [cross](https://github.com/rust-embedded/cross) exists, and is far more full featured, the
project lags behind in updating the base OS, GCC, and QEMU versions used (as of this writing).
An [example](/example/rust-job.sh) exists that handles my specific use case for one project, and might
serve as inspiration for modifications to suit more complicated needs.
### Building
Using `podman` since I do not have `docker` itself installed:
# Assuming you have cloned this repository and are in the repo
$ cd docker
$ podman build -t crossbuild:dev -f ./Dockerfile
### Use
Again using `podman` and assuming you're in the repository:
$ podman run --rm \
-e REPO_URL="https://git.staart.one/ajmartinez/connchk.git" \
-e BIN_NAME="connchk" -v ./example/:/opt/build \
crossbuild:dev /opt/build/rust-job.sh
# ...
$ tree example
├── armv7-unknown-linux-gnueabihf_connchk
├── i686-unknown-linux-gnu_connchk
└── rust-job.sh
$ file example/*_connchk
example/armv7-unknown-linux-gnueabihf_connchk: ELF 32-bit LSB executable, ARM, EABI5 version 1 (GNU/Linux), statically linked, BuildID[sha1]=00811fa9637b6abf243fb707a8970b0cea43ba4f, for GNU/Linux 3.2.0, stripped
example/i686-unknown-linux-gnu_connchk: ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), statically linked, BuildID[sha1]=6e1d92bb01aed5b0adb673b1dfbe5fb28cf5da18, for GNU/Linux 3.2.0, stripped
- [Example 1](examples/multi-target-static-git.md): A Rust project fetched from Git, and then compiled for ARMv7 and i686 targets, including
a static C runtime
- [Example 2](examples/armhf-stretch-crate.md): A Rust project volume mounted as an exported package (`.crate` file), and compiled for
ARMv7 with dynamic linking for a legacy target based on Debian Stretch
### License

@ -1,5 +1,5 @@
# syntax=docker/dockerfile:1
FROM ubuntu:20.04
FROM ubuntu:latest
ARG DEBIAN_FRONTEND=noninteractive
@ -11,7 +11,10 @@ RUN apt-get update && apt-get --yes install \
libc6-dev-i386-amd64-cross \
curl \
git && apt clean all && \
echo "umask 0022" > /etc/profile.d/01-fix-umask.sh
echo "umask 0022" > /etc/profile.d/01-fix-umask.sh && \
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && \
/root/.cargo/bin/rustup target add armv7-unknown-linux-gnueabihf && \
/root/.cargo/bin/rustup target add i686-unknown-linux-gnu
WORKDIR /opt/build

@ -0,0 +1,31 @@
# Multi-Target Static Rust Project from Git Repo
Using this [Dockerfile](../docker/multi-target-static-git) one can build a statically
linked Rust project from a Git repo (provided it has minimal external dependencies)
in an Ubuntu (latest) container targeting both ARMv7 and i686.
### Container Build
`$ podman build -t crossbuild-multi -f multi-target-static-git`
### Build Example
This assumes `PROJECT_DIR` is set to the path to which this repo was cloned.
The project built in this is example is my [`connchk` crate](https://git.staart.one/ajmartinez/connchk).
$ mkdir ~/build_dir
$ cp ${PROJECT_DIR}/examples/multi-target-static-git.sh ~/build_dir/
$ podman run --rm -it -e GIT_REPO="https://git.staart.one/ajmartinez/connchk.git" \
-e BIN_NAME="connchk" \
-v "${HOME}/build_dir:/opt/build:z \
crossbuild-multi:latest \
# Build output redacted
$ file build_dir/*_connchk
build_dir/armv7-unknown-linux-gnueabihf_connchk: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, BuildID[sha1]=f4c5af4314c56d6d2a6d4a1743ca3e3ccd0f955d, for GNU/Linux 3.2.0, stripped
build_dir/i686-unknown-linux-gnu_connchk: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, BuildID[sha1]=e9937cbc4f944b66aedd393ef270be9ab85002da, for GNU/Linux 3.2.0, stripped

@ -8,25 +8,20 @@ I686="i686-unknown-linux-gnu"
TARGETS=( "${ARMV7}" "${I686}" )
if [ -z ${REPO_URL} ]; then
echo "Missing REPO_URL, exiting" >&2
exit 1
echo "Missing REPO_URL, exiting" >&2
exit 1
if [ -z ${BIN_NAME} ]; then
echo "Missing BIN_NAME, exiting" >&2
exit 1
echo "Missing BIN_NAME, exiting" >&2
exit 1
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
source $HOME/.cargo/env
rustup target add "${ARMV7}"
rustup target add "${I686}"
cat >>$HOME/.cargo/config <<EOF
rustflags = ["-C", "target-feature=+crt-static"]
rustflags = ["-C", "target-feature=+crt-static", "-C", "strip=symbols"]
linker = "arm-linux-gnueabihf-gcc"
@ -40,10 +35,9 @@ git clone ${REPO_URL} output
cd output
for target in "${TARGETS[@]}"; do
cargo build --release --target "${target}"
strip "${BIN_PATH}"
mv "${BIN_PATH}" "/opt/build/${target}_${BIN_NAME}"
cargo build --release --target "${target}"
mv "${BIN_PATH}" "/opt/build/${target}_${BIN_NAME}"
cd /opt/build