#!/bin/sh # Build release binaries for distribution. # Builds a native binary for the current OS, plus Windows (cross-compile). # # Usage: # ./build-release.sh # version from Cargo.toml (e.g. 1.0.0) # ./build-release.sh beta1 # appends suffix (e.g. 1.0.0-beta1) # ./build-release.sh rc1 # appends suffix (e.g. 1.0.0-rc1) # # Supported host platforms: # Linux -- builds linux-x86_64 + windows-x86_64 (via MinGW) # FreeBSD -- builds freebsd-x86_64 + windows-x86_64 (via MinGW) # Windows -- use build-release.ps1 instead # # To produce all three native binaries, run this script on both # Linux and FreeBSD, then collect artifacts from both runs. # # Cross-compile Linux<->FreeBSD is not supported (requires a full sysroot). set -e # Detect host OS OS="$(uname -s)" case "$OS" in Linux) HOST="linux" ;; FreeBSD) HOST="freebsd" ;; Darwin) HOST="macos" ;; *) echo "Unsupported host OS: $OS" echo "Use build-release.ps1 on Windows." exit 1 ;; esac # Read version from the single source of truth: Cargo.toml BASE_VERSION=$(grep '^version' Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/' | tr -d '\r') if [ -z "$BASE_VERSION" ]; then echo "Error: Could not read version from Cargo.toml" exit 1 fi # Optional pre-release suffix (beta1, rc1, etc.) # Strip a leading 'v' if passed by accident (e.g. v1.0.0 -> ignored, 1.0.0 used from Cargo.toml) SUFFIX="${1#v}" if [ -n "$SUFFIX" ]; then VERSION="${BASE_VERSION}-${SUFFIX}" else VERSION="$BASE_VERSION" fi RELEASE_DIR="release-artifacts" echo "Building Anvil v${VERSION} release binaries..." echo " Host platform: ${HOST}" echo " Version base: ${BASE_VERSION} (from Cargo.toml)" if [ -n "$SUFFIX" ]; then echo " Suffix: ${SUFFIX}" fi echo "" # Clean previous artifacts rm -rf "$RELEASE_DIR" mkdir -p "$RELEASE_DIR" # -- Native binary ----------------------------------------------------------- echo "Building ${HOST} x86_64 binary..." cargo build --release strip target/release/anvil 2>/dev/null || true echo "Packaging ${HOST} binary..." cd target/release tar -czf "../../$RELEASE_DIR/anvil-${VERSION}-${HOST}-x86_64.tar.gz" anvil cd ../.. # -- Windows binary (cross-compile via MinGW) -------------------------------- echo "" echo "Building Windows x86_64 binary (cross-compile)..." # rustup is required to add cross-compile targets. # On FreeBSD, Rust is typically installed via pkg and rustup is not available. if ! command -v rustup > /dev/null 2>&1; then echo " rustup not found -- Windows cross-compile requires rustup." case "$HOST" in freebsd) echo " On FreeBSD, install rustup via: curl https://sh.rustup.rs -sSf | sh" ;; *) echo " Install rustup from: https://rustup.rs" ;; esac echo "Skipping Windows build." elif ! command -v x86_64-w64-mingw32-gcc > /dev/null 2>&1; then case "$HOST" in linux) echo " MinGW not found. Install with: sudo apt install mingw-w64" ;; freebsd) echo " MinGW not available in FreeBSD pkg repos." echo " Windows binary must be built on Linux (boot into Linux or use a bhyve VM)." ;; esac echo "Skipping Windows build." else # Ensure Windows target is installed if ! rustup target list | grep -q "x86_64-pc-windows-gnu (installed)"; then echo "Installing Windows cross-compile target..." rustup target add x86_64-pc-windows-gnu fi cargo build --release --target x86_64-pc-windows-gnu x86_64-w64-mingw32-strip target/x86_64-pc-windows-gnu/release/anvil.exe 2>/dev/null || true echo "Packaging Windows binary..." cd target/x86_64-pc-windows-gnu/release zip -q "../../../$RELEASE_DIR/anvil-${VERSION}-windows-x86_64.zip" anvil.exe cd ../../.. fi # -- Checksums --------------------------------------------------------------- echo "" echo "Generating checksums..." cd "$RELEASE_DIR" # sha256sum on Linux, sha256 on FreeBSD/macOS if command -v sha256sum > /dev/null 2>&1; then sha256sum * > SHA256SUMS else shasum -a 256 * > SHA256SUMS fi cd .. # -- Summary ----------------------------------------------------------------- echo "" echo "===========================================================" echo " Anvil v${VERSION} release artifacts built successfully!" echo "===========================================================" echo "" echo "Artifacts in $RELEASE_DIR/:" ls -lh "$RELEASE_DIR" echo "" echo "Checksums:" cat "$RELEASE_DIR/SHA256SUMS" echo "" case "$HOST" in freebsd) echo "FreeBSD binary built. To also ship a Linux binary:" echo " Option 1 (easiest): boot into Linux and run ./build-release.sh" echo " Option 2: run this script inside a Linux bhyve VM" echo " Option 3: set up a Linux CI runner (e.g. Gitea Actions)" echo " Then collect all artifacts before uploading to Gitea." ;; linux) echo "Linux binary built. To also ship a FreeBSD binary:" echo " Boot into FreeBSD and run ./build-release.sh" echo " Then collect all artifacts before uploading to Gitea." ;; esac echo "" echo "Upload to Gitea:" echo " 1. Create release: Releases -> New Release -> Tag: v${VERSION}" echo " 2. Drag and drop files from $RELEASE_DIR/" echo " 3. Save" echo ""