Files
archy/image-recipe/scripts/build-backend.sh
T

149 lines
5.5 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# Build Archipelago backend binary for Debian Linux
#
# Target architecture:
# (unset) native host build — unchanged default behavior
# ARCH=aarch64 build for ARM64 (Pi 5 test installs — see
# docs/raspberry-pi-test-install.md). On the M2 — our
# dedicated ARM64 build machine — this runs at native speed
# (Apple Silicon runs arm64 Linux containers natively).
# On x86_64 it prefers cargo-zigbuild (fast host cross
# build) or falls back to an emulated rust:trixie Docker
# build (needs qemu binfmt, slow).
#
# The backend is rustls-only (no OpenSSL dependency), so cross-building needs
# just a rustup target + the zig linker — no sysroot libraries.
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
BACKEND_DIR="$PROJECT_ROOT/core/archipelago"
OUTPUT_DIR="$SCRIPT_DIR/../build/backend"
# Resolve target architecture / cross-compile triple.
ARCH="${ARCH:-native}"
# Normalize uname -m into our arch vocabulary (macOS reports arm64; the M2
# builder is an arm64 host even though it produces Linux binaries via Docker).
case "$(uname -m)" in
x86_64|amd64) HOST_ARCH="x86_64" ;;
aarch64|arm64) HOST_ARCH="aarch64" ;;
*) HOST_ARCH="$(uname -m)" ;;
esac
CROSS_TARGET=""
case "$ARCH" in
native) ;;
aarch64|x86_64)
if [[ "$ARCH" == "$HOST_ARCH" && "$OSTYPE" != "darwin"* ]]; then
# Linux host building for itself — plain native build
echo "ℹ️ ARCH=$ARCH matches host — building natively"
else
# Explicit target triple — on Apple Silicon (M2) the arm64
# container runs natively; only x86_64 hosts emulate.
CROSS_TARGET="${ARCH}-unknown-linux-gnu"
echo "🎯 Building for $ARCH ($CROSS_TARGET)"
fi
;;
*) echo "❌ ARCH must be 'native', 'aarch64' or 'x86_64' (got: $ARCH)" >&2; exit 1 ;;
esac
OUT_NAME="archipelago"
if [ -n "$CROSS_TARGET" ]; then
OUT_NAME="archipelago-${ARCH}"
fi
echo "🔨 Building Archipelago backend..."
echo " Source: $BACKEND_DIR"
echo " Output: $OUTPUT_DIR/$OUT_NAME"
echo ""
# Create output directory
mkdir -p "$OUTPUT_DIR"
# Check if we should use Docker
USE_DOCKER=false
if [[ "$OSTYPE" == "darwin"* ]]; then
USE_DOCKER=true
echo "🍎 macOS detected - using Docker for Linux build"
elif ! command -v rustc >/dev/null 2>&1; then
USE_DOCKER=true
echo "⚠️ Rust not found - using Docker"
fi
# Cross-build without cargo-zigbuild (e.g. system rust without rustup targets)
# falls back to the emulated Docker path instead of hard-failing.
if [ "$USE_DOCKER" != true ] && [ -n "$CROSS_TARGET" ] \
&& ! command -v cargo-zigbuild >/dev/null 2>&1; then
echo "⚠️ cargo-zigbuild not found — using the emulated Docker build (slow)"
USE_DOCKER=true
fi
if [ "$USE_DOCKER" = true ]; then
echo "🐳 Building in Docker container..."
# Cross builds in Docker use --platform for an emulated target-arch rust
# toolchain (needs qemu binfmt; slow but zero host setup). An explicit
# --target keeps the shared target/ dir from colliding with host-arch
# builds.
PLATFORM_ARGS=""
INNER_BUILD="cargo build --release"
INNER_COPY="cp ../target/release/archipelago /output/${OUT_NAME}"
if [ -n "$CROSS_TARGET" ]; then
PLATFORM_ARGS="--platform linux/$([[ "$ARCH" == "aarch64" ]] && echo arm64 || echo amd64)"
INNER_BUILD="rustup target add ${CROSS_TARGET} && cargo build --release --target ${CROSS_TARGET}"
INNER_COPY="cp ../target/${CROSS_TARGET}/release/archipelago /output/${OUT_NAME}"
if [[ "$(uname -m)" == "arm64" && "$ARCH" == "aarch64" ]]; then
echo " (Apple Silicon — arm64 containers run natively here)"
else
echo " (emulated ${ARCH} build — expect it to be slow)"
fi
fi
# shellcheck disable=SC2086
docker run --rm \
-v "$PROJECT_ROOT:/workspace" \
-v "$OUTPUT_DIR:/output" \
-w /workspace/core/archipelago \
$PLATFORM_ARGS \
rust:trixie \
sh -c "
echo '📦 Installing build dependencies...'
apt-get update && apt-get install -y pkg-config libssl-dev
echo '🔨 Building Archipelago backend...'
${INNER_BUILD}
echo '📋 Copying binary to output...'
${INNER_COPY}
echo '✅ Build complete!'
ls -lh /output/
"
elif [ -n "$CROSS_TARGET" ]; then
# Host-side cross build: cargo-zigbuild (zig as linker) — much faster than
# the emulated Docker path. On Arch: pacman -S cargo-zigbuild (pulls zig).
echo "🐧 Cross-compiling on host with cargo-zigbuild..."
rustup target add "$CROSS_TARGET"
cd "$BACKEND_DIR"
cargo zigbuild --release --target "$CROSS_TARGET"
cp "../target/${CROSS_TARGET}/release/archipelago" "$OUTPUT_DIR/$OUT_NAME"
else
# Native Linux build
echo "🐧 Building natively..."
cd "$BACKEND_DIR"
cargo build --release
cp "../target/release/archipelago" "$OUTPUT_DIR/archipelago"
fi
# Strip binary for smaller size (GNU strip handles foreign-arch ELF too).
if [ -f "$OUTPUT_DIR/$OUT_NAME" ]; then
if command -v strip >/dev/null 2>&1 && [[ "$OSTYPE" != "darwin"* ]]; then
strip "$OUTPUT_DIR/$OUT_NAME"
fi
echo ""
echo "✅ Backend built: $OUTPUT_DIR/$OUT_NAME"
ls -lh "$OUTPUT_DIR/$OUT_NAME"
else
echo "❌ Build failed - binary not found"
exit 1
fi