diff --git a/Cross.toml b/Cross.toml new file mode 100644 index 000000000..4c94ab261 --- /dev/null +++ b/Cross.toml @@ -0,0 +1,5 @@ +[target.aarch64-unknown-linux-gnu] +dockerfile = { file = "Dockerfile.cross-aarch64", context = "." } + +[build.env] +passthrough = ["SPACEBOT_SKIP_FRONTEND_BUILD"] diff --git a/Dockerfile.cross-aarch64 b/Dockerfile.cross-aarch64 new file mode 100644 index 000000000..e76f1e88c --- /dev/null +++ b/Dockerfile.cross-aarch64 @@ -0,0 +1,49 @@ +FROM ubuntu:22.04 + +ENV DEBIAN_FRONTEND=noninteractive + +# Host (amd64) compiler + cross-compilation toolchain + build tools +RUN apt-get update && apt-get install -y --no-install-recommends \ + gcc \ + g++ \ + libc6-dev \ + gcc-aarch64-linux-gnu \ + g++-aarch64-linux-gnu \ + libc6-dev-arm64-cross \ + libstdc++-12-dev-arm64-cross \ + pkg-config \ + cmake \ + make \ + curl \ + unzip \ + ca-certificates \ + && rm -rf /var/lib/apt/lists/* + +# ARM64 sysroot libraries (arm64 packages come from ports.ubuntu.com) +RUN dpkg --add-architecture arm64 \ + && sed -i 's/^deb /deb [arch=amd64] /' /etc/apt/sources.list \ + && echo "deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports jammy main restricted universe multiverse" >> /etc/apt/sources.list \ + && echo "deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports jammy-updates main restricted universe multiverse" >> /etc/apt/sources.list \ + && echo "deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports jammy-security main restricted universe multiverse" >> /etc/apt/sources.list \ + && apt-get update \ + && apt-get install -y --no-install-recommends libssl-dev:arm64 libsqlite3-dev:arm64 \ + && rm -rf /var/lib/apt/lists/* + +# protoc (x86_64 host binary for prost/lancedb build-time codegen) +RUN curl -fsSL -o /tmp/protoc.zip \ + https://github.com/protocolbuffers/protobuf/releases/download/v29.3/protoc-29.3-linux-x86_64.zip \ + && unzip /tmp/protoc.zip -d /usr/local \ + && chmod +x /usr/local/bin/protoc \ + && rm /tmp/protoc.zip + +# Cross-compilation environment +ENV CROSS_TOOLCHAIN_PREFIX=aarch64-linux-gnu- \ + CROSS_SYSROOT=/usr/aarch64-linux-gnu \ + CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc \ + PKG_CONFIG_ALLOW_CROSS=1 \ + PKG_CONFIG_PATH=/usr/lib/aarch64-linux-gnu/pkgconfig \ + OPENSSL_NO_VENDOR=1 \ + OPENSSL_LIB_DIR=/usr/lib/aarch64-linux-gnu \ + OPENSSL_INCLUDE_DIR=/usr/include \ + SQLITE3_LIB_DIR=/usr/lib/aarch64-linux-gnu \ + SQLITE3_INCLUDE_DIR=/usr/include diff --git a/README.md b/README.md index 0c17bb3ac..e25040f6f 100644 --- a/README.md +++ b/README.md @@ -432,6 +432,22 @@ cd spacebot cargo build --release ``` +#### Cross-compile for ARM (aarch64) + +To build for Raspberry Pi or other aarch64 Linux machines from an x86_64 host: + +```bash +# Install cross (once) +cargo install cross --locked + +# Build (frontend is skipped automatically) +just build-aarch64 +# Output: target/aarch64-unknown-linux-gnu/release/spacebot +``` + +The included `Dockerfile.cross-aarch64` provides the aarch64 cross-toolchain +and sysroot libraries. CI uses native ARM runners — this is for local builds. + ### Minimal Config Create `config.toml`: diff --git a/justfile b/justfile index 1785de972..fce0337ff 100644 --- a/justfile +++ b/justfile @@ -38,3 +38,9 @@ gate-pr-ci-fast: preflight-ci # and outputs to interface/public/opencode-embed/. build-opencode-embed: ./scripts/build-opencode-embed.sh + +# Cross-compile for aarch64 Linux (Raspberry Pi, ARM servers). +# Requires: cargo install cross --locked +# Output: target/aarch64-unknown-linux-gnu/release/spacebot +build-aarch64: + SPACEBOT_SKIP_FRONTEND_BUILD=1 cross build --target aarch64-unknown-linux-gnu --release