#!/usr/bin/env bash # Cross-compile quicproquo for musl targets (OpenWrt / embedded Linux). # # Produces statically linked, stripped binaries optimised for size. # Requires: cargo-zigbuild (preferred) or cross. # # Usage: # ./scripts/cross-compile.sh # all targets # ./scripts/cross-compile.sh x86_64-unknown-linux-musl # single target # # Output: target//release/qpq-server (stripped) set -euo pipefail TARGETS=( x86_64-unknown-linux-musl armv7-unknown-linux-musleabihf aarch64-unknown-linux-musl ) MAX_SIZE_MB=5 # Size-optimised release profile overrides. export CARGO_PROFILE_RELEASE_OPT_LEVEL=s export CARGO_PROFILE_RELEASE_LTO=true export CARGO_PROFILE_RELEASE_CODEGEN_UNITS=1 export CARGO_PROFILE_RELEASE_STRIP=symbols # Detect build tool. if command -v cargo-zigbuild &>/dev/null; then BUILD_CMD="cargo zigbuild" elif command -v cross &>/dev/null; then BUILD_CMD="cross build" else echo "ERROR: Install cargo-zigbuild or cross first:" >&2 echo " cargo install cargo-zigbuild # recommended" >&2 echo " cargo install cross # alternative" >&2 exit 1 fi # If arguments provided, use those as targets. if [ $# -gt 0 ]; then TARGETS=("$@") fi SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" cd "$PROJECT_ROOT" echo "=== quicproquo cross-compilation ===" echo "Build tool: $BUILD_CMD" echo "Targets: ${TARGETS[*]}" echo "" FAILED=() for target in "${TARGETS[@]}"; do echo "--- Building for $target ---" if $BUILD_CMD --release --target "$target" --bin qpq-server; then BINARY="target/$target/release/qpq-server" if [ -f "$BINARY" ]; then SIZE=$(stat -c%s "$BINARY" 2>/dev/null || stat -f%z "$BINARY") SIZE_MB=$(echo "scale=2; $SIZE / 1048576" | bc) MAX_BYTES=$((MAX_SIZE_MB * 1048576)) echo " Binary: $BINARY" echo " Size: ${SIZE_MB} MB" if [ "$SIZE" -gt "$MAX_BYTES" ]; then echo " WARNING: Binary exceeds ${MAX_SIZE_MB} MB size limit!" FAILED+=("$target (size: ${SIZE_MB} MB)") else echo " OK: within ${MAX_SIZE_MB} MB limit" fi else echo " ERROR: Binary not found at $BINARY" FAILED+=("$target (binary not found)") fi else echo " ERROR: Build failed for $target" FAILED+=("$target (build failed)") fi echo "" done if [ ${#FAILED[@]} -gt 0 ]; then echo "=== FAILURES ===" for f in "${FAILED[@]}"; do echo " - $f" done exit 1 fi echo "=== All targets built successfully ==="