2026-02-08 20:09:38 +00:00
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
set -euo pipefail
|
|
|
|
|
|
|
|
|
|
# Rustelo Cross-Compilation Build Script
|
|
|
|
|
# Builds Rustelo applications for Linux targets on macOS using Docker
|
|
|
|
|
|
|
|
|
|
PROJECT_ROOT="$(pwd)"
|
|
|
|
|
BUILD_TARGET="${CARGO_BUILD_TARGET:-x86_64-unknown-linux-gnu}"
|
|
|
|
|
BUILD_MODE="${RUSTELO_MODE:-release}"
|
|
|
|
|
DOCKER_IMAGE="${RUSTELO_CROSS_IMAGE:-rustelo-cross:latest}"
|
|
|
|
|
VERBOSE="${RUSTELO_VERBOSE:-false}"
|
|
|
|
|
|
|
|
|
|
# Colors for output
|
|
|
|
|
RED='\033[0;31m'
|
|
|
|
|
GREEN='\033[0;32m'
|
|
|
|
|
YELLOW='\033[1;33m'
|
|
|
|
|
BLUE='\033[0;34m'
|
|
|
|
|
NC='\033[0m'
|
|
|
|
|
|
|
|
|
|
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
|
|
|
|
|
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
|
|
|
|
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
|
|
|
|
log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
|
|
|
|
|
|
|
|
|
|
show_help() {
|
|
|
|
|
cat << EOF
|
|
|
|
|
Rustelo Cross-Compilation Build Script
|
|
|
|
|
|
|
|
|
|
USAGE: $0 [OPTIONS] [COMMAND]
|
|
|
|
|
|
|
|
|
|
OPTIONS:
|
|
|
|
|
-t, --target <TARGET> Target architecture (default: x86_64-unknown-linux-gnu)
|
|
|
|
|
-m, --mode <MODE> Build mode: dev, release (default: release)
|
|
|
|
|
-i, --image <IMAGE> Docker image to use (default: rustelo-cross:latest)
|
|
|
|
|
-v, --verbose Enable verbose output
|
|
|
|
|
-h, --help Show this help message
|
|
|
|
|
|
|
|
|
|
COMMANDS:
|
|
|
|
|
build Build the Rustelo application (default)
|
|
|
|
|
assets Process and build assets only
|
|
|
|
|
deps Install dependencies (npm + cargo)
|
|
|
|
|
clean Clean build artifacts
|
|
|
|
|
shell Start interactive shell in container
|
|
|
|
|
test Run tests in cross-compilation environment
|
|
|
|
|
EOF
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
COMMAND=""
|
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
|
|
|
case $1 in
|
|
|
|
|
-t|--target) BUILD_TARGET="$2"; shift 2 ;;
|
|
|
|
|
-m|--mode) BUILD_MODE="$2"; shift 2 ;;
|
|
|
|
|
-i|--image) DOCKER_IMAGE="$2"; shift 2 ;;
|
|
|
|
|
-v|--verbose) VERBOSE=true; shift ;;
|
|
|
|
|
-h|--help) show_help; exit 0 ;;
|
|
|
|
|
*) COMMAND="$1"; shift ;;
|
|
|
|
|
esac
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
COMMAND="${COMMAND:-build}"
|
|
|
|
|
|
|
|
|
|
if [[ ! -f "Cargo.toml" ]]; then
|
|
|
|
|
log_error "No Cargo.toml found. Are you in a Rust project directory?"
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
setup_cross_dirs() {
|
|
|
|
|
log_info "Setting up cross-compilation directories..."
|
|
|
|
|
mkdir -p target-linux node_modules_linux .docker/cache
|
|
|
|
|
log_success "Cross-compilation directories ready"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
build_docker_image() {
|
|
|
|
|
local dockerfile="${1:-Dockerfile.cross}"
|
2026-02-08 20:37:49 +00:00
|
|
|
|
2026-02-08 20:09:38 +00:00
|
|
|
if ! docker image inspect "$DOCKER_IMAGE" >/dev/null 2>&1; then
|
|
|
|
|
log_info "Building Docker image: $DOCKER_IMAGE"
|
|
|
|
|
if [[ -f "$dockerfile" ]]; then
|
|
|
|
|
docker build -f "$dockerfile" -t "$DOCKER_IMAGE" .
|
|
|
|
|
log_success "Docker image built successfully"
|
|
|
|
|
else
|
|
|
|
|
log_error "Dockerfile not found: $dockerfile"
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
else
|
|
|
|
|
log_info "Using existing Docker image: $DOCKER_IMAGE"
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
docker_run_opts() {
|
|
|
|
|
echo "--rm --platform linux/amd64 -v ${PROJECT_ROOT}:/workspace -v ${PROJECT_ROOT}/target-linux:/workspace/target -v ${PROJECT_ROOT}/node_modules_linux:/workspace/node_modules -v ${PROJECT_ROOT}/.docker/cache:/root/.cargo/registry -w /workspace -e CARGO_BUILD_TARGET=${BUILD_TARGET} -e RUSTELO_MODE=${BUILD_MODE}"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
install_deps() {
|
|
|
|
|
log_info "Installing dependencies in cross-compilation environment..."
|
|
|
|
|
docker run $(docker_run_opts) "$DOCKER_IMAGE" bash -c '
|
|
|
|
|
set -euo pipefail
|
|
|
|
|
if [[ -f package.json ]]; then
|
|
|
|
|
echo "Installing Node.js dependencies..."
|
|
|
|
|
pnpm install --frozen-lockfile
|
|
|
|
|
fi
|
|
|
|
|
echo "Fetching Rust dependencies..."
|
|
|
|
|
cargo fetch --target $CARGO_BUILD_TARGET
|
|
|
|
|
echo "Dependencies installed successfully"
|
|
|
|
|
'
|
|
|
|
|
log_success "Dependencies installed"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
build_assets() {
|
|
|
|
|
log_info "Building assets for $BUILD_TARGET..."
|
|
|
|
|
docker run $(docker_run_opts) "$DOCKER_IMAGE" bash -c '
|
|
|
|
|
set -euo pipefail
|
|
|
|
|
if command -v rustelo >/dev/null 2>&1; then
|
|
|
|
|
echo "Processing Rustelo assets..."
|
|
|
|
|
rustelo build --categories static,content,config
|
|
|
|
|
else
|
|
|
|
|
echo "Rustelo CLI not found, using fallback asset processing..."
|
|
|
|
|
if [[ -d assets ]]; then
|
|
|
|
|
mkdir -p target/assets
|
|
|
|
|
cp -r assets/* target/assets/
|
|
|
|
|
fi
|
|
|
|
|
fi
|
|
|
|
|
echo "Assets built successfully"
|
|
|
|
|
'
|
|
|
|
|
log_success "Assets built"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
build_rust() {
|
|
|
|
|
log_info "Building Rust application for $BUILD_TARGET..."
|
|
|
|
|
docker run $(docker_run_opts) "$DOCKER_IMAGE" bash -c '
|
|
|
|
|
set -euo pipefail
|
|
|
|
|
echo "Building Rust application..."
|
|
|
|
|
if [[ "$RUSTELO_MODE" == "release" ]]; then
|
|
|
|
|
cargo build --target $CARGO_BUILD_TARGET --release
|
|
|
|
|
else
|
|
|
|
|
cargo build --target $CARGO_BUILD_TARGET
|
|
|
|
|
fi
|
|
|
|
|
echo "Build completed successfully"
|
|
|
|
|
'
|
|
|
|
|
log_success "Rust application built"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
run_tests() {
|
|
|
|
|
log_info "Running tests in cross-compilation environment..."
|
|
|
|
|
docker run $(docker_run_opts) "$DOCKER_IMAGE" bash -c '
|
|
|
|
|
set -euo pipefail
|
|
|
|
|
echo "Running Rust tests..."
|
|
|
|
|
cargo test --target $CARGO_BUILD_TARGET
|
|
|
|
|
'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
clean_build() {
|
|
|
|
|
log_info "Cleaning cross-compilation artifacts..."
|
|
|
|
|
rm -rf target-linux node_modules_linux .docker/cache
|
|
|
|
|
log_success "Build artifacts cleaned"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interactive_shell() {
|
|
|
|
|
log_info "Starting interactive shell in cross-compilation environment..."
|
|
|
|
|
docker run -it $(docker_run_opts) "$DOCKER_IMAGE" bash
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
main() {
|
|
|
|
|
setup_cross_dirs
|
2026-02-08 20:37:49 +00:00
|
|
|
|
2026-02-08 20:09:38 +00:00
|
|
|
case "$COMMAND" in
|
|
|
|
|
build) build_docker_image; install_deps; build_assets; build_rust ;;
|
|
|
|
|
assets) build_docker_image; install_deps; build_assets ;;
|
|
|
|
|
deps) build_docker_image; install_deps ;;
|
|
|
|
|
test) build_docker_image; install_deps; run_tests ;;
|
|
|
|
|
clean) clean_build ;;
|
|
|
|
|
shell) build_docker_image; interactive_shell ;;
|
|
|
|
|
*) log_error "Unknown command: $COMMAND"; show_help; exit 1 ;;
|
|
|
|
|
esac
|
2026-02-08 20:37:49 +00:00
|
|
|
|
2026-02-08 20:09:38 +00:00
|
|
|
log_success "Cross-compilation completed successfully!"
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-08 20:37:49 +00:00
|
|
|
main "$@"
|