Skip to content

Build macOS Binaries (All Variants) #6

Build macOS Binaries (All Variants)

Build macOS Binaries (All Variants) #6

name: Build macOS Binaries (All Variants)
on:
workflow_dispatch:
inputs:
create_release:
description: 'Create GitHub Release after build'
required: false
default: 'false'
jobs:
# ============================================================================
# Build ALL macOS Variants (ARM + Intel + Standard + Metal)
# ============================================================================
build-macos-all:
name: Build All macOS Variants (4 variants)
runs-on: macos-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: recursive
- name: Install dependencies
run: |
echo "🔧 Installing dependencies..."
brew install cmake
echo "✅ CMake installed: $(cmake --version | head -1)"
echo "✅ Clang: $(clang --version | head -1)"
# ========================================================================
# VARIANT 1: BitNet ARM (M1/M2/M3/M4 with TL1 kernels)
# ========================================================================
- name: Build BitNet ARM (Apple Silicon)
run: |
echo "🔨 Building BitNet ARM (M1/M2/M3/M4 - TL1 kernels)..."
cmake -B build-macos-bitnet-arm \
-DBITNET_ARM_TL1=ON \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
-DLLAMA_BUILD_SERVER=ON \
-DLLAMA_BUILD_EXAMPLES=ON \
.
if cmake --build build-macos-bitnet-arm --config Release -j; then
echo "BITNET_ARM_SUCCESS=true" >> $GITHUB_ENV
echo "✅ BitNet ARM build SUCCESS"
else
echo "BITNET_ARM_SUCCESS=false" >> $GITHUB_ENV
echo "❌ BitNet ARM build FAILED"
fi
# ========================================================================
# VARIANT 2: BitNet Intel (SKIPPED - GitHub Actions uses ARM runners)
# ========================================================================
- name: Skip BitNet Intel (Intel Macs)
run: |
echo "⏭️ Skipping BitNet Intel build..."
echo ""
echo "Reason: GitHub macOS runners are Apple Silicon (M1/M2/M3) only."
echo "Cross-compiling ARM → x86 is problematic due to CPU detection issues."
echo ""
echo "To build for Intel Macs, run build-all-macos.sh locally on an Intel Mac."
echo "Intel Macs are legacy (discontinued 2020) - ARM build covers modern Macs."
echo ""
echo "BITNET_INTEL_SUCCESS=skipped" >> $GITHUB_ENV
# ========================================================================
# VARIANT 3: Standard CPU (no BitNet, universal)
# ========================================================================
- name: Build Standard CPU (universal)
run: |
echo "🔨 Building Standard CPU (no BitNet)..."
cmake -B build-macos-standard-cpu \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
-DGGML_METAL=OFF \
-DLLAMA_BUILD_SERVER=ON \
-DLLAMA_BUILD_EXAMPLES=ON \
3rdparty/llama.cpp
if cmake --build build-macos-standard-cpu --config Release -j; then
echo "STANDARD_CPU_SUCCESS=true" >> $GITHUB_ENV
echo "✅ Standard CPU build SUCCESS"
else
echo "STANDARD_CPU_SUCCESS=false" >> $GITHUB_ENV
echo "❌ Standard CPU build FAILED"
fi
# ========================================================================
# VARIANT 4: Metal GPU (ALL Macs)
# ========================================================================
- name: Build Metal GPU (ALL Macs)
run: |
echo "🔨 Building Metal GPU (M1/M2/M3 + Intel)..."
cmake -B build-macos-standard-metal \
-DGGML_METAL=ON \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
-DLLAMA_BUILD_SERVER=ON \
-DLLAMA_BUILD_EXAMPLES=ON \
3rdparty/llama.cpp
if cmake --build build-macos-standard-metal --config Release -j; then
echo "METAL_GPU_SUCCESS=true" >> $GITHUB_ENV
echo "✅ Metal GPU build SUCCESS"
else
echo "METAL_GPU_SUCCESS=false" >> $GITHUB_ENV
echo "❌ Metal GPU build FAILED"
fi
# ========================================================================
# Organize & Copy All Artifacts
# ========================================================================
- name: Organize release structure
run: |
echo "📁 Creating release directory structure..."
# Create all subdirectories
mkdir -p BitnetRelease/cpu/macos/bitnet-arm
mkdir -p BitnetRelease/cpu/macos/bitnet-intel
mkdir -p BitnetRelease/cpu/macos/standard
mkdir -p BitnetRelease/gpu/macos/standard-metal
echo ""
echo "=================================================="
echo "Copying build artifacts to BitnetRelease/..."
echo "=================================================="
echo ""
# ================================================================
# Copy BitNet ARM binaries
# ================================================================
if [ "$BITNET_ARM_SUCCESS" = "true" ]; then
echo "📦 Copying BitNet ARM binaries..."
if [ -d "build-macos-bitnet-arm/bin" ]; then
cp -f build-macos-bitnet-arm/bin/* BitnetRelease/cpu/macos/bitnet-arm/ 2>/dev/null || true
fi
# Copy .dylib files
find build-macos-bitnet-arm -name "*.dylib" -type f -exec cp -f {} BitnetRelease/cpu/macos/bitnet-arm/ \; 2>/dev/null || true
chmod +x BitnetRelease/cpu/macos/bitnet-arm/* 2>/dev/null || true
FILE_COUNT=$(ls -1 BitnetRelease/cpu/macos/bitnet-arm/ 2>/dev/null | wc -l)
echo " ✅ bitnet-arm: $FILE_COUNT files copied"
else
echo " ⚠️ BitNet ARM build failed - skipping"
fi
# ================================================================
# Skip BitNet Intel (not built on GitHub Actions)
# ================================================================
echo "⏭️ Skipping BitNet Intel (not built on ARM runners)"
echo " Build locally on Intel Mac if needed"
# ================================================================
# Copy Standard CPU binaries
# ================================================================
if [ "$STANDARD_CPU_SUCCESS" = "true" ]; then
echo "📦 Copying Standard CPU binaries..."
if [ -d "build-macos-standard-cpu/bin" ]; then
cp -f build-macos-standard-cpu/bin/* BitnetRelease/cpu/macos/standard/ 2>/dev/null || true
fi
# Copy .dylib files
find build-macos-standard-cpu -name "*.dylib" -type f -exec cp -f {} BitnetRelease/cpu/macos/standard/ \; 2>/dev/null || true
chmod +x BitnetRelease/cpu/macos/standard/* 2>/dev/null || true
FILE_COUNT=$(ls -1 BitnetRelease/cpu/macos/standard/ 2>/dev/null | wc -l)
echo " ✅ standard: $FILE_COUNT files copied"
else
echo " ⚠️ Standard CPU build failed - skipping"
fi
# ================================================================
# Copy Metal GPU binaries
# ================================================================
if [ "$METAL_GPU_SUCCESS" = "true" ]; then
echo "📦 Copying Metal GPU binaries..."
if [ -d "build-macos-standard-metal/bin" ]; then
cp -f build-macos-standard-metal/bin/* BitnetRelease/gpu/macos/standard-metal/ 2>/dev/null || true
fi
# Copy .metallib files (Metal shaders)
find build-macos-standard-metal -name "*.metallib" -type f -exec cp -f {} BitnetRelease/gpu/macos/standard-metal/ \; 2>/dev/null || true
# Copy .dylib files
find build-macos-standard-metal -name "*.dylib" -type f -exec cp -f {} BitnetRelease/gpu/macos/standard-metal/ \; 2>/dev/null || true
chmod +x BitnetRelease/gpu/macos/standard-metal/* 2>/dev/null || true
FILE_COUNT=$(ls -1 BitnetRelease/gpu/macos/standard-metal/ 2>/dev/null | wc -l)
echo " ✅ standard-metal: $FILE_COUNT files copied"
else
echo " ⚠️ Metal GPU build failed - skipping"
fi
echo ""
echo "=================================================="
echo "Creating README & VERIFICATION files..."
echo "=================================================="
# Create GPU README
cat > BitnetRelease/gpu/macos/README.md << 'EOF'
# 🍎 macOS GPU Support (Metal Only)
## What Works on macOS
macOS supports **Metal GPU acceleration** for standard llama.cpp inference.
### ✅ Supported: Metal GPU
- **Technology**: Apple Metal (built into macOS)
- **Hardware**: ALL Macs
- M1/M2/M3/M4 (Apple Silicon) - **Best performance!**
- Intel Macs with Iris/AMD GPUs - **Good performance**
- **Location**: `standard-metal/`
### ❌ NOT Supported on macOS
- **CUDA**: Apple doesn't support NVIDIA GPUs
- **Vulkan**: Apple uses Metal instead
- **BitNet GPU**: Requires CUDA (Windows/Linux only)
## Quick Start
```bash
cd standard-metal/
# Full GPU offload (fastest)
./llama-server -m your-model.gguf -ngl 99
# Partial GPU offload (balance CPU/GPU)
./llama-server -m your-model.gguf -ngl 35
```
---
Built by GitHub Actions: ${{ github.run_number }}
Commit: ${{ github.sha }}
EOF
# Create CPU VERIFICATION
cat > BitnetRelease/cpu/macos/VERIFICATION.md << 'EOF'
# 🔍 BitNet macOS Build Verification Report
## Build Matrix (GitHub Actions)
This directory contains **2 CPU variants** built by GitHub Actions:
### ✅ CPU Variants Built
- **bitnet-arm/** - BitNet for Apple Silicon (M1/M2/M3/M4 with TL1 kernels)
- **standard/** - Standard llama.cpp (universal, no BitNet)
### ⏭️ Skipped on GitHub Actions
- **bitnet-intel/** - BitNet for Intel Macs (requires local Intel Mac build)
- GitHub's macOS runners are Apple Silicon only
- Cross-compiling ARM → x86 causes CPU detection issues
- Intel Macs are legacy (discontinued 2020)
- To build: run `build-all-macos.sh` locally on an Intel Mac
### GPU Variant (separate directory)
- **../gpu/macos/standard-metal/** - Metal GPU acceleration (ALL Macs)
## Quick Start
### For M1/M2/M3/M4 (Apple Silicon):
```bash
cd bitnet-arm/
./llama-server -m bitnet-model.gguf
```
### For ANY Mac (universal standard build):
```bash
cd standard/
./llama-server -m model.gguf
```
### For Metal GPU (Best Performance):
```bash
cd ../gpu/macos/standard-metal/
./llama-server -m model.gguf -ngl 35 # Offload 35 layers to GPU
```
## Technical Details
- **Compiler:** Clang (from Xcode)
- **BitNet TL1:** ARM-optimized kernels for M1/M2/M3/M4
- **BitNet TL2:** x86-optimized kernels for Intel
- **Metal:** Apple's GPU framework (all Macs)
---
Built by GitHub Actions: ${{ github.run_number }}
Commit: ${{ github.sha }}
Date: ${{ github.event.head_commit.timestamp }}
EOF
echo "✅ README & VERIFICATION files created"
echo ""
echo "=================================================="
echo "BUILD SUMMARY"
echo "=================================================="
echo ""
echo "BitNet ARM: $([ "$BITNET_ARM_SUCCESS" = "true" ] && echo "✅ SUCCESS" || echo "❌ FAILED")"
echo "BitNet Intel: $([ "$BITNET_INTEL_SUCCESS" = "true" ] && echo "✅ SUCCESS" || echo "❌ FAILED")"
echo "Standard CPU: $([ "$STANDARD_CPU_SUCCESS" = "true" ] && echo "✅ SUCCESS" || echo "❌ FAILED")"
echo "Metal GPU: $([ "$METAL_GPU_SUCCESS" = "true" ] && echo "✅ SUCCESS" || echo "❌ FAILED")"
echo ""
echo "=================================================="
echo "FINAL STRUCTURE"
echo "=================================================="
echo ""
echo "BitnetRelease/cpu/macos/"
ls -lh BitnetRelease/cpu/macos/ 2>/dev/null || echo " (empty)"
echo ""
for subdir in bitnet-arm standard; do
if [ -d "BitnetRelease/cpu/macos/$subdir" ]; then
COUNT=$(ls -1 BitnetRelease/cpu/macos/$subdir 2>/dev/null | wc -l)
echo " ✅ $subdir/: $COUNT files"
fi
done
echo " ⏭️ bitnet-intel/: skipped (requires Intel Mac)"
echo ""
echo "BitnetRelease/gpu/macos/"
ls -lh BitnetRelease/gpu/macos/ 2>/dev/null || echo " (empty)"
echo ""
if [ -d "BitnetRelease/gpu/macos/standard-metal" ]; then
COUNT=$(ls -1 BitnetRelease/gpu/macos/standard-metal 2>/dev/null | wc -l)
echo " standard-metal/: $COUNT files"
fi
# ========================================================================
# Create Downloadable ZIP
# ========================================================================
- name: Create ZIP artifact
run: |
echo "📦 Creating ZIP archive for macOS builds ONLY..."
# Create temp directory structure (preserves full directory tree)
mkdir -p macos-release/cpu
mkdir -p macos-release/gpu
# Copy ENTIRE macOS directories (no filtering - just like Windows/Linux)
cp -r BitnetRelease/cpu/macos macos-release/cpu/ 2>/dev/null || true
cp -r BitnetRelease/gpu/macos macos-release/gpu/ 2>/dev/null || true
# Copy READMEs
cp BitnetRelease/README.md macos-release/ 2>/dev/null || true
cp BitnetRelease/DEVELOPER_GUIDE.md macos-release/ 2>/dev/null || true
cp BitnetRelease/LICENSE macos-release/ 2>/dev/null || true
# Zip CPU variants (entire cpu/macos/ directory tree)
cd macos-release
zip -r ../macos-cpu-all.zip cpu/
# Zip GPU variant (entire gpu/macos/ directory tree)
zip -r ../macos-gpu-metal.zip gpu/
# Zip everything together (complete macOS structure)
cd ..
zip -r macos-complete.zip macos-release/
echo ""
echo "✅ ZIP files created (macOS builds only - full directory structure):"
ls -lh macos-*.zip
# Cleanup temp directory
rm -rf macos-release
# ========================================================================
# Upload Artifacts
# ========================================================================
- name: Upload CPU artifacts
uses: actions/upload-artifact@v4
with:
name: macos-cpu-all
path: macos-cpu-all.zip
retention-days: 90
- name: Upload GPU artifacts
uses: actions/upload-artifact@v4
with:
name: macos-gpu-metal
path: macos-gpu-metal.zip
retention-days: 90
- name: Upload Complete Build
uses: actions/upload-artifact@v4
with:
name: macos-complete-build
path: macos-complete.zip
retention-days: 90
# ========================================================================
# Create GitHub Release (Optional)
# ========================================================================
- name: Create GitHub Release
if: github.event.inputs.create_release == 'true'
uses: softprops/action-gh-release@v1
with:
tag_name: macos-build-${{ github.run_number }}
name: macOS Complete Build (Build ${{ github.run_number }})
body: |
## 🍎 BitNet macOS Complete Build
**Build:** ${{ github.run_number }}
**Commit:** ${{ github.sha }}
**Date:** ${{ github.event.head_commit.timestamp }}
### ✅ What's Included:
- **BitNet ARM** - M1/M2/M3/M4 with TL1 kernels
- **BitNet Intel** - Intel Macs with TL2 kernels
- **Standard CPU** - Universal, no BitNet
- **Metal GPU** - ALL Macs (M1/M2/M3 + Intel)
### 📦 Download Options:
- **macos-complete.zip** - Everything (CPU + GPU)
- **macos-cpu-all.zip** - Just CPU variants (3 variants)
- **macos-gpu-metal.zip** - Just Metal GPU variant
### 📁 Extract & Use:
```bash
# Download macos-complete.zip
unzip macos-complete.zip
# For Apple Silicon (M1/M2/M3):
cd BitnetRelease/cpu/macos/bitnet-arm/
./llama-server -m model.gguf
# For Metal GPU (best performance):
cd BitnetRelease/gpu/macos/standard-metal/
./llama-server -m model.gguf -ngl 99
```
### 🚀 TabAgent Integration:
Extract to your TabAgent Server's `BitnetRelease/` folder:
```bash
unzip macos-complete.zip -d /path/to/TabAgent/Server/BitNet/
```
draft: false
prerelease: false
files: |
macos-complete.zip
macos-cpu-all.zip
macos-gpu-metal.zip
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}