Archived
163 lines
5.9 KiB
Bash
Executable File
163 lines
5.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# build-targets.sh — Build the El VM (elvm) for all supported platforms.
|
|
#
|
|
# Usage:
|
|
# ./build-targets.sh # build all targets
|
|
# ./build-targets.sh --list # list targets and prerequisites
|
|
# ./build-targets.sh x86_64-apple-darwin # build a specific target
|
|
#
|
|
# Prerequisites:
|
|
# - Rust toolchain (rustup) with cross-compilation targets installed
|
|
# - For Linux targets: cross-linkers (see comments below)
|
|
#
|
|
# Install a target:
|
|
# rustup target add <target>
|
|
#
|
|
# For cross-compilation from macOS to Linux:
|
|
# brew install FiloSottile/musl-cross/musl-cross
|
|
# # or use `cross` (https://github.com/cross-rs/cross):
|
|
# cargo install cross --git https://github.com/cross-rs/cross
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
OUTPUT_DIR="${SCRIPT_DIR}/dist/elvm"
|
|
|
|
# ── Target definitions ────────────────────────────────────────────────────────
|
|
# Format: "target:description:linker_hint"
|
|
declare -a TARGETS=(
|
|
"x86_64-unknown-linux-gnu:Linux x86_64 (glibc):brew install FiloSottile/musl-cross/musl-cross or use 'cross'"
|
|
"aarch64-unknown-linux-gnu:Linux ARM64 (glibc):brew install FiloSottile/musl-cross/musl-cross or use 'cross'"
|
|
"x86_64-unknown-linux-musl:Linux x86_64 (musl, static):brew install FiloSottile/musl-cross/musl-cross"
|
|
"aarch64-unknown-linux-musl:Linux ARM64 (musl, static):brew install aarch64-unknown-linux-musl cross-linker"
|
|
"x86_64-apple-darwin:macOS Intel:native (no cross tooling needed on macOS)"
|
|
"aarch64-apple-darwin:macOS Apple Silicon:native (no cross tooling needed on macOS)"
|
|
"x86_64-pc-windows-gnu:Windows x86_64:brew install mingw-w64"
|
|
"aarch64-pc-windows-msvc:Windows ARM64:requires Windows MSVC SDK (Windows only)"
|
|
)
|
|
|
|
# ── Helpers ───────────────────────────────────────────────────────────────────
|
|
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m' # No Color
|
|
|
|
ok() { echo -e " ${GREEN}✓${NC} $*"; }
|
|
warn() { echo -e " ${YELLOW}⚠${NC} $*"; }
|
|
fail() { echo -e " ${RED}✗${NC} $*"; }
|
|
|
|
# ── List mode ─────────────────────────────────────────────────────────────────
|
|
|
|
if [[ "${1:-}" == "--list" ]]; then
|
|
echo ""
|
|
echo "El VM cross-compilation targets"
|
|
echo "================================"
|
|
echo ""
|
|
for entry in "${TARGETS[@]}"; do
|
|
IFS=':' read -r target desc hint <<< "$entry"
|
|
printf " %-42s %s\n" "$target" "$desc"
|
|
printf " %-42s Prereq: %s\n" "" "$hint"
|
|
echo ""
|
|
done
|
|
echo "Install a target: rustup target add <target>"
|
|
echo "List installed: rustup target list --installed"
|
|
exit 0
|
|
fi
|
|
|
|
# ── Filter targets ────────────────────────────────────────────────────────────
|
|
|
|
if [[ $# -gt 0 && "${1:-}" != "--list" ]]; then
|
|
# Build only the specified target(s).
|
|
SELECTED=("$@")
|
|
else
|
|
# Build all targets.
|
|
SELECTED=()
|
|
for entry in "${TARGETS[@]}"; do
|
|
IFS=':' read -r target _ _ <<< "$entry"
|
|
SELECTED+=("$target")
|
|
done
|
|
fi
|
|
|
|
# ── Build ─────────────────────────────────────────────────────────────────────
|
|
|
|
echo ""
|
|
echo -e "${BLUE}El VM — cross-platform build${NC}"
|
|
echo "Output directory: $OUTPUT_DIR"
|
|
echo ""
|
|
|
|
mkdir -p "$OUTPUT_DIR"
|
|
|
|
BUILT=0
|
|
SKIPPED=0
|
|
FAILED=0
|
|
|
|
for target in "${SELECTED[@]}"; do
|
|
# Find description for this target.
|
|
desc="$target"
|
|
for entry in "${TARGETS[@]}"; do
|
|
IFS=':' read -r t d _ <<< "$entry"
|
|
if [[ "$t" == "$target" ]]; then desc="$d"; break; fi
|
|
done
|
|
|
|
echo -e "${BLUE}→ Building $target${NC} ($desc)"
|
|
|
|
# Check if the Rust target is installed.
|
|
if ! rustup target list --installed 2>/dev/null | grep -q "^$target\b"; then
|
|
warn "Target $target not installed — installing..."
|
|
if rustup target add "$target" 2>/dev/null; then
|
|
ok "Installed $target"
|
|
else
|
|
fail "Cannot install $target — skipping"
|
|
((SKIPPED++))
|
|
continue
|
|
fi
|
|
fi
|
|
|
|
# Attempt to build.
|
|
binary_suffix=""
|
|
if [[ "$target" == *"windows"* ]]; then
|
|
binary_suffix=".exe"
|
|
fi
|
|
|
|
binary_name="elvm-${target}${binary_suffix}"
|
|
output_path="$OUTPUT_DIR/$binary_name"
|
|
|
|
if (cd "$SCRIPT_DIR" && cargo build --release --target "$target" -p elvm 2>&1 | tail -5); then
|
|
src="$SCRIPT_DIR/target/$target/release/elvm${binary_suffix}"
|
|
if [[ -f "$src" ]]; then
|
|
cp "$src" "$output_path"
|
|
size=$(du -h "$output_path" | cut -f1)
|
|
ok "Built $binary_name ($size)"
|
|
((BUILT++))
|
|
else
|
|
fail "Binary not found at $src"
|
|
((FAILED++))
|
|
fi
|
|
else
|
|
fail "Build failed for $target (cross-linker may be missing — see --list)"
|
|
((FAILED++))
|
|
fi
|
|
echo ""
|
|
done
|
|
|
|
# ── Summary ───────────────────────────────────────────────────────────────────
|
|
|
|
echo "────────────────────────────────"
|
|
echo "Built: $BUILT"
|
|
echo "Skipped: $SKIPPED"
|
|
echo "Failed: $FAILED"
|
|
|
|
if [[ $BUILT -gt 0 ]]; then
|
|
echo ""
|
|
echo "Artifacts:"
|
|
ls -lh "$OUTPUT_DIR/"
|
|
fi
|
|
|
|
echo ""
|
|
if [[ $FAILED -gt 0 ]]; then
|
|
echo -e "${YELLOW}Some targets failed. Run './build-targets.sh --list' for prerequisites.${NC}"
|
|
exit 1
|
|
fi
|