diff options
| author | diogo464 <[email protected]> | 2025-07-10 22:20:34 +0100 |
|---|---|---|
| committer | diogo464 <[email protected]> | 2025-07-10 22:20:34 +0100 |
| commit | 0ead2c37efe34278a859edbce40e8bba7bf021fd (patch) | |
| tree | aaf17c0a8bd10b596962ae52f25e8bcb0e62dea8 /scripts/build-static.sh | |
| parent | 3b0721341c46922b5c1c94bdbbf37099424ee5bc (diff) | |
Add GitHub Actions release workflow and build scripts
- Add .github/workflows/release.yml for automated releases on version tags
- Add scripts/build-static.sh for building statically linked binaries
- Add scripts/prepare-release.sh for preparing release artifacts
- Optimize Cargo.toml for smaller binary size (reduced from 4.5MB to 2.9MB)
- Add scripts/README.md with usage documentation
The workflow automatically builds binaries for Linux (musl) and macOS (Intel/ARM)
when a version tag is pushed.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <[email protected]>
Diffstat (limited to 'scripts/build-static.sh')
| -rwxr-xr-x | scripts/build-static.sh | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/scripts/build-static.sh b/scripts/build-static.sh new file mode 100755 index 0000000..d835e79 --- /dev/null +++ b/scripts/build-static.sh | |||
| @@ -0,0 +1,218 @@ | |||
| 1 | #!/bin/bash | ||
| 2 | set -euo pipefail | ||
| 3 | |||
| 4 | # Script to build static binaries for Linux and macOS | ||
| 5 | # Can be run locally or in CI | ||
| 6 | |||
| 7 | SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | ||
| 8 | PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" | ||
| 9 | BINARY_NAME="oar-p2p" | ||
| 10 | |||
| 11 | # Parse command line arguments | ||
| 12 | TARGET_OS="${1:-all}" # linux, macos, or all | ||
| 13 | OUTPUT_DIR="${2:-$PROJECT_ROOT/target/release-static}" | ||
| 14 | |||
| 15 | # Colors for output | ||
| 16 | RED='\033[0;31m' | ||
| 17 | GREEN='\033[0;32m' | ||
| 18 | YELLOW='\033[1;33m' | ||
| 19 | NC='\033[0m' # No Color | ||
| 20 | |||
| 21 | log_info() { | ||
| 22 | echo -e "${GREEN}[INFO]${NC} $1" | ||
| 23 | } | ||
| 24 | |||
| 25 | log_error() { | ||
| 26 | echo -e "${RED}[ERROR]${NC} $1" >&2 | ||
| 27 | } | ||
| 28 | |||
| 29 | log_warn() { | ||
| 30 | echo -e "${YELLOW}[WARN]${NC} $1" | ||
| 31 | } | ||
| 32 | |||
| 33 | # Ensure we're in the project root | ||
| 34 | cd "$PROJECT_ROOT" | ||
| 35 | |||
| 36 | # Create output directory | ||
| 37 | mkdir -p "$OUTPUT_DIR" | ||
| 38 | |||
| 39 | # Function to build for Linux with musl | ||
| 40 | build_linux() { | ||
| 41 | local arch="${1:-x86_64}" | ||
| 42 | local target="${arch}-unknown-linux-musl" | ||
| 43 | |||
| 44 | log_info "Building static binary for Linux ($arch)..." | ||
| 45 | |||
| 46 | # Check if target is installed | ||
| 47 | if ! rustup target list --installed | grep -q "$target"; then | ||
| 48 | log_info "Installing Rust target: $target" | ||
| 49 | rustup target add "$target" | ||
| 50 | fi | ||
| 51 | |||
| 52 | # Set environment variables for static linking | ||
| 53 | export RUSTFLAGS="-C target-feature=+crt-static" | ||
| 54 | |||
| 55 | # Build the binary | ||
| 56 | log_info "Running cargo build for $target..." | ||
| 57 | cargo build --release --target "$target" --target-dir "$PROJECT_ROOT/target" | ||
| 58 | |||
| 59 | # Copy binary to output directory with platform suffix | ||
| 60 | local output_name="${BINARY_NAME}-linux-${arch}" | ||
| 61 | cp "target/$target/release/$BINARY_NAME" "$OUTPUT_DIR/$output_name" | ||
| 62 | |||
| 63 | # Strip the binary to reduce size | ||
| 64 | if command -v strip >/dev/null 2>&1; then | ||
| 65 | log_info "Stripping binary to reduce size..." | ||
| 66 | strip "$OUTPUT_DIR/$output_name" | ||
| 67 | fi | ||
| 68 | |||
| 69 | # Make it executable | ||
| 70 | chmod +x "$OUTPUT_DIR/$output_name" | ||
| 71 | |||
| 72 | log_info "Linux binary built: $OUTPUT_DIR/$output_name" | ||
| 73 | |||
| 74 | # Print binary info | ||
| 75 | if command -v file >/dev/null 2>&1; then | ||
| 76 | file "$OUTPUT_DIR/$output_name" | ||
| 77 | fi | ||
| 78 | |||
| 79 | # Check if it's actually statically linked | ||
| 80 | if command -v ldd >/dev/null 2>&1; then | ||
| 81 | if ldd "$OUTPUT_DIR/$output_name" 2>&1 | grep -q "not a dynamic executable"; then | ||
| 82 | log_info "✓ Binary is statically linked" | ||
| 83 | else | ||
| 84 | log_warn "Binary appears to be dynamically linked" | ||
| 85 | fi | ||
| 86 | fi | ||
| 87 | } | ||
| 88 | |||
| 89 | # Function to build for macOS | ||
| 90 | build_macos() { | ||
| 91 | local arch="${1:-x86_64}" | ||
| 92 | local target | ||
| 93 | |||
| 94 | case "$arch" in | ||
| 95 | x86_64) | ||
| 96 | target="x86_64-apple-darwin" | ||
| 97 | ;; | ||
| 98 | aarch64|arm64) | ||
| 99 | target="aarch64-apple-darwin" | ||
| 100 | ;; | ||
| 101 | *) | ||
| 102 | log_error "Unknown macOS architecture: $arch" | ||
| 103 | return 1 | ||
| 104 | ;; | ||
| 105 | esac | ||
| 106 | |||
| 107 | # Check if we're on macOS | ||
| 108 | if [[ "$OSTYPE" != "darwin"* ]]; then | ||
| 109 | log_warn "Cannot build macOS binaries on non-macOS systems" | ||
| 110 | log_info "macOS binaries must be built on macOS or in CI" | ||
| 111 | return 0 | ||
| 112 | fi | ||
| 113 | |||
| 114 | log_info "Building binary for macOS ($arch)..." | ||
| 115 | |||
| 116 | # Check if target is installed | ||
| 117 | if ! rustup target list --installed | grep -q "$target"; then | ||
| 118 | log_info "Installing Rust target: $target" | ||
| 119 | rustup target add "$target" | ||
| 120 | fi | ||
| 121 | |||
| 122 | # macOS doesn't support fully static binaries, but we can minimize dependencies | ||
| 123 | export RUSTFLAGS="-C target-feature=+crt-static" | ||
| 124 | |||
| 125 | # Build the binary | ||
| 126 | log_info "Running cargo build for $target..." | ||
| 127 | cargo build --release --target "$target" --target-dir "$PROJECT_ROOT/target" | ||
| 128 | |||
| 129 | # Copy binary to output directory with platform suffix | ||
| 130 | local output_name="${BINARY_NAME}-macos-${arch}" | ||
| 131 | cp "target/$target/release/$BINARY_NAME" "$OUTPUT_DIR/$output_name" | ||
| 132 | |||
| 133 | # Strip the binary to reduce size (macOS strip is different) | ||
| 134 | if [[ "$OSTYPE" == "darwin"* ]] && command -v strip >/dev/null 2>&1; then | ||
| 135 | log_info "Stripping binary to reduce size..." | ||
| 136 | strip "$OUTPUT_DIR/$output_name" | ||
| 137 | fi | ||
| 138 | |||
| 139 | # Make it executable | ||
| 140 | chmod +x "$OUTPUT_DIR/$output_name" | ||
| 141 | |||
| 142 | log_info "macOS binary built: $OUTPUT_DIR/$output_name" | ||
| 143 | |||
| 144 | # Print binary info | ||
| 145 | if command -v file >/dev/null 2>&1; then | ||
| 146 | file "$OUTPUT_DIR/$output_name" | ||
| 147 | fi | ||
| 148 | } | ||
| 149 | |||
| 150 | # Function to check dependencies | ||
| 151 | check_dependencies() { | ||
| 152 | local missing_deps=() | ||
| 153 | |||
| 154 | # Check for Rust | ||
| 155 | if ! command -v cargo >/dev/null 2>&1; then | ||
| 156 | missing_deps+=("cargo (Rust)") | ||
| 157 | fi | ||
| 158 | |||
| 159 | # Check for rustup | ||
| 160 | if ! command -v rustup >/dev/null 2>&1; then | ||
| 161 | missing_deps+=("rustup") | ||
| 162 | fi | ||
| 163 | |||
| 164 | if [ ${#missing_deps[@]} -ne 0 ]; then | ||
| 165 | log_error "Missing required dependencies:" | ||
| 166 | for dep in "${missing_deps[@]}"; do | ||
| 167 | echo " - $dep" | ||
| 168 | done | ||
| 169 | exit 1 | ||
| 170 | fi | ||
| 171 | |||
| 172 | # Check Rust version (nightly required based on Cargo.toml) | ||
| 173 | if ! rustc --version | grep -q "nightly"; then | ||
| 174 | log_warn "This project requires Rust nightly. Current version:" | ||
| 175 | rustc --version | ||
| 176 | log_info "Attempting to use nightly for this build..." | ||
| 177 | export RUSTUP_TOOLCHAIN=nightly | ||
| 178 | fi | ||
| 179 | } | ||
| 180 | |||
| 181 | # Main execution | ||
| 182 | main() { | ||
| 183 | log_info "Starting static build process..." | ||
| 184 | log_info "Output directory: $OUTPUT_DIR" | ||
| 185 | |||
| 186 | # Check dependencies | ||
| 187 | check_dependencies | ||
| 188 | |||
| 189 | case "$TARGET_OS" in | ||
| 190 | linux) | ||
| 191 | build_linux "x86_64" | ||
| 192 | # Optionally build for ARM64 | ||
| 193 | # build_linux "aarch64" | ||
| 194 | ;; | ||
| 195 | macos|darwin) | ||
| 196 | # Build for both Intel and Apple Silicon | ||
| 197 | build_macos "x86_64" | ||
| 198 | build_macos "aarch64" | ||
| 199 | ;; | ||
| 200 | all) | ||
| 201 | # Build for all platforms | ||
| 202 | build_linux "x86_64" | ||
| 203 | build_macos "x86_64" | ||
| 204 | build_macos "aarch64" | ||
| 205 | ;; | ||
| 206 | *) | ||
| 207 | log_error "Unknown target OS: $TARGET_OS" | ||
| 208 | echo "Usage: $0 [linux|macos|all] [output_dir]" | ||
| 209 | exit 1 | ||
| 210 | ;; | ||
| 211 | esac | ||
| 212 | |||
| 213 | log_info "Build complete! Binaries available in: $OUTPUT_DIR" | ||
| 214 | ls -lh "$OUTPUT_DIR" | ||
| 215 | } | ||
| 216 | |||
| 217 | # Run main function | ||
| 218 | main \ No newline at end of file | ||
