Add example with extra target dependencies (libpcap)

- ARMv7 target running Debian Stretch
- Depends on libpcap0.8-dev:armhf
- Adds dummy crate to force linking as an example
This commit is contained in:
Anthony J. Martinez 2022-09-03 14:15:31 -05:00
parent acb2861c6f
commit 17e7d7a9cf
Signed by: ajmartinez
GPG Key ID: A2206FDD769DBCFC
5 changed files with 119 additions and 0 deletions

View File

@ -0,0 +1,19 @@
# syntax=docker/dockerfile:1
FROM debian:stretch
ARG DEBIAN_FRONTEND=noninteractive
ARG TZ=UTC
RUN dpkg --add-architecture armhf && \
apt-get update && \
apt-get --yes install \
crossbuild-essential-armhf \
curl \
libpcap0.8-dev:armhf && \
apt clean all && \
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && \
/root/.cargo/bin/rustup target add armv7-unknown-linux-gnueabihf
WORKDIR /opt/build
CMD ["/bin/bash"]

View File

@ -0,0 +1,41 @@
# ARMv7 Dynamic Rust Project from Cargo Package
Using this [Dockerfile](../docker/armhf-stretch-crate) one can build a dynamically
linked Rust project from a Cargo package (`.crate` file, a gzipped tarball) that
depends on `libpcap0.8` in a Debian Stretch container targetting ARMv7.
Note that the Dockerfile does a few special things needed to account for the
*target* architecture's development headers:
1. The `armhf` architecture is added before `apt` is updated using `dpkg --add-architecture armhf`
2. Since `libpcap-dev` itself has no `armhf` installation candidate, the specific package `libpcap0.8-dev:armhf` is specified instead
Without these two steps, cross compliation dependent on libraries that differ across architectures is hopeless.
### Container Build
`$ podman build -t crossbuild-armhf -f armhf-stretch-crate`
### Build Example
This assumes `PROJECT_DIR` is set to the path to which this repo was cloned, and that you have
the Rust toolchain installed with `cargo` on your `PATH`.
The project built in this example is [here](./pcap-example/).
```bash
$ mkdir ~/build_dir
$ cd ${PROJECT_DIR}/examples/pcap-example/
$ cargo package --no-verify --allow-dirty
$ cp target/package/pcap-example-0.1.0.crate ~/build_dir/
$ podman run --rm -it e BIN_NAME="pcap-example" \
-e BIN_VERSION="0.1.0" \
-v "${HOME}/build_dir:/opt/build:z \
crossbuild-armhf:latest \
/opt/build/armhf-stretch-crate.sh
# Build output redacted
$ file build_dir/*_pcap-example
build_dir/armv7-unknown-linux-gnueabihf_pcap-example: ELF 32-bit LSB pie executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 3.2.0, BuildID[sha1]=40ed6d3beeed98797558d4024fbdb468f58abd49, stripped
```

47
examples/armhf-stretch-crate.sh Executable file
View File

@ -0,0 +1,47 @@
#!/bin/bash
set -e
ARMV7="armv7-unknown-linux-gnueabihf"
if [ -z "${BIN_NAME}" ]; then
echo "Missing BIN_NAME, exiting" >&2
exit 1
fi
if [ -z "${BIN_VERSION}" ]; then
echo "Missing BIN_VERSION, exiting" >&2
exit 1
fi
source ${HOME}/.cargo/env
cat >>"${HOME}/.cargo/config" <<EOF
[build]
rustflags = ["-C", "strip=symbols"]
[target."${ARMV7}"]
linker = "arm-linux-gnueabihf-gcc"
EOF
PROJ_DIR="${BIN_NAME}-${BIN_VERSION}"
CRATE="${PROJ_DIR}.crate"
if [ ! -f "${CRATE}" ]; then
echo "Expected crate not found" >&2
exit 1
fi
tar xf "${CRATE}"
cd "${PROJ_DIR}"
cargo build --release --target "${ARMV7}"
BIN_PATH="target/${ARMV7}/release/${BIN_NAME}"
mv "${BIN_PATH}" "/opt/build/${ARMV7}_${BIN_NAME}"
cd /opt/build
rm -rf "${PROJ_DIR}"

View File

@ -0,0 +1,9 @@
[package]
name = "pcap-example"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
pcap = "0.10"

View File

@ -0,0 +1,3 @@
fn main() {
let _cap = pcap::Capture::dead(pcap::Linktype::ETHERNET).unwrap();
}