camera-trng/scripts/build-release.sh

216 lines
6.1 KiB
Bash
Executable File

#!/usr/bin/env bash
# Build camera-qrng for multiple platforms.
# Usage: ./scripts/build-release.sh [target...]
#
# Targets:
# native - Build for current platform (default)
# aarch64-apple - Apple Silicon (M1/M2/M3)
# x86_64-apple - Intel Mac
# aarch64-linux - Linux ARM64 (Raspberry Pi 4/5, etc.)
# x86_64-linux - Linux x86_64
# all - Build all targets
#
# Prerequisites:
# - Rust toolchain with cross-compilation targets
# - For Linux cross-compile from macOS: cross (cargo install cross)
#
# Install targets:
# rustup target add aarch64-apple-darwin x86_64-apple-darwin
# rustup target add aarch64-unknown-linux-gnu x86_64-unknown-linux-gnu
set -e
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
OUTPUT_DIR="$PROJECT_DIR/release"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
info() { echo -e "${GREEN}[INFO]${NC} $1"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
error() { echo -e "${RED}[ERROR]${NC} $1"; exit 1; }
get_rust_target() {
case "$1" in
aarch64-apple) echo "aarch64-apple-darwin" ;;
x86_64-apple) echo "x86_64-apple-darwin" ;;
aarch64-linux) echo "aarch64-unknown-linux-gnu" ;;
x86_64-linux) echo "x86_64-unknown-linux-gnu" ;;
*) echo "" ;;
esac
}
get_friendly_name() {
case "$1" in
aarch64-apple) echo "Apple Silicon (M1/M2/M3)" ;;
x86_64-apple) echo "Intel Mac" ;;
aarch64-linux) echo "Linux ARM64 (Raspberry Pi)" ;;
x86_64-linux) echo "Linux x86_64" ;;
*) echo "$1" ;;
esac
}
get_output_name() {
case "$1" in
aarch64-apple) echo "camera-qrng-aarch64-macos" ;;
x86_64-apple) echo "camera-qrng-x86_64-macos" ;;
aarch64-linux) echo "camera-qrng-aarch64-linux" ;;
x86_64-linux) echo "camera-qrng-x86_64-linux" ;;
*) echo "camera-qrng-$1" ;;
esac
}
build_native() {
info "Building for native platform..."
cargo build --release
local binary="$PROJECT_DIR/target/release/camera-qrng"
if [[ -f "$binary" ]]; then
cp "$binary" "$OUTPUT_DIR/camera-qrng-native"
info "Built: $OUTPUT_DIR/camera-qrng-native"
file "$OUTPUT_DIR/camera-qrng-native"
fi
}
build_target() {
local shortname=$1
local target
target=$(get_rust_target "$shortname")
local friendly
friendly=$(get_friendly_name "$shortname")
local output_name
output_name=$(get_output_name "$shortname")
if [[ -z "$target" ]]; then
error "Unknown target: $shortname"
fi
info "Building for $friendly ($target)..."
# Check if target is installed
if ! rustup target list --installed 2>/dev/null | grep -q "$target"; then
warn "Target $target not installed. Installing..."
rustup target add "$target" || {
warn "Failed to add target $target. Skipping."
return 1
}
fi
# For Linux targets from macOS, try cross first
local use_cross=false
if [[ "$OSTYPE" == "darwin"* ]] && [[ "$target" == *"linux"* ]]; then
if command -v cross &> /dev/null; then
use_cross=true
else
warn "Linux cross-compilation requires 'cross'. Install with: cargo install cross"
warn "Attempting native cargo build (may fail due to linker issues)..."
fi
fi
if [[ "$use_cross" == true ]]; then
cross build --release --target "$target" 2>&1 || {
warn "Cross build failed for $target"
return 1
}
else
cargo build --release --target "$target" 2>&1 || {
warn "Build failed for $target"
return 1
}
fi
local binary="$PROJECT_DIR/target/$target/release/camera-qrng"
if [[ -f "$binary" ]]; then
cp "$binary" "$OUTPUT_DIR/$output_name"
info "Built: $OUTPUT_DIR/$output_name"
file "$OUTPUT_DIR/$output_name"
else
warn "Binary not found at $binary"
return 1
fi
}
install_manpage() {
info "Copying manpage..."
if [[ -f "$PROJECT_DIR/man/camera-qrng.1" ]]; then
cp "$PROJECT_DIR/man/camera-qrng.1" "$OUTPUT_DIR/"
gzip -c "$PROJECT_DIR/man/camera-qrng.1" > "$OUTPUT_DIR/camera-qrng.1.gz"
info "Manpage: $OUTPUT_DIR/camera-qrng.1.gz"
fi
}
show_usage() {
cat << EOF
Usage: $0 [target...]
Targets:
native Build for current platform (default)
aarch64-apple Apple Silicon (M1/M2/M3)
x86_64-apple Intel Mac
aarch64-linux Linux ARM64 (Raspberry Pi 4/5)
x86_64-linux Linux x86_64
all Build all targets
Examples:
$0 # Build native only
$0 all # Build all platforms
$0 aarch64-apple # Build Apple Silicon only
$0 aarch64-linux x86_64-linux # Build Linux targets
EOF
}
main() {
cd "$PROJECT_DIR"
mkdir -p "$OUTPUT_DIR"
local success=0
local failed=0
# Default to native if no args
if [[ $# -eq 0 ]]; then
set -- "native"
fi
# Process targets
for target in "$@"; do
case "$target" in
-h|--help)
show_usage
exit 0
;;
all)
for t in native aarch64-apple x86_64-apple aarch64-linux x86_64-linux; do
if [[ "$t" == "native" ]]; then
build_native && success=$((success+1)) || failed=$((failed+1))
else
build_target "$t" && success=$((success+1)) || failed=$((failed+1))
fi
done
;;
native)
build_native && success=$((success+1)) || failed=$((failed+1))
;;
*)
build_target "$target" && success=$((success+1)) || failed=$((failed+1))
;;
esac
done
install_manpage
echo ""
info "Build complete: $success succeeded, $failed failed"
echo ""
info "Release artifacts in: $OUTPUT_DIR/"
ls -la "$OUTPUT_DIR/"
if [[ $failed -gt 0 ]]; then
exit 1
fi
}
main "$@"