# macOS Cross-Compilation Setup

## Overview

GuruRMM agent can now be built for macOS (Intel and Apple Silicon) directly on the Linux build server (172.16.3.30) without requiring a Mac for compilation.

## Architecture

- **Build Server**: Ubuntu 22.04 LTS (172.16.3.30)
- **Toolchain**: osxcross with macOS SDK 14.5
- **Targets**:
  - `x86_64-apple-darwin` (Intel Macs)
  - `aarch64-apple-darwin` (Apple Silicon Macs)
- **TLS Stack**: rustls (pure Rust, no native dependencies)

## Key Changes

### 1. Cargo.toml Modifications

The agent now uses **conditional dependencies** for TLS:

- **Windows/Linux**: `native-tls` (for Windows 7 compatibility)
- **macOS**: `rustls-tls-native-roots` (for easier cross-compilation)

```toml
[target.'cfg(not(target_os = "macos"))'.dependencies]
tokio-tungstenite = { version = "0.24", features = ["native-tls"] }
reqwest = { version = "0.12", default-features = false, features = ["json", "native-tls"] }

[target.'cfg(target_os = "macos")'.dependencies]
tokio-tungstenite = { version = "0.24", features = ["rustls-tls-native-roots"] }
reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls-native-roots", "blocking"] }
```

### 2. Cargo Configuration (.cargo/config.toml)

Linker configuration for macOS targets:

```toml
[target.x86_64-apple-darwin]
linker = "/opt/osxcross/target/bin/x86_64-apple-darwin23.5-clang"
ar = "/opt/osxcross/target/bin/x86_64-apple-darwin23.5-ar"

[target.aarch64-apple-darwin]
linker = "/opt/osxcross/target/bin/aarch64-apple-darwin23.5-clang"
ar = "/opt/osxcross/target/bin/aarch64-apple-darwin23.5-ar"
```

## Build Server Setup

### Installed Components

1. **osxcross**: `/opt/osxcross/`
   - macOS SDK 14.5 (darwin23.5)
   - Clang/LLVM cross-compilers
   - Binutils for macOS

2. **Rust Toolchain**:
   - rustc 1.94.1
   - Targets: `x86_64-apple-darwin`, `aarch64-apple-darwin`

3. **Build Dependencies**:
   - clang-14
   - cmake 3.22.1
   - libxml2-dev
   - uuid-dev

### Environment Variables

For cross-compilation, the following must be set:

```bash
export PATH="/opt/osxcross/target/bin:$PATH"
export CC_x86_64_apple_darwin=x86_64-apple-darwin23.5-clang
export AR_x86_64_apple_darwin=x86_64-apple-darwin23.5-ar
export CC_aarch64_apple_darwin=aarch64-apple-darwin23.5-clang
export AR_aarch64_apple_darwin=aarch64-apple-darwin23.5-ar
```

## Building for macOS

### Using the Build Script

The simplest method is to use the provided build script:

```bash
cd ~/gururmm/agent
./build-macos.sh
```

This will:
- Build for both Intel (x86_64) and Apple Silicon (arm64)
- Create binaries in `dist/` directory
- Generate SHA256 checksums
- Name binaries: `gururmm-agent-macos-{amd64|arm64}-v{version}`

### Manual Build

For individual targets:

```bash
# Source environment
source ~/.cargo/env
export PATH="/opt/osxcross/target/bin:$PATH"

# Intel Macs
export CC_x86_64_apple_darwin=x86_64-apple-darwin23.5-clang
export AR_x86_64_apple_darwin=x86_64-apple-darwin23.5-ar
cargo build --release --target x86_64-apple-darwin

# Apple Silicon Macs
export CC_aarch64_apple_darwin=aarch64-apple-darwin23.5-clang
export AR_aarch64_apple_darwin=aarch64-apple-darwin23.5-ar
cargo build --release --target aarch64-apple-darwin
```

## Build Output

### Binary Sizes

- **Intel (x86_64)**: ~3.5 MB
- **Apple Silicon (arm64)**: ~3.1 MB

### Build Times (on 172.16.3.30)

- **Clean build**: ~1 minute 30 seconds per target
- **Incremental build**: ~20-30 seconds per target

### Output Directory Structure

```
dist/
├── gururmm-agent-macos-amd64-v0.6.0
├── gururmm-agent-macos-amd64-v0.6.0.sha256
├── gururmm-agent-macos-arm64-v0.6.0
└── gururmm-agent-macos-arm64-v0.6.0.sha256
```

## Deployment

### Installation on macOS

Intel Macs:
```bash
curl -fsSL http://172.16.3.30/downloads/gururmm-agent-macos-amd64 -o /tmp/gururmm-agent
chmod +x /tmp/gururmm-agent
sudo /tmp/gururmm-agent install --server-url wss://rmm-api.azcomputerguru.com/ws --api-key SITE-CODE
```

Apple Silicon Macs:
```bash
curl -fsSL http://172.16.3.30/downloads/gururmm-agent-macos-arm64 -o /tmp/gururmm-agent
chmod +x /tmp/gururmm-agent
sudo /tmp/gururmm-agent install --server-url wss://rmm-api.azcomputerguru.com/ws --api-key SITE-CODE
```

### macOS Service Configuration

The agent installs as a launchd service:
- **Plist**: `/Library/LaunchDaemons/com.gururmm.agent.plist`
- **Binary**: `/usr/local/bin/gururmm-agent`
- **Config**: `/etc/gururmm/agent.toml`

## Troubleshooting

### Build Failures

1. **"ring" crate compilation errors**:
   - Ensure `CC_*` and `AR_*` environment variables are set
   - Verify osxcross binaries are in PATH

2. **Linker errors**:
   - Check `.cargo/config.toml` has correct linker paths
   - Verify osxcross installation at `/opt/osxcross/target/bin/`

3. **"native-tls" errors on macOS**:
   - Ensure Cargo.toml uses `rustls-tls-native-roots` for macOS targets
   - Conditional dependencies must be properly configured

### Testing Binaries

To verify a macOS binary was built correctly:

```bash
# On build server
file target/x86_64-apple-darwin/release/gururmm-agent
# Output: Mach-O 64-bit executable x86_64

file target/aarch64-apple-darwin/release/gururmm-agent
# Output: Mach-O 64-bit executable arm64
```

On an actual Mac, the binary should run without errors:
```bash
./gururmm-agent --version
# Output: gururmm-agent 0.6.0
```

## Maintenance

### Updating osxcross

To update to a newer macOS SDK:

1. Download SDK from https://github.com/joseluisq/macosx-sdks/releases
2. Place in `/opt/osxcross/tarballs/`
3. Run `/opt/osxcross/build.sh`
4. Update linker paths in `.cargo/config.toml` if SDK version changes

### Updating Rust Targets

```bash
rustup target add x86_64-apple-darwin
rustup target add aarch64-apple-darwin
```

## Security Notes

- macOS SDK usage is in a legal gray area; osxcross requires accepting Xcode license terms
- Binaries built with osxcross are functionally identical to native macOS builds
- TLS implementation (rustls) is audited and widely used in production Rust applications
- No code signing is performed; users will need to approve binary on first run

## CI/CD Integration

The build script can be integrated into automated builds:

```bash
# Example: Build on git push
cd ~/gururmm/agent
git pull
./build-macos.sh
# Copy to deployment directory
cp dist/gururmm-agent-macos-* /var/www/gururmm/downloads/
```

## Performance

Cross-compiled binaries perform identically to native builds:
- No runtime overhead from cross-compilation
- Full optimization with `opt-level = "z"` and LTO
- Binary stripping reduces size without affecting performance

## Future Enhancements

- [ ] Code signing for macOS binaries (requires Apple Developer account)
- [ ] Notarization for Gatekeeper compatibility
- [ ] Universal binary (combined Intel + ARM)
- [ ] Automated CI/CD pipeline with GitHub Actions (macOS runners)

---

**Last Updated**: 2026-04-03
**Build Server**: 172.16.3.30 (Ubuntu 22.04)
**osxcross Version**: 1.5
**SDK Version**: macOS 14.5 (darwin23.5)
