From fad0b3b751d3fb265f1d4361ef71bf963556a21d Mon Sep 17 00:00:00 2001 From: Anders-Petter Ljungquist Date: Wed, 8 May 2024 09:44:27 +0200 Subject: [PATCH] Demonstrate containerized builds This should make it easier to build the example apps in CI systems where setting up docker-in-docker is difficult. As desirable side effect of this is that it becomes easier to build the example apps on any system, including those where following the advanced setup may be difficult. To be able to build both inside and outside docker containers branching is introduced in the makefile. The added complexity is unfortunate but worthwhile in order to better support containerized builds. The goal is to eventually replace most of the makefile with a cargo plugin. --- .dockerignore | 3 +++ Dockerfile | 58 ++++++++++++++++++++++++++++++++++++++++++ Makefile | 11 ++++++++ README.md | 29 ++++++++++++++------- docker/install_rust.sh | 15 +++++++++++ 5 files changed, 107 insertions(+), 9 deletions(-) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100755 docker/install_rust.sh diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..8132bdb --- /dev/null +++ b/.dockerignore @@ -0,0 +1,3 @@ +* +!/docker/ +!/rust-toolchain.toml \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..788d448 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,58 @@ +ARG REPO=axisecp +ARG SDK=acap-native-sdk +ARG UBUNTU_VERSION=22.04 +ARG VERSION=1.14 +ARG BASE_IMAGE=debian:bookworm-20240423-slim + +FROM ${REPO}/${SDK}:${VERSION}-aarch64-ubuntu${UBUNTU_VERSION} AS sdk-aarch64 +FROM ${REPO}/${SDK}:${VERSION}-armv7hf-ubuntu${UBUNTU_VERSION} AS sdk-armv7hf +FROM ${BASE_IMAGE} + +COPY --from=sdk-aarch64 /opt/axis/acapsdk/axis-acap-manifest-tools /opt/axis/acapsdk/axis-acap-manifest-tools +COPY --from=sdk-aarch64 /opt/axis/acapsdk/environment-setup-cortexa53-crypto-poky-linux /opt/axis/acapsdk/environment-setup-cortexa53-crypto-poky-linux +COPY --from=sdk-armv7hf /opt/axis/acapsdk/environment-setup-cortexa9hf-neon-poky-linux-gnueabi /opt/axis/acapsdk/environment-setup-cortexa9hf-neon-poky-linux-gnueabi +COPY --from=sdk-aarch64 /opt/axis/acapsdk/sysroots/aarch64 /opt/axis/acapsdk/sysroots/aarch64 +COPY --from=sdk-armv7hf /opt/axis/acapsdk/sysroots/armv7hf /opt/axis/acapsdk/sysroots/armv7hf +COPY --from=sdk-aarch64 /opt/axis/acapsdk/sysroots/x86_64-pokysdk-linux /opt/axis/acapsdk/sysroots/x86_64-pokysdk-linux + +RUN apt-get update \ + && apt-get install -y \ + build-essential \ + clang \ + g++-aarch64-linux-gnu \ + g++-arm-linux-gnueabihf \ + pkg-config \ + python3-jsonschema \ + wget \ + && rm -rf /var/lib/apt/lists/* + +ENV RUSTUP_HOME=/usr/local/rustup \ + CARGO_HOME=/usr/local/cargo \ + PATH=/usr/local/cargo/bin:$PATH + +COPY docker/install_rust.sh rust-toolchain.toml ./ +RUN ./install_rust.sh \ + && rustup target add \ + aarch64-unknown-linux-gnu \ + thumbv7neon-unknown-linux-gnueabihf \ + && rm install_rust.sh rust-toolchain.toml + +ENV \ + SYSROOT_AARCH64=/opt/axis/acapsdk/sysroots/aarch64 \ + SYSROOT_ARMV7HF=/opt/axis/acapsdk/sysroots/armv7hf +# The above makes the below easier to read +ENV \ + CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER="aarch64-linux-gnu-gcc" \ + CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUSTFLAGS="-C link-args=--sysroot=${SYSROOT_AARCH64}" \ + CC_aarch64_axis_linux_gnu="aarch64-linux-gnu-gcc" \ + CXX_aarch64_axis_linux_gnu="aarch64-linux-gnu-g++" \ + PKG_CONFIG_LIBDIR_aarch64_unknown_linux_gnu="${SYSROOT_AARCH64}/usr/lib/pkgconfig:${SYSROOT_AARCH64}/usr/share/pkgconfig" \ + PKG_CONFIG_PATH_aarch64_unknown_linux_gnu="${SYSROOT_AARCH64}/usr/lib/pkgconfig:${SYSROOT_AARCH64}/usr/share/pkgconfig" \ + PKG_CONFIG_SYSROOT_DIR_aarch64_unknown_linux_gnu="${SYSROOT_AARCH64}" \ + CARGO_TARGET_THUMBV7NEON_UNKNOWN_LINUX_GNUEABIHF_LINKER="arm-linux-gnueabihf-gcc" \ + CARGO_TARGET_THUMBV7NEON_UNKNOWN_LINUX_GNUEABIHF_RUSTFLAGS="-C link-args=--sysroot=${SYSROOT_ARMV7HF}" \ + CC_thumbv7neon_unknown_linux_gnueabihf="arm-linux-gnueabihf-gcc" \ + CXX_thumbv7neon_unknown_linux_gnueabihf="arm-linux-gnueabihf-g++" \ + PKG_CONFIG_LIBDIR_thumbv7neon_unknown_linux_gnueabihf="${SYSROOT_ARMV7HF}/usr/lib/pkgconfig:${SYSROOT_ARMV7HF}/usr/share/pkgconfig" \ + PKG_CONFIG_PATH_thumbv7neon_unknown_linux_gnueabihf="${SYSROOT_ARMV7HF}/usr/lib/pkgconfig:${SYSROOT_ARMV7HF}/usr/share/pkgconfig" \ + PKG_CONFIG_SYSROOT_DIR_thumbv7neon_unknown_linux_gnueabihf="${SYSROOT_ARMV7HF}" \ No newline at end of file diff --git a/Makefile b/Makefile index 675873c..5ebb26c 100644 --- a/Makefile +++ b/Makefile @@ -202,15 +202,26 @@ target/%/$(PACKAGE)/_envoy: ARCH=$* # at some point we need to map one to the other. It might as well be here. target/aarch64/$(PACKAGE)/_envoy: target/aarch64-unknown-linux-gnu/release/$(PACKAGE) target/armv7hf/$(PACKAGE)/_envoy: target/thumbv7neon-unknown-linux-gnueabihf/release/$(PACKAGE) +# When building for all targets using a single image we cannot rely on wildcard matching. +target/aarch64/$(PACKAGE)/_envoy: ENVIRONMENT_SETUP=environment-setup-cortexa53-crypto-poky-linux +target/armv7hf/$(PACKAGE)/_envoy: ENVIRONMENT_SETUP=environment-setup-cortexa9hf-neon-poky-linux-gnueabi target/%/$(PACKAGE)/_envoy: apps/$(PACKAGE)/manifest.json apps/$(PACKAGE)/LICENSE $(wildcard apps/$(PACKAGE)/otherfiles/*) # Make sure we don't include any obsolete files in the `.eap` if [ -d $(@D) ]; then rm -r $(@D); fi mkdir -p $(@D) cp -r $^ $(@D) +ifeq (0, $(shell test -e /.dockerenv; echo $$?)) + . /opt/axis/acapsdk/$(ENVIRONMENT_SETUP) && cd $(@D) && acap-build --build no-build . +else $(DOCKER_RUN) sh -c ". /opt/axis/acapsdk/environment-setup-* && acap-build --build no-build ." +endif touch $@ # Always rebuild the executable because configuring accurate cache invalidation is annoying. target/%/release/$(PACKAGE): FORCE +ifeq (0, $(shell test -e /.dockerenv; echo $$?)) + cargo -v build --release --target $* --package $(PACKAGE) +else cross -v build --release --target $* --package $(PACKAGE) +endif touch $@ # This is a hack to make the `_envoy` target above always build diff --git a/README.md b/README.md index f1d3479..bb4e000 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,25 @@ _Easy and safe [ACAP] apps using [Rust]_ ## Quickstart guide +Build the `hello_world` example and create `.eap` files in the `target/acap/` directory like + +```sh +docker build --tag acap-rs . +docker run \ + --interactive \ + --rm \ + --tty \ + --user $(id -u):$(id -g) \ + --volume $(pwd):$(pwd) \ + --workdir $(pwd) \ + acap-rs \ + make build PACKAGE=hello_world +``` + +This works with any of the [example applications](#example-applications). + +## Advanced setup + Ensure global prerequisites are installed: * Docker @@ -22,15 +41,7 @@ source ./init_env.sh make sync_env ``` -Build the `hello_world` example and create `.eap` files in the `target/acap/` directory like - -```sh -PACKAGE=hello_world make build -``` - -This works with any of the [example applications](#example-applications). - -Other important workflows are documented in the [Makefile](./Makefile) and can be listed with `make help`. +Important workflows are documented in the [Makefile](./Makefile) and can now be listed with `make help`. ## Example applications diff --git a/docker/install_rust.sh b/docker/install_rust.sh new file mode 100755 index 0000000..1bbbdb3 --- /dev/null +++ b/docker/install_rust.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env sh +set -eux +wget "https://static.rust-lang.org/rustup/archive/1.26.0/x86_64-unknown-linux-gnu/rustup-init" +echo "0b2f6c8f85a3d02fde2efc0ced4657869d73fccfce59defb4e8d29233116e6db rustup-init" | sha256sum -c - +chmod +x rustup-init + +./rustup-init \ + --default-host x86_64-unknown-linux-gnu \ + --default-toolchain $(grep "channel" rust-toolchain.toml | cut -d '"' -f 2) \ + --no-modify-path \ + --profile minimal \ + -y + +rm rustup-init +chmod -R a+w $RUSTUP_HOME $CARGO_HOME \ No newline at end of file