From 0c2de8890970fe8572cb712f807085d535fd556e Mon Sep 17 00:00:00 2001 From: thanos Date: Sat, 10 Jan 2026 16:31:48 +0200 Subject: [PATCH] Add cross-platform build scripts and infrastructure This commit adds comprehensive cross-platform build and testing infrastructure for rust-bottle, enabling automated builds across all supported platforms from a single macOS/ARM development machine. New Features: - Cross-platform build scripts for macOS/ARM, macOS/x86_64, Linux/x86_64, and Linux/ARM64 - Docker and Podman support for Linux builds with automatic runtime detection - Dockerfiles for Linux x86_64 and ARM64 builds using latest Rust - Prerequisites checking script to verify build environment setup - Quick build test script for fast compilation verification - Alternative build script using cross tool for efficient cross-compilation - Comprehensive build documentation in scripts/README_BUILD.md Infrastructure: - Added .cargo/config.toml for cross-compilation linker configuration - Updated .gitignore to allow .cargo/config.toml while ignoring other cargo files - Docker images use rust:latest to support Cargo.lock v4 format - All scripts are bash 3.2+ compatible for macOS compatibility Build Scripts: - build-all-platforms.sh: Orchestrates builds for all platforms - build-macos-arm.sh: Native macOS/ARM builds - build-macos-x86_64.sh: macOS/x86_64 builds using Rosetta 2 - build-linux-x86_64.sh: Linux/x86_64 builds using Docker/Podman - build-linux-arm64.sh: Linux/ARM64 builds using Docker/Podman - build-using-cross.sh: Alternative using cross tool - check-prerequisites.sh: Verify required tools and setup - quick-build-test.sh: Quick compilation test without full test suite Docker Support: - Dockerfile.linux-x86_64: Linux x86_64 build environment - Dockerfile.linux-arm64: Linux ARM64 build environment with cross-compilation - .dockerignore: Excludes unnecessary files from Docker builds - Automatic detection of Docker vs Podman (prefers Podman if available) Documentation: - scripts/README_BUILD.md: Complete guide for cross-platform builds - Includes troubleshooting, prerequisites, and usage examples - Documents Docker vs Podman differences and usage This infrastructure enables: - Automated testing across all target platforms - CI/CD integration for multi-platform builds - Easy verification of cross-compilation setup - Consistent build environments across development machines --- .cargo/config.toml | 22 +++ .gitignore | 5 + scripts/.dockerignore | 15 ++ scripts/Dockerfile.linux-arm64 | 31 ++++ scripts/Dockerfile.linux-x86_64 | 24 +++ scripts/README_BUILD.md | 284 ++++++++++++++++++++++++++++++++ scripts/build-all-platforms.sh | 155 +++++++++++++++++ scripts/build-linux-arm64.sh | 122 ++++++++++++++ scripts/build-linux-x86_64.sh | 119 +++++++++++++ scripts/build-macos-arm.sh | 90 ++++++++++ scripts/build-macos-x86_64.sh | 94 +++++++++++ scripts/build-using-cross.sh | 103 ++++++++++++ scripts/check-prerequisites.sh | 166 +++++++++++++++++++ scripts/quick-build-test.sh | 98 +++++++++++ 14 files changed, 1328 insertions(+) create mode 100644 .cargo/config.toml create mode 100644 scripts/.dockerignore create mode 100644 scripts/Dockerfile.linux-arm64 create mode 100644 scripts/Dockerfile.linux-x86_64 create mode 100644 scripts/README_BUILD.md create mode 100755 scripts/build-all-platforms.sh create mode 100755 scripts/build-linux-arm64.sh create mode 100755 scripts/build-linux-x86_64.sh create mode 100755 scripts/build-macos-arm.sh create mode 100755 scripts/build-macos-x86_64.sh create mode 100755 scripts/build-using-cross.sh create mode 100755 scripts/check-prerequisites.sh create mode 100755 scripts/quick-build-test.sh diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000..681b1c7 --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,22 @@ +# Cargo configuration for cross-compilation +# This file helps configure cross-compilation targets + +[target.x86_64-apple-darwin] +# macOS x86_64 (Intel) - uses native toolchain or Rosetta 2 + +[target.aarch64-apple-darwin] +# macOS ARM64 (Apple Silicon) - native + +[target.x86_64-unknown-linux-gnu] +# Linux x86_64 - for Docker builds +linker = "x86_64-linux-gnu-gcc" + +[target.aarch64-unknown-linux-gnu] +# Linux ARM64 - for Docker builds with cross-compilation +linker = "aarch64-linux-gnu-gcc" + +# Build configuration +[build] +# Uncomment to set default target +# default-target = "aarch64-apple-darwin" + diff --git a/.gitignore b/.gitignore index aa04385..0046796 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,11 @@ **/*.rs.bk Cargo.lock +# Cargo configuration +# Allow .cargo/config.toml (project settings) but ignore other files +.cargo/* +!.cargo/config.toml + # Coverage reports coverage/ *.profraw diff --git a/scripts/.dockerignore b/scripts/.dockerignore new file mode 100644 index 0000000..daabf8c --- /dev/null +++ b/scripts/.dockerignore @@ -0,0 +1,15 @@ +# Docker ignore file for rust-bottle builds +target/ +.git/ +.gitignore +*.md +!README.md +coverage/ +.vscode/ +.idea/ +*.swp +*.swo +*~ +.DS_Store +Cargo.lock + diff --git a/scripts/Dockerfile.linux-arm64 b/scripts/Dockerfile.linux-arm64 new file mode 100644 index 0000000..7f17192 --- /dev/null +++ b/scripts/Dockerfile.linux-arm64 @@ -0,0 +1,31 @@ +# Dockerfile for building rust-bottle on Linux/ARM64 +# This can use native ARM64 Docker or QEMU emulation +# Using latest stable Rust to support Cargo.lock v4 +FROM rust:latest + +# Install required dependencies +RUN apt-get update && apt-get install -y \ + build-essential \ + pkg-config \ + libssl-dev \ + ca-certificates \ + gcc-aarch64-linux-gnu \ + libc6-dev-arm64-cross \ + && rm -rf /var/lib/apt/lists/* + +# Install cross-compilation target +RUN rustup target add aarch64-unknown-linux-gnu + +# Set up cross-compilation linker +ENV CC_aarch64_unknown_linux_gnu=aarch64-linux-gnu-gcc +ENV CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc + +# Set working directory +WORKDIR /workspace + +# Pre-create target directory to avoid permission issues +RUN mkdir -p /workspace/target + +# Default command +CMD ["bash"] + diff --git a/scripts/Dockerfile.linux-x86_64 b/scripts/Dockerfile.linux-x86_64 new file mode 100644 index 0000000..ef5353c --- /dev/null +++ b/scripts/Dockerfile.linux-x86_64 @@ -0,0 +1,24 @@ +# Dockerfile for building rust-bottle on Linux/x86_64 +# Using latest stable Rust to support Cargo.lock v4 +FROM rust:latest + +# Install required dependencies +RUN apt-get update && apt-get install -y \ + build-essential \ + pkg-config \ + libssl-dev \ + ca-certificates \ + && rm -rf /var/lib/apt/lists/* + +# Install cross-compilation target (native for x86_64, but good to be explicit) +RUN rustup target add x86_64-unknown-linux-gnu + +# Set working directory +WORKDIR /workspace + +# Pre-create target directory to avoid permission issues +RUN mkdir -p /workspace/target + +# Default command +CMD ["bash"] + diff --git a/scripts/README_BUILD.md b/scripts/README_BUILD.md new file mode 100644 index 0000000..8f755ae --- /dev/null +++ b/scripts/README_BUILD.md @@ -0,0 +1,284 @@ +# Cross-Platform Build Scripts + +This directory contains scripts for building and testing `rust-bottle` on multiple platforms from a macOS/ARM (Apple Silicon) machine. + +## Supported Platforms + +- **macOS/ARM** (Apple Silicon) - Native build +- **macOS/x86_64** (Intel) - Using Rosetta 2 +- **Linux/x86_64** - Using Docker or Podman +- **Linux/ARM64** - Using Docker or Podman with cross-compilation + +## Prerequisites + +### Check Prerequisites + +Before running build scripts, check if all prerequisites are met: + +```bash +./scripts/check-prerequisites.sh +``` + +This will verify: +- Rust and Cargo installation +- Platform information +- Rosetta 2 availability (for macOS/x86_64) +- Docker or Podman installation and status +- Required Rust targets +- Optional `cross` tool + +### For All Builds +- Rust toolchain installed (`rustup`) +- Cargo installed + +### For macOS/x86_64 Builds +- Rosetta 2 installed (usually pre-installed on Apple Silicon Macs) + - If not installed: `softwareupdate --install-rosetta` + +### For Linux Builds +- **Docker** or **Podman** installed and working + - **Docker Desktop**: https://www.docker.com/products/docker-desktop + - **Podman**: https://podman.io/getting-started/installation + - Scripts automatically detect and use whichever is available (Podman is preferred if both are installed) + - Ensure Docker daemon is running (if using Docker) before executing Linux build scripts + - Podman doesn't require a daemon + +## Quick Start + +### Build All Platforms + +Run the main script to build for all platforms: + +```bash +./scripts/build-all-platforms.sh +``` + +This will: +1. Build for macOS/ARM (native) +2. Build for macOS/x86_64 (using Rosetta 2) +3. Build for Linux/x86_64 (using Docker or Podman) +4. Build for Linux/ARM64 (using Docker or Podman) + +### Build Individual Platforms + +You can also build for individual platforms: + +```bash +# macOS/ARM (native) +./scripts/build-macos-arm.sh + +# macOS/x86_64 (Rosetta 2) +./scripts/build-macos-x86_64.sh + +# Linux/x86_64 (Docker or Podman) +./scripts/build-linux-x86_64.sh + +# Linux/ARM64 (Docker or Podman) +./scripts/build-linux-arm64.sh +``` + +### Quick Build Test (Compilation Only) + +For a quick test that only checks compilation (no tests): + +```bash +./scripts/quick-build-test.sh +``` + +### Alternative: Using `cross` Tool + +For more efficient cross-compilation, you can use the `cross` tool: + +```bash +# Install cross first +cargo install cross --git https://github.com/cross-rs/cross + +# Run cross builds +./scripts/build-using-cross.sh +``` + +**Note**: The `cross` tool is faster for compilation but may not support running tests for all targets. Use container-based scripts (Docker/Podman) for full test coverage. + +## How It Works + +### macOS/ARM (Native) +- Uses the native Rust toolchain +- No special setup required +- Fastest build option + +### macOS/x86_64 (Rosetta 2) +- Uses `arch -x86_64` to run commands in x86_64 mode +- Automatically installs the `x86_64-apple-darwin` target +- All cargo commands run through Rosetta 2 + +### Linux/x86_64 (Docker/Podman) +- Uses Docker or Podman with the official Rust image +- Automatically detects and uses Podman if available, otherwise falls back to Docker +- Builds in a Linux container environment +- Uses native x86_64 container runtime (or emulation if needed) + +### Linux/ARM64 (Docker/Podman) +- Uses Docker or Podman with cross-compilation support +- Automatically detects and uses Podman if available, otherwise falls back to Docker +- Can use native ARM64 container runtime (if available) or QEMU emulation +- Installs cross-compilation toolchain (`gcc-aarch64-linux-gnu`) + +## Feature Testing + +All scripts test multiple feature combinations: +- Default (no features) +- `ml-kem` only +- `post-quantum` only +- `ml-kem,post-quantum` (all features) + +Each feature combination is built and tested. + +## Container Images + +The container images (Docker/Podman compatible) are built automatically when you run the Linux build scripts. They are based on: +- `rust:latest` - Official Rust Docker image (latest stable version) +- Includes build dependencies (build-essential, pkg-config, libssl-dev) +- Pre-configured with cross-compilation targets +- Supports Cargo.lock v4 format + +### Container Image Names +- `rust-bottle-linux-x86_64` - For Linux x86_64 builds +- `rust-bottle-linux-arm64` - For Linux ARM64 builds + +### Rebuilding Container Images + +Container images are automatically rebuilt if the Dockerfile changes. To force a rebuild: + +```bash +# Using Docker +docker build -f scripts/Dockerfile.linux-x86_64 -t rust-bottle-linux-x86_64 . +docker build -f scripts/Dockerfile.linux-arm64 -t rust-bottle-linux-arm64 . + +# Using Podman +podman build -f scripts/Dockerfile.linux-x86_64 -t rust-bottle-linux-x86_64 . +podman build -f scripts/Dockerfile.linux-arm64 -t rust-bottle-linux-arm64 . +``` + +**Note**: The scripts automatically detect whether to use Docker or Podman and use the appropriate command. + +## Troubleshooting + +### Rosetta 2 Not Available +If you get an error about Rosetta 2: +```bash +softwareupdate --install-rosetta +``` + +### Container Runtime Not Working +If container commands fail: + +**For Docker:** +1. Start Docker Desktop +2. Wait for it to fully start +3. Verify with: `docker info` + +**For Podman:** +1. Podman doesn't require a daemon, but verify it's working: `podman info` +2. On macOS, you may need Podman Machine: `podman machine init && podman machine start` +3. Verify with: `podman info` + +### Cross-Compilation Issues +If Linux ARM64 builds fail: +1. Ensure your container runtime (Docker/Podman) supports multi-platform builds +2. Check that QEMU is available (usually automatic with Docker Desktop or Podman) +3. Try building the container image manually to see detailed errors +4. For Podman, ensure `podman machine` is configured for multi-arch support + +### Rust Target Not Installed +The scripts automatically install required targets, but if you encounter issues: +```bash +# macOS targets +rustup target add aarch64-apple-darwin +rustup target add x86_64-apple-darwin + +# Linux targets (for container builds) +# These are installed inside containers automatically +``` + +### Permission Denied +If scripts are not executable: +```bash +chmod +x scripts/build-*.sh +``` + +## Build Artifacts + +Build artifacts are stored in: +- `target/aarch64-apple-darwin/release/` - macOS/ARM builds +- `target/x86_64-apple-darwin/release/` - macOS/x86_64 builds +- `target/x86_64-unknown-linux-gnu/release/` - Linux/x86_64 builds (in containers) +- `target/aarch64-unknown-linux-gnu/release/` - Linux/ARM64 builds (in containers) + +## Performance Notes + +- **macOS/ARM**: Fastest (native) +- **macOS/x86_64**: Slower (Rosetta 2 translation overhead) +- **Linux/x86_64**: Medium speed (container overhead, but native architecture) +- **Linux/ARM64**: Slowest (container + cross-compilation or emulation) + +## CI/CD Integration + +These scripts can be integrated into CI/CD pipelines: +- GitHub Actions +- GitLab CI +- CircleCI +- etc. + +Example GitHub Actions workflow: +```yaml +- name: Build all platforms + run: ./scripts/build-all-platforms.sh +``` + +## Advanced Usage + +### Building Specific Features Only + +You can modify the scripts to test only specific features by editing the `FEATURES` array in each script. + +### Custom Container Images + +You can customize the container images (Docker/Podman compatible) by editing the Dockerfiles: +- `scripts/Dockerfile.linux-x86_64` +- `scripts/Dockerfile.linux-arm64` + +### Parallel Builds + +The scripts run builds sequentially. For faster execution, you could modify them to run in parallel, but be aware of resource constraints (especially with containers). + +## Configuration + +Cross-compilation settings are configured in `.cargo/config.toml`. You can modify this file to adjust linker settings or add additional targets. + +## Podman vs Docker + +The scripts automatically detect and use **Podman** if available, otherwise fall back to **Docker**. Both are fully supported: + +### Podman Advantages +- No daemon required (rootless by default) +- Better security model (rootless containers) +- Docker-compatible commands +- Works well on macOS with Podman Machine + +### Docker Advantages +- More widely used and documented +- Better GUI support (Docker Desktop) +- More mature ecosystem + +### Which to Use? +- **Use Podman** if you prefer rootless containers and don't need Docker Desktop +- **Use Docker** if you want Docker Desktop's GUI and ecosystem +- Scripts work with either - they auto-detect what's available + +## See Also + +- [Rust Cross-Compilation Guide](https://rust-lang.github.io/rustup/cross-compilation.html) +- [Docker Multi-Platform Builds](https://docs.docker.com/build/building/multi-platform/) +- [Podman Documentation](https://docs.podman.io/) +- [Rosetta 2 Documentation](https://developer.apple.com/documentation/apple-silicon/about-the-rosetta-translation-environment) + diff --git a/scripts/build-all-platforms.sh b/scripts/build-all-platforms.sh new file mode 100755 index 0000000..b706981 --- /dev/null +++ b/scripts/build-all-platforms.sh @@ -0,0 +1,155 @@ +#!/bin/bash +# Cross-platform build script for rust-bottle +# Builds for: macOS/ARM, macOS/x86_64, Linux/x86_64, Linux/ARM64 +# Run from macOS/ARM (Apple Silicon) + +set -e + +# Colors for output +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +RED='\033[0;31m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Script directory +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" + +# Feature sets to test +declare -a FEATURES=( + "" + "ml-kem" + "post-quantum" + "ml-kem,post-quantum" +) + +# Results tracking (using arrays compatible with bash 3.2+) +RESULTS_TARGETS=() +RESULTS_STATUS=() +TOTAL_TARGETS=0 +PASSED_TARGETS=0 +FAILED_TARGETS=0 + +# Function to print header +print_header() { + echo "" + echo -e "${BLUE}========================================${NC}" + echo -e "${BLUE}$1${NC}" + echo -e "${BLUE}========================================${NC}" + echo "" +} + +# Function to print result +print_result() { + local target=$1 + local status=$2 + TOTAL_TARGETS=$((TOTAL_TARGETS + 1)) + + # Store results in parallel arrays + RESULTS_TARGETS+=("$target") + RESULTS_STATUS+=("$status") + + if [ "$status" = "PASS" ]; then + echo -e "${GREEN}✓ ${target}: PASSED${NC}" + PASSED_TARGETS=$((PASSED_TARGETS + 1)) + else + echo -e "${RED}✗ ${target}: FAILED${NC}" + FAILED_TARGETS=$((FAILED_TARGETS + 1)) + fi +} + +# Check if running on macOS +if [[ "$OSTYPE" != "darwin"* ]]; then + echo -e "${RED}ERROR: This script is designed to run on macOS${NC}" + exit 1 +fi + +# Check architecture +ARCH=$(uname -m) +if [ "$ARCH" != "arm64" ]; then + echo -e "${YELLOW}WARNING: This script is optimized for macOS/ARM (Apple Silicon)${NC}" + echo -e "${YELLOW}Some builds may not work as expected on Intel Macs${NC}" +fi + +print_header "Cross-Platform Build Test for rust-bottle" + +echo "Platform: macOS/ARM (Apple Silicon)" +echo "Targets:" +echo " - macOS/ARM (native)" +echo " - macOS/x86_64 (Rosetta 2)" +echo " - Linux/x86_64 (Docker)" +echo " - Linux/ARM64 (Docker)" +echo "" + +# Change to project root +cd "$PROJECT_ROOT" + +# 1. Native macOS/ARM build +print_header "1. Building for macOS/ARM (native)" +if "$SCRIPT_DIR/build-macos-arm.sh"; then + print_result "macOS/ARM" "PASS" +else + print_result "macOS/ARM" "FAIL" +fi + +# 2. macOS/x86_64 build using Rosetta 2 +print_header "2. Building for macOS/x86_64 (Rosetta 2)" +if "$SCRIPT_DIR/build-macos-x86_64.sh"; then + print_result "macOS/x86_64" "PASS" +else + print_result "macOS/x86_64" "FAIL" +fi + +# 3. Linux/x86_64 build using Docker +print_header "3. Building for Linux/x86_64 (Docker)" +if "$SCRIPT_DIR/build-linux-x86_64.sh"; then + print_result "Linux/x86_64" "PASS" +else + print_result "Linux/x86_64" "FAIL" +fi + +# 4. Linux/ARM64 build using Docker +print_header "4. Building for Linux/ARM64 (Docker)" +if "$SCRIPT_DIR/build-linux-arm64.sh"; then + print_result "Linux/ARM64" "PASS" +else + print_result "Linux/ARM64" "FAIL" +fi + +# Print summary +print_header "Build Summary" +echo "Total targets: $TOTAL_TARGETS" +echo -e "${GREEN}Passed: $PASSED_TARGETS${NC}" +if [ $FAILED_TARGETS -gt 0 ]; then + echo -e "${RED}Failed: $FAILED_TARGETS${NC}" +else + echo -e "${GREEN}Failed: $FAILED_TARGETS${NC}" +fi +echo "" + +# Print detailed results +echo "Detailed Results:" +# Use a counter instead of array indices for bash 3.2 compatibility +i=0 +while [ $i -lt ${#RESULTS_TARGETS[@]} ]; do + target="${RESULTS_TARGETS[$i]}" + status="${RESULTS_STATUS[$i]}" + if [ "$status" = "PASS" ]; then + echo -e " ${GREEN}✓${NC} $target" + else + echo -e " ${RED}✗${NC} $target" + fi + i=$((i + 1)) +done +echo "" + +# Exit with appropriate code +if [ $FAILED_TARGETS -eq 0 ]; then + echo -e "${GREEN}All builds completed successfully!${NC}" + exit 0 +else + echo -e "${RED}Some builds failed. Check the output above for details.${NC}" + exit 1 +fi + diff --git a/scripts/build-linux-arm64.sh b/scripts/build-linux-arm64.sh new file mode 100755 index 0000000..c6a4850 --- /dev/null +++ b/scripts/build-linux-arm64.sh @@ -0,0 +1,122 @@ +#!/bin/bash +# Build script for Linux/ARM64 using Docker or Podman +# Uses Docker/Podman with cross-compilation or QEMU emulation + +set -e + +# Colors for output +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +RED='\033[0;31m' +NC='\033[0m' # No Color + +# Script directory +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" + +# Feature sets to test +declare -a FEATURES=( + "" + "ml-kem" + "post-quantum" + "ml-kem,post-quantum" +) + +# Detect container runtime (Podman or Docker) +detect_container_runtime() { + if command -v podman &> /dev/null; then + if podman info &>/dev/null 2>&1; then + echo "podman" + return 0 + fi + fi + + if command -v docker &> /dev/null; then + if docker info &>/dev/null 2>&1; then + echo "docker" + return 0 + fi + fi + + return 1 +} + +# Detect and set container runtime +CONTAINER_RUNTIME=$(detect_container_runtime || echo "") + +if [ -z "$CONTAINER_RUNTIME" ]; then + echo -e "${RED}ERROR: Neither Docker nor Podman is available${NC}" + echo " Install Docker Desktop from: https://www.docker.com/products/docker-desktop" + echo " Or install Podman from: https://podman.io/getting-started/installation" + exit 1 +fi + +echo -e "${YELLOW}Building for Linux/ARM64 using ${CONTAINER_RUNTIME}${NC}" +echo "" + +# Change to project root +cd "$PROJECT_ROOT" + +# Docker image name +IMAGE_NAME="rust-bottle-linux-arm64" +DOCKERFILE="$SCRIPT_DIR/Dockerfile.linux-arm64" + +# Build Docker image if it doesn't exist or if Dockerfile is newer +if [ ! -f "$DOCKERFILE" ]; then + echo -e "${RED}ERROR: Dockerfile not found: $DOCKERFILE${NC}" + exit 1 +fi + +echo "Building container image: $IMAGE_NAME" +echo "Note: This may take a few minutes on first run..." +$CONTAINER_RUNTIME build -f "$DOCKERFILE" -t "$IMAGE_NAME" "$PROJECT_ROOT" + +# Run builds in Docker container +FAILED=0 +for features in "${FEATURES[@]}"; do + feature_name=${features:-"default"} + echo -e "${YELLOW}Building with features: ${feature_name}${NC}" + + # Prepare cargo command + if [ -z "$features" ]; then + CARGO_BUILD="cargo build --target aarch64-unknown-linux-gnu --release" + CARGO_TEST="cargo test --target aarch64-unknown-linux-gnu" + else + CARGO_BUILD="cargo build --target aarch64-unknown-linux-gnu --features $features --release" + CARGO_TEST="cargo test --target aarch64-unknown-linux-gnu --features $features" + fi + + # Build + # Note: Podman may not support --platform flag in all versions, but it's harmless + if ! $CONTAINER_RUNTIME run --rm \ + --platform linux/arm64 \ + -v "$PROJECT_ROOT:/workspace" \ + -w /workspace \ + "$IMAGE_NAME" \ + bash -c "$CARGO_BUILD"; then + echo -e "${RED}Build failed for ${feature_name}${NC}" + FAILED=1 + fi + + # Test + echo -e "${YELLOW}Running tests with features: ${feature_name}${NC}" + if ! $CONTAINER_RUNTIME run --rm \ + --platform linux/arm64 \ + -v "$PROJECT_ROOT:/workspace" \ + -w /workspace \ + "$IMAGE_NAME" \ + bash -c "$CARGO_TEST"; then + echo -e "${RED}Tests failed for ${feature_name}${NC}" + FAILED=1 + fi + echo "" +done + +if [ $FAILED -eq 0 ]; then + echo -e "${GREEN}✓ Linux/ARM64 build completed successfully${NC}" + exit 0 +else + echo -e "${RED}✗ Linux/ARM64 build failed${NC}" + exit 1 +fi + diff --git a/scripts/build-linux-x86_64.sh b/scripts/build-linux-x86_64.sh new file mode 100755 index 0000000..fbfd1eb --- /dev/null +++ b/scripts/build-linux-x86_64.sh @@ -0,0 +1,119 @@ +#!/bin/bash +# Build script for Linux/x86_64 using Docker or Podman +# Uses Docker/Podman to build in a Linux environment + +set -e + +# Colors for output +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +RED='\033[0;31m' +NC='\033[0m' # No Color + +# Script directory +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" + +# Feature sets to test +declare -a FEATURES=( + "" + "ml-kem" + "post-quantum" + "ml-kem,post-quantum" +) + +# Detect container runtime (Podman or Docker) +detect_container_runtime() { + if command -v podman &> /dev/null; then + if podman info &>/dev/null 2>&1; then + echo "podman" + return 0 + fi + fi + + if command -v docker &> /dev/null; then + if docker info &>/dev/null 2>&1; then + echo "docker" + return 0 + fi + fi + + return 1 +} + +# Detect and set container runtime +CONTAINER_RUNTIME=$(detect_container_runtime || echo "") + +if [ -z "$CONTAINER_RUNTIME" ]; then + echo -e "${RED}ERROR: Neither Docker nor Podman is available${NC}" + echo " Install Docker Desktop from: https://www.docker.com/products/docker-desktop" + echo " Or install Podman from: https://podman.io/getting-started/installation" + exit 1 +fi + +echo -e "${YELLOW}Building for Linux/x86_64 using ${CONTAINER_RUNTIME}${NC}" +echo "" + +# Change to project root +cd "$PROJECT_ROOT" + +# Docker image name +IMAGE_NAME="rust-bottle-linux-x86_64" +DOCKERFILE="$SCRIPT_DIR/Dockerfile.linux-x86_64" + +# Build Docker image if it doesn't exist or if Dockerfile is newer +if [ ! -f "$DOCKERFILE" ]; then + echo -e "${RED}ERROR: Dockerfile not found: $DOCKERFILE${NC}" + exit 1 +fi + +echo "Building container image: $IMAGE_NAME" +echo "Note: This may take a few minutes on first run..." +$CONTAINER_RUNTIME build -f "$DOCKERFILE" -t "$IMAGE_NAME" "$PROJECT_ROOT" + +# Run builds in Docker container +FAILED=0 +for features in "${FEATURES[@]}"; do + feature_name=${features:-"default"} + echo -e "${YELLOW}Building with features: ${feature_name}${NC}" + + # Prepare cargo command + if [ -z "$features" ]; then + CARGO_BUILD="cargo build --target x86_64-unknown-linux-gnu --release" + CARGO_TEST="cargo test --target x86_64-unknown-linux-gnu" + else + CARGO_BUILD="cargo build --target x86_64-unknown-linux-gnu --features $features --release" + CARGO_TEST="cargo test --target x86_64-unknown-linux-gnu --features $features" + fi + + # Build + if ! $CONTAINER_RUNTIME run --rm \ + -v "$PROJECT_ROOT:/workspace" \ + -w /workspace \ + "$IMAGE_NAME" \ + bash -c "$CARGO_BUILD"; then + echo -e "${RED}Build failed for ${feature_name}${NC}" + FAILED=1 + fi + + # Test + echo -e "${YELLOW}Running tests with features: ${feature_name}${NC}" + if ! $CONTAINER_RUNTIME run --rm \ + -v "$PROJECT_ROOT:/workspace" \ + -w /workspace \ + "$IMAGE_NAME" \ + bash -c "$CARGO_TEST"; then + echo -e "${RED}Tests failed for ${feature_name}${NC}" + FAILED=1 + fi + echo "" +done + +if [ $FAILED -eq 0 ]; then + echo -e "${GREEN}✓ Linux/x86_64 build completed successfully${NC}" + exit 0 +else + echo -e "${RED}✗ Linux/x86_64 build failed${NC}" + exit 1 +fi + diff --git a/scripts/build-macos-arm.sh b/scripts/build-macos-arm.sh new file mode 100755 index 0000000..28dc0ec --- /dev/null +++ b/scripts/build-macos-arm.sh @@ -0,0 +1,90 @@ +#!/bin/bash +# Build script for macOS/ARM (Apple Silicon) - native build +# This is the native platform, so no special setup needed + +set -e + +# Colors for output +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +RED='\033[0;31m' +NC='\033[0m' # No Color + +# Script directory +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" + +# Feature sets to test +declare -a FEATURES=( + "" + "ml-kem" + "post-quantum" + "ml-kem,post-quantum" +) + +echo -e "${YELLOW}Building for macOS/ARM (Apple Silicon) - Native${NC}" +echo "" + +# Change to project root +cd "$PROJECT_ROOT" + +# Verify we're on ARM +ARCH=$(uname -m) +if [ "$ARCH" != "arm64" ]; then + echo -e "${RED}ERROR: This script should run on ARM64 Mac${NC}" + exit 1 +fi + +# Check if Rust is installed +if ! command -v rustc &> /dev/null; then + echo -e "${RED}ERROR: Rust is not installed${NC}" + echo " Install it with: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh" + exit 1 +fi + +# Install target if needed +echo "Installing target: aarch64-apple-darwin" +rustup target add aarch64-apple-darwin 2>/dev/null || true + +# Build for each feature set +FAILED=0 +for features in "${FEATURES[@]}"; do + feature_name=${features:-"default"} + echo -e "${YELLOW}Building with features: ${feature_name}${NC}" + + if [ -z "$features" ]; then + if ! cargo build --target aarch64-apple-darwin --release; then + echo -e "${RED}Build failed for ${feature_name}${NC}" + FAILED=1 + fi + else + if ! cargo build --target aarch64-apple-darwin --features "$features" --release; then + echo -e "${RED}Build failed for ${feature_name}${NC}" + FAILED=1 + fi + fi + + # Run tests + echo -e "${YELLOW}Running tests with features: ${feature_name}${NC}" + if [ -z "$features" ]; then + if ! cargo test --target aarch64-apple-darwin; then + echo -e "${RED}Tests failed for ${feature_name}${NC}" + FAILED=1 + fi + else + if ! cargo test --target aarch64-apple-darwin --features "$features"; then + echo -e "${RED}Tests failed for ${feature_name}${NC}" + FAILED=1 + fi + fi + echo "" +done + +if [ $FAILED -eq 0 ]; then + echo -e "${GREEN}✓ macOS/ARM build completed successfully${NC}" + exit 0 +else + echo -e "${RED}✗ macOS/ARM build failed${NC}" + exit 1 +fi + diff --git a/scripts/build-macos-x86_64.sh b/scripts/build-macos-x86_64.sh new file mode 100755 index 0000000..7299635 --- /dev/null +++ b/scripts/build-macos-x86_64.sh @@ -0,0 +1,94 @@ +#!/bin/bash +# Build script for macOS/x86_64 (Intel) using Rosetta 2 +# This uses arch -x86_64 to run commands in x86_64 mode + +set -e + +# Colors for output +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +RED='\033[0;31m' +NC='\033[0m' # No Color + +# Script directory +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" + +# Feature sets to test +declare -a FEATURES=( + "" + "ml-kem" + "post-quantum" + "ml-kem,post-quantum" +) + +echo -e "${YELLOW}Building for macOS/x86_64 (Intel) using Rosetta 2${NC}" +echo "" + +# Change to project root +cd "$PROJECT_ROOT" + +# Check if Rosetta 2 is available +if ! arch -x86_64 /usr/bin/true &>/dev/null; then + echo -e "${RED}ERROR: Rosetta 2 is not available${NC}" + echo " Install Rosetta 2 with: softwareupdate --install-rosetta" + exit 1 +fi + +# Check if Rust is installed +if ! command -v rustc &> /dev/null; then + echo -e "${RED}ERROR: Rust is not installed${NC}" + echo " Install it with: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh" + exit 1 +fi + +# Install target if needed (using x86_64 arch) +echo "Installing target: x86_64-apple-darwin" +arch -x86_64 rustup target add x86_64-apple-darwin 2>/dev/null || true + +# Set up environment for x86_64 builds +# We need to use arch -x86_64 for all cargo commands +CARGO_CMD="arch -x86_64 cargo" + +# Build for each feature set +FAILED=0 +for features in "${FEATURES[@]}"; do + feature_name=${features:-"default"} + echo -e "${YELLOW}Building with features: ${feature_name}${NC}" + + if [ -z "$features" ]; then + if ! $CARGO_CMD build --target x86_64-apple-darwin --release; then + echo -e "${RED}Build failed for ${feature_name}${NC}" + FAILED=1 + fi + else + if ! $CARGO_CMD build --target x86_64-apple-darwin --features "$features" --release; then + echo -e "${RED}Build failed for ${feature_name}${NC}" + FAILED=1 + fi + fi + + # Run tests + echo -e "${YELLOW}Running tests with features: ${feature_name}${NC}" + if [ -z "$features" ]; then + if ! $CARGO_CMD test --target x86_64-apple-darwin; then + echo -e "${RED}Tests failed for ${feature_name}${NC}" + FAILED=1 + fi + else + if ! $CARGO_CMD test --target x86_64-apple-darwin --features "$features"; then + echo -e "${RED}Tests failed for ${feature_name}${NC}" + FAILED=1 + fi + fi + echo "" +done + +if [ $FAILED -eq 0 ]; then + echo -e "${GREEN}✓ macOS/x86_64 build completed successfully${NC}" + exit 0 +else + echo -e "${RED}✗ macOS/x86_64 build failed${NC}" + exit 1 +fi + diff --git a/scripts/build-using-cross.sh b/scripts/build-using-cross.sh new file mode 100755 index 0000000..30b3f5b --- /dev/null +++ b/scripts/build-using-cross.sh @@ -0,0 +1,103 @@ +#!/bin/bash +# Alternative build script using `cross` for cross-compilation +# This is more efficient than Docker for some use cases +# Install cross with: cargo install cross --git https://github.com/cross-rs/cross + +set -e + +# Colors for output +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +RED='\033[0;31m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Script directory +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" + +# Feature sets to test +declare -a FEATURES=( + "" + "ml-kem" + "post-quantum" + "ml-kem,post-quantum" +) + +echo -e "${YELLOW}Building using cross for cross-compilation${NC}" +echo "" + +# Check if cross is installed +if ! command -v cross &> /dev/null; then + echo -e "${RED}ERROR: cross is not installed${NC}" + echo " Install it with: cargo install cross --git https://github.com/cross-rs/cross" + echo " Or use the Docker-based scripts instead" + exit 1 +fi + +# Change to project root +cd "$PROJECT_ROOT" + +# Targets to build +declare -a TARGETS=( + "x86_64-unknown-linux-gnu" + "aarch64-unknown-linux-gnu" +) + +# Results tracking +FAILED=0 + +# Build for each target +for target in "${TARGETS[@]}"; do + echo -e "${BLUE}========================================${NC}" + echo -e "${BLUE}Building for: ${target}${NC}" + echo -e "${BLUE}========================================${NC}" + echo "" + + # Install target if needed + echo "Installing target: $target" + rustup target add "$target" 2>/dev/null || true + echo "" + + # Build for each feature set + for features in "${FEATURES[@]}"; do + feature_name=${features:-"default"} + echo -e "${YELLOW}Building with features: ${feature_name}${NC}" + + if [ -z "$features" ]; then + if ! cross build --target "$target" --release; then + echo -e "${RED}Build failed for ${target} with ${feature_name}${NC}" + FAILED=1 + fi + else + if ! cross build --target "$target" --features "$features" --release; then + echo -e "${RED}Build failed for ${target} with ${feature_name}${NC}" + FAILED=1 + fi + fi + + # Test (cross test may not work for all targets) + echo -e "${YELLOW}Running tests with features: ${feature_name}${NC}" + if [ -z "$features" ]; then + if ! cross test --target "$target"; then + echo -e "${YELLOW}Tests may not work with cross for ${target}${NC}" + echo -e "${YELLOW}This is normal - use Docker scripts for full testing${NC}" + fi + else + if ! cross test --target "$target" --features "$features"; then + echo -e "${YELLOW}Tests may not work with cross for ${target}${NC}" + echo -e "${YELLOW}This is normal - use Docker scripts for full testing${NC}" + fi + fi + echo "" + done +done + +if [ $FAILED -eq 0 ]; then + echo -e "${GREEN}✓ All cross builds completed successfully!${NC}" + exit 0 +else + echo -e "${RED}✗ Some cross builds failed${NC}" + exit 1 +fi + diff --git a/scripts/check-prerequisites.sh b/scripts/check-prerequisites.sh new file mode 100755 index 0000000..5197546 --- /dev/null +++ b/scripts/check-prerequisites.sh @@ -0,0 +1,166 @@ +#!/bin/bash +# Prerequisites check script for cross-platform builds +# Checks if all required tools are installed and configured + +set -e + +# Colors for output +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +RED='\033[0;31m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +echo -e "${BLUE}Checking Prerequisites for Cross-Platform Builds${NC}" +echo "" + +ALL_OK=1 + +# Check Rust +echo -n "Checking Rust... " +if command -v rustc &> /dev/null; then + RUST_VERSION=$(rustc --version) + echo -e "${GREEN}✓${NC} $RUST_VERSION" +else + echo -e "${RED}✗ Not installed${NC}" + echo " Install with: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh" + ALL_OK=0 +fi + +# Check Cargo +echo -n "Checking Cargo... " +if command -v cargo &> /dev/null; then + CARGO_VERSION=$(cargo --version) + echo -e "${GREEN}✓${NC} $CARGO_VERSION" +else + echo -e "${RED}✗ Not installed${NC}" + ALL_OK=0 +fi + +# Check platform +echo -n "Checking platform... " +if [[ "$OSTYPE" == "darwin"* ]]; then + ARCH=$(uname -m) + OS_VERSION=$(sw_vers -productVersion) + echo -e "${GREEN}✓${NC} macOS $OS_VERSION ($ARCH)" + + # Check Rosetta 2 + if [ "$ARCH" = "arm64" ]; then + echo -n "Checking Rosetta 2... " + if arch -x86_64 /usr/bin/true &>/dev/null 2>&1; then + echo -e "${GREEN}✓ Available${NC}" + else + echo -e "${YELLOW}⚠ Not available${NC}" + echo " Install with: softwareupdate --install-rosetta" + echo " (Required for macOS/x86_64 builds)" + fi + fi +else + echo -e "${YELLOW}⚠ Not macOS - some scripts may not work${NC}" +fi + +# Check Docker/Podman +HAS_CONTAINER_RUNTIME=0 + +# Check Podman first (preferred if available) +echo -n "Checking Podman... " +if command -v podman &> /dev/null; then + PODMAN_VERSION=$(podman --version) + echo -e "${GREEN}✓${NC} $PODMAN_VERSION" + + # Check if Podman is working (no daemon needed) + echo -n "Checking Podman... " + if podman info &>/dev/null 2>&1; then + echo -e "${GREEN}✓ Working${NC}" + HAS_CONTAINER_RUNTIME=1 + else + echo -e "${YELLOW}⚠ Installed but not working${NC}" + fi +else + echo -e "${YELLOW}⚠ Not installed${NC}" +fi + +# Check Docker +echo -n "Checking Docker... " +if command -v docker &> /dev/null; then + DOCKER_VERSION=$(docker --version) + echo -e "${GREEN}✓${NC} $DOCKER_VERSION" + + # Check if Docker is running + echo -n "Checking Docker daemon... " + if docker info &>/dev/null 2>&1; then + echo -e "${GREEN}✓ Running${NC}" + HAS_CONTAINER_RUNTIME=1 + + # Check Docker buildx for multi-platform + echo -n "Checking Docker buildx... " + if docker buildx version &>/dev/null 2>&1; then + echo -e "${GREEN}✓ Available${NC}" + else + echo -e "${YELLOW}⚠ Not available${NC}" + echo " (Helpful for multi-platform builds)" + fi + else + echo -e "${RED}✗ Not running${NC}" + echo " Start Docker Desktop and try again" + fi +else + echo -e "${YELLOW}⚠ Not installed${NC}" +fi + +# Summary for container runtime +if [ $HAS_CONTAINER_RUNTIME -eq 0 ]; then + echo -e "${YELLOW}⚠ No container runtime available${NC}" + echo " Install Docker Desktop from: https://www.docker.com/products/docker-desktop" + echo " Or install Podman from: https://podman.io/getting-started/installation" + echo " (Required for Linux builds)" + ALL_OK=0 +fi + +# Check Rust targets +echo "" +echo "Checking Rust targets..." +TARGETS=( + "aarch64-apple-darwin:macOS/ARM" + "x86_64-apple-darwin:macOS/x86_64" + "x86_64-unknown-linux-gnu:Linux/x86_64" + "aarch64-unknown-linux-gnu:Linux/ARM64" +) + +for target_info in "${TARGETS[@]}"; do + IFS=':' read -r target name <<< "$target_info" + echo -n " $name ($target)... " + if rustup target list --installed 2>/dev/null | grep -q "^$target$"; then + echo -e "${GREEN}✓ Installed${NC}" + else + echo -e "${YELLOW}⚠ Not installed${NC}" + echo " Install with: rustup target add $target" + fi +done + +# Check cross tool (optional) +echo "" +echo -n "Checking cross tool (optional)... " +if command -v cross &> /dev/null; then + CROSS_VERSION=$(cross --version 2>/dev/null || echo "installed") + echo -e "${GREEN}✓${NC} $CROSS_VERSION" + echo " (Alternative to Docker for cross-compilation)" +else + echo -e "${YELLOW}⚠ Not installed${NC}" + echo " Install with: cargo install cross --git https://github.com/cross-rs/cross" + echo " (Optional - Docker scripts work without it)" +fi + +# Summary +echo "" +echo -e "${BLUE}========================================${NC}" +if [ $ALL_OK -eq 1 ]; then + echo -e "${GREEN}✓ All essential prerequisites are met!${NC}" + echo " You can run: ./scripts/build-all-platforms.sh" + exit 0 +else + echo -e "${YELLOW}⚠ Some prerequisites are missing${NC}" + echo " Please install missing tools before running build scripts" + exit 1 +fi + diff --git a/scripts/quick-build-test.sh b/scripts/quick-build-test.sh new file mode 100755 index 0000000..dd16840 --- /dev/null +++ b/scripts/quick-build-test.sh @@ -0,0 +1,98 @@ +#!/bin/bash +# Quick build test script - tests builds without running full test suite +# Useful for quickly verifying compilation across platforms + +set -e + +# Colors for output +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +RED='\033[0;31m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Script directory +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" + +echo -e "${BLUE}Quick Build Test - Compilation Only${NC}" +echo "This script quickly tests compilation (no tests) for all platforms" +echo "" + +# Change to project root +cd "$PROJECT_ROOT" + +# Quick build function +quick_build() { + local target=$1 + local name=$2 + local features=${3:-""} + + echo -e "${YELLOW}Building ${name}...${NC}" + + if [ -z "$features" ]; then + if cargo build --target "$target" --release 2>&1 | grep -q "Finished"; then + echo -e "${GREEN}✓ ${name} compiled successfully${NC}" + return 0 + else + echo -e "${RED}✗ ${name} compilation failed${NC}" + return 1 + fi + else + if cargo build --target "$target" --features "$features" --release 2>&1 | grep -q "Finished"; then + echo -e "${GREEN}✓ ${name} compiled successfully${NC}" + return 0 + else + echo -e "${RED}✗ ${name} compilation failed${NC}" + return 1 + fi + fi +} + +FAILED=0 + +# 1. macOS/ARM (native) +if [ "$(uname -m)" = "arm64" ]; then + rustup target add aarch64-apple-darwin 2>/dev/null || true + if ! quick_build "aarch64-apple-darwin" "macOS/ARM" ""; then + FAILED=1 + fi + if ! quick_build "aarch64-apple-darwin" "macOS/ARM (ml-kem)" "ml-kem"; then + FAILED=1 + fi +fi + +# 2. macOS/x86_64 (if Rosetta 2 available) +if arch -x86_64 /usr/bin/true &>/dev/null 2>&1; then + arch -x86_64 rustup target add x86_64-apple-darwin 2>/dev/null || true + if ! arch -x86_64 cargo build --target x86_64-apple-darwin --release 2>&1 | grep -q "Finished"; then + echo -e "${RED}✗ macOS/x86_64 compilation failed${NC}" + FAILED=1 + else + echo -e "${GREEN}✓ macOS/x86_64 compiled successfully${NC}" + fi +fi + +# 3. Linux targets (check if Docker or Podman is available) +HAS_CONTAINER_RUNTIME=0 +if command -v podman &> /dev/null && podman info &>/dev/null 2>&1; then + echo -e "${YELLOW}Podman is available - Linux builds can be tested${NC}" + echo -e "${YELLOW}Run full build scripts for Linux targets${NC}" + HAS_CONTAINER_RUNTIME=1 +elif command -v docker &> /dev/null && docker info &>/dev/null 2>&1; then + echo -e "${YELLOW}Docker is available - Linux builds can be tested${NC}" + echo -e "${YELLOW}Run full build scripts for Linux targets${NC}" + HAS_CONTAINER_RUNTIME=1 +else + echo -e "${YELLOW}No container runtime (Docker/Podman) available - skipping Linux builds${NC}" +fi + +echo "" +if [ $FAILED -eq 0 ]; then + echo -e "${GREEN}✓ Quick build test passed!${NC}" + exit 0 +else + echo -e "${RED}✗ Quick build test failed${NC}" + exit 1 +fi +