Add cross-compilation support for Linux and Windows

- Add Docker-based build system for cross-compiling on Apple Silicon
- Create Dockerfiles for Linux x86_64 and ARM64, Windows x86_64
- Add build-all.sh script for automated multi-platform builds
- Configure cargo-deb and cargo-generate-rpm for Linux packaging
- Update README with cross-compilation instructions

Supported outputs:
- Linux x86_64: .deb, .rpm, .tar.gz
- Windows x86_64: .zip

Note: Linux ARM64 disabled due to upstream zune-jpeg NEON bug
This commit is contained in:
cottongin
2026-02-05 08:21:42 -05:00
parent 054deb873d
commit cde8ae5626
8 changed files with 239 additions and 0 deletions

1
.gitignore vendored
View File

@@ -1,5 +1,6 @@
chat-summaries/ chat-summaries/
target/ target/
dist/
.DS_Store .DS_Store
*.mp4 *.mp4

View File

@@ -41,3 +41,17 @@ open = "5"
[profile.release] [profile.release]
opt-level = 3 opt-level = 3
lto = true lto = true
[package.metadata.deb]
maintainer = "cottongin"
copyright = "2026"
depends = "ffmpeg"
section = "graphics"
# Note: cargo-deb auto-detects binary location when --target is specified
[package.metadata.generate-rpm]
assets = [
{ source = "target/x86_64-unknown-linux-gnu/release/avif-maker", dest = "/usr/bin/avif-maker", mode = "755" }
]
[package.metadata.generate-rpm.requires]
ffmpeg = "*"

19
Cross.toml Normal file
View File

@@ -0,0 +1,19 @@
[build]
# Don't mount host's cargo/rustup - use container's toolchain
pre-build = []
[build.env]
passthrough = ["RUST_BACKTRACE"]
[target.x86_64-unknown-linux-gnu]
image = "avif-maker-linux-x86_64"
# Use container's Rust instead of host's
env.volumes = []
[target.aarch64-unknown-linux-gnu]
image = "avif-maker-linux-arm64"
env.volumes = []
[target.x86_64-pc-windows-gnu]
image = "avif-maker-windows-x86_64"
env.volumes = []

View File

@@ -85,6 +85,51 @@ Three test files are included:
- `Highlander-IMustFlipSmaller-OG.gif` - Animated GIF without transparency - `Highlander-IMustFlipSmaller-OG.gif` - Animated GIF without transparency
- `BTS-240-art.gif` - Animated GIF with transparency (1-bit alpha) - `BTS-240-art.gif` - Animated GIF with transparency (1-bit alpha)
## Cross-Compilation (Build for Linux/Windows from macOS)
Build distributable packages for multiple platforms from a single machine.
### Prerequisites
```bash
# Install build tools
cargo install cross cargo-deb cargo-generate-rpm
# Ensure Docker Desktop is installed and running
docker info
```
### Docker Configuration (Apple Silicon Mac)
Before cross-compiling, configure Docker Desktop to share the Homebrew path:
1. Open Docker Desktop
2. Go to **Settings****Resources****File Sharing**
3. Add `/opt/homebrew` to the shared paths
4. Click **Apply & Restart**
### Building
```bash
# First-time setup: Build Docker images
./scripts/build-all.sh --setup-docker
# Build all targets
./scripts/build-all.sh
```
### Output
After building, packages are in `dist/<version>/`:
| Platform | Files | Notes |
|----------|-------|-------|
| Linux x86_64 | `.deb`, `.rpm`, `.tar.gz` | Cross-compiled |
| Linux ARM64 | `.tar.gz` | Build natively on ARM64 Linux |
| Windows x86_64 | `.zip` | Cross-compiled |
**Note:** Linux ARM64 cross-compilation is disabled due to an upstream `zune-jpeg` NEON bug. Build ARM64 natively on a Linux ARM64 system.
## Architecture ## Architecture
``` ```
@@ -105,6 +150,9 @@ avif-maker/
│ ├── drop_zone.rs # Drag-and-drop area │ ├── drop_zone.rs # Drag-and-drop area
│ ├── settings.rs # Settings panel │ ├── settings.rs # Settings panel
│ └── queue.rs # Job queue display │ └── queue.rs # Job queue display
├── docker/ # Cross-compilation Dockerfiles
├── scripts/
│ └── build-all.sh # Build script for all platforms
└── Cargo.toml └── Cargo.toml
``` ```

View File

@@ -0,0 +1,22 @@
FROM --platform=linux/amd64 rust:1.85-bookworm
# Install build dependencies and ARM64 cross-compiler
RUN dpkg --add-architecture arm64 && apt-get update && apt-get install -y \
cmake \
nasm \
meson \
ninja-build \
gcc-aarch64-linux-gnu \
g++-aarch64-linux-gnu \
libc6-dev-arm64-cross \
&& rm -rf /var/lib/apt/lists/*
# Add the ARM64 target
RUN rustup target add aarch64-unknown-linux-gnu
# Configure cargo for cross-compilation
ENV CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc
ENV CC_aarch64_unknown_linux_gnu=aarch64-linux-gnu-gcc
ENV CXX_aarch64_unknown_linux_gnu=aarch64-linux-gnu-g++
WORKDIR /build

View File

@@ -0,0 +1,25 @@
FROM --platform=linux/amd64 rust:1.85-bookworm
# Install build dependencies for libavif, dav1d, and GUI
RUN apt-get update && apt-get install -y \
cmake \
nasm \
meson \
ninja-build \
libx11-dev \
libxcursor-dev \
libxrandr-dev \
libxi-dev \
libgl1-mesa-dev \
libwayland-dev \
libxkbcommon-dev \
rpm \
&& rm -rf /var/lib/apt/lists/*
# Add the target
RUN rustup target add x86_64-unknown-linux-gnu
# Install packaging tools
RUN cargo install cargo-deb cargo-generate-rpm
WORKDIR /build

View File

@@ -0,0 +1,20 @@
FROM --platform=linux/amd64 rust:1.85-bookworm
# Install build dependencies and MinGW cross-compiler
RUN apt-get update && apt-get install -y \
cmake \
nasm \
meson \
ninja-build \
mingw-w64 \
&& rm -rf /var/lib/apt/lists/*
# Add the Windows target
RUN rustup target add x86_64-pc-windows-gnu
# Configure cargo for cross-compilation
ENV CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER=x86_64-w64-mingw32-gcc
ENV CC_x86_64_pc_windows_gnu=x86_64-w64-mingw32-gcc
ENV CXX_x86_64_pc_windows_gnu=x86_64-w64-mingw32-g++
WORKDIR /build

90
scripts/build-all.sh Executable file
View File

@@ -0,0 +1,90 @@
#!/bin/bash
set -e
# Cross-compilation build script for AVIF Maker
# Uses Docker directly (not cross tool) for Apple Silicon compatibility
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
cd "$PROJECT_DIR"
VERSION=${1:-$(grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)".*/\1/')}
DIST_DIR="dist/$VERSION"
# Handle --setup-docker flag
if [[ "$1" == "--setup-docker" ]]; then
echo "Building Docker images for cross-compilation..."
echo ""
echo "Building Linux x86_64 image..."
docker build --platform linux/amd64 -t avif-maker-linux-x86_64 -f docker/Dockerfile.linux-x86_64 .
echo ""
echo "Building Linux ARM64 image..."
docker build --platform linux/amd64 -t avif-maker-linux-arm64 -f docker/Dockerfile.linux-arm64 .
echo ""
echo "Building Windows x86_64 image..."
docker build --platform linux/amd64 -t avif-maker-windows-x86_64 -f docker/Dockerfile.windows-x86_64 .
echo ""
echo "Docker images built successfully!"
echo "You can now run: ./scripts/build-all.sh"
exit 0
fi
mkdir -p "$DIST_DIR"
echo "Building AVIF Maker v$VERSION"
echo "================================"
# Check if Docker images exist
if ! docker image inspect avif-maker-linux-x86_64 >/dev/null 2>&1; then
echo "Docker images not found. Run './scripts/build-all.sh --setup-docker' first."
exit 1
fi
# Linux x86_64
echo ""
echo "Building and packaging Linux x86_64..."
docker run --rm --platform linux/amd64 \
-v "$PROJECT_DIR:/build" \
-w /build \
avif-maker-linux-x86_64 \
bash -c "
set -e
echo 'Compiling...'
cargo build --release --target x86_64-unknown-linux-gnu
echo 'Stripping binary...'
strip target/x86_64-unknown-linux-gnu/release/avif-maker
echo 'Creating .deb package...'
cargo deb --target x86_64-unknown-linux-gnu --no-build -o dist/$VERSION/
echo 'Creating .rpm package...'
cargo generate-rpm --target x86_64-unknown-linux-gnu -o dist/$VERSION/
"
# Create tarball (can run on host)
echo "Creating tarball..."
tar -czvf "$DIST_DIR/avif-maker-$VERSION-linux-x86_64.tar.gz" \
-C target/x86_64-unknown-linux-gnu/release avif-maker
# Linux ARM64
# NOTE: ARM64 cross-compilation is currently disabled due to upstream zune-jpeg NEON bug.
# Build ARM64 natively on a Linux ARM64 system instead.
echo ""
echo "Skipping Linux ARM64 (upstream zune-jpeg bug with NEON cross-compilation)"
echo "To build ARM64, run natively on a Linux ARM64 system."
# Windows x86_64
echo ""
echo "Building Windows x86_64..."
docker run --rm --platform linux/amd64 \
-v "$PROJECT_DIR:/build" \
-w /build \
avif-maker-windows-x86_64 \
cargo build --release --target x86_64-pc-windows-gnu
zip -j "$DIST_DIR/avif-maker-$VERSION-windows-x86_64.zip" \
target/x86_64-pc-windows-gnu/release/avif-maker.exe
echo ""
echo "================================"
echo "Build complete! Artifacts in $DIST_DIR/"
echo ""
ls -la "$DIST_DIR/"