From 7a0771215d9bd52dc9d6913abee56a9f62893d3e Mon Sep 17 00:00:00 2001 From: Anders Betts Date: Fri, 18 Sep 2026 10:24:32 +0200 Subject: deploy: cross-compile arm64 binaries on the dev machine The target only assembles the image from prebuilt binaries, so redeploys no longer compile sqlite/argon2 on the NAS. New deploy/Dockerfile.cross provides the gcc-aarch64-linux-gnu toolchain; the Dockerfile uses .prebuilt/ when present. --- .dockerignore | 1 + .gitignore | 1 + Dockerfile | 9 ++++++++- Makefile | 2 +- deploy/Dockerfile.cross | 12 ++++++++++++ deploy/cross-build.sh | 13 +++++++++++++ scripts/deploy.sh | 17 +++++++++++++++-- 7 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 deploy/Dockerfile.cross create mode 100644 deploy/cross-build.sh diff --git a/.dockerignore b/.dockerignore index 110fe6f..6e6f325 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,5 +1,6 @@ .git .github +.prebuilt/ build/ var/ .env diff --git a/.gitignore b/.gitignore index 811ddc5..13080ca 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ build/ +.prebuilt/ *.o *.a *.db diff --git a/Dockerfile b/Dockerfile index d658d70..41e2895 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,7 +8,14 @@ RUN apt-get update \ && rm -rf /var/lib/apt/lists/* WORKDIR /src COPY . . -RUN make -j"$(nproc)" VERSION="$VERSION" && make test VERSION="$VERSION" +# With .prebuilt/ the binaries are cross-compiled on the development machine +# (see deploy/Dockerfile.cross); otherwise build and test from source. +RUN if [ -x .prebuilt/bokfd ]; then \ + mkdir -p build && \ + cp .prebuilt/bokfd .prebuilt/bokfctl .prebuilt/bokftui build/; \ + else \ + make -j"$(nproc)" VERSION="$VERSION" && make test VERSION="$VERSION"; \ + fi FROM debian:bookworm-slim AS runtime RUN apt-get update \ diff --git a/Makefile b/Makefile index 418dc8e..d35176b 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ DEPFLAGS = -MMD -MP CPPFLAGS = -Isrc -Iclients -Ivendor -Ivendor/argon2 DEFS = -D_GNU_SOURCE -DARGON2_NO_THREADS -DBOKF_VERSION=\"$(VERSION)\" -BUILD = build +BUILD ?= build VENDOR_SRC = vendor/sqlite3.c vendor/yyjson.c vendor/sha256.c \ vendor/argon2/argon2.c vendor/argon2/core.c \ diff --git a/deploy/Dockerfile.cross b/deploy/Dockerfile.cross new file mode 100644 index 0000000..9a568cf --- /dev/null +++ b/deploy/Dockerfile.cross @@ -0,0 +1,12 @@ +# Cross-compile the arm64 binaries on an amd64 host. The runtime image is +# assembled later on the target host from the produced binaries. +FROM debian:bookworm +RUN dpkg --add-architecture arm64 \ + && apt-get update \ + && apt-get install -y --no-install-recommends \ + make ca-certificates gcc-aarch64-linux-gnu \ + libncurses-dev:arm64 libssl-dev:arm64 \ + && rm -rf /var/lib/apt/lists/* +COPY cross-build.sh /usr/local/bin/cross-build +RUN chmod 0755 /usr/local/bin/cross-build +ENTRYPOINT ["/usr/local/bin/cross-build"] diff --git a/deploy/cross-build.sh b/deploy/cross-build.sh new file mode 100644 index 0000000..7c90b0f --- /dev/null +++ b/deploy/cross-build.sh @@ -0,0 +1,13 @@ +#!/bin/sh +# Cross-compile bokfd/bokfctl/bokftui for aarch64. Expects the source +# read-only at /src, writes the binaries to /out and takes the version from +# $VERSION. Run through deploy/Dockerfile.cross. +set -eu + +make -C /src -j"$(nproc)" BUILD=/tmp/build \ + CC=aarch64-linux-gnu-gcc \ + CFLAGS="-O2 -g -L/usr/lib/aarch64-linux-gnu" \ + VERSION="${VERSION:-0.1.0-dev}" + +mkdir -p /out +cp /tmp/build/bokfd /tmp/build/bokfctl /tmp/build/bokftui /out/ diff --git a/scripts/deploy.sh b/scripts/deploy.sh index 25c86dc..c345a21 100755 --- a/scripts/deploy.sh +++ b/scripts/deploy.sh @@ -47,7 +47,7 @@ case "$BOKF_BUILD" in if [ "$(uname -m)" = "$host_arch" ]; then BOKF_BUILD=local else - echo "deploy: host is $host_arch, building there" + echo "deploy: host is $host_arch, cross-building here" BOKF_BUILD=remote fi ;; @@ -64,12 +64,25 @@ if [ "$BOKF_BUILD" = local ]; then echo "deploy: shipping image to $BOKF_HOST" docker save "bokf:$TAG" | gzip | "${SSH[@]}" 'gunzip | docker load' else - echo "deploy: building image bokf:$TAG on $BOKF_HOST" + echo "deploy: cross-compiling $host_arch binaries on this machine" + rm -rf .prebuilt + mkdir -p .prebuilt + docker build -q -f deploy/Dockerfile.cross -t bokf-cross deploy/ >/dev/null + docker run --rm -e "VERSION=$TAG" -v "$PWD":/src:ro \ + -v "$PWD/.prebuilt":/out bokf-cross + if command -v file >/dev/null 2>&1 && + ! file .prebuilt/bokfd | grep -q aarch64; then + echo "deploy: cross-build produced no arm64 binary" >&2 + rm -rf .prebuilt + exit 1 + fi + echo "deploy: assembling image bokf:$TAG on $BOKF_HOST" tar -cf - \ --exclude=./.git --exclude=./build --exclude=./var --exclude=./.env \ --exclude='./*.se' --exclude='./*.db' --exclude='./*.db-wal' \ --exclude='./*.db-shm' --exclude=./docs . | "${SSH[@]}" "docker build --build-arg 'VERSION=$TAG' -t 'bokf:$TAG' -" + rm -rf .prebuilt fi remote "mkdir -p '$BOKF_REMOTE_DIR'" -- cgit v1.3