216 lines
6.1 KiB
Bash
Executable File
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 "$@"
|