diff --git a/.gitignore b/.gitignore index 8e797c8..2cad518 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ chat-summaries/ target/ +dist/ .DS_Store *.mp4 diff --git a/Cargo.toml b/Cargo.toml index 1428dc0..9515571 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,3 +41,17 @@ open = "5" [profile.release] opt-level = 3 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 = "*" diff --git a/Cross.toml b/Cross.toml new file mode 100644 index 0000000..5de2e28 --- /dev/null +++ b/Cross.toml @@ -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 = [] diff --git a/README.md b/README.md index 9a2853f..b0b959a 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,51 @@ Three test files are included: - `Highlander-IMustFlipSmaller-OG.gif` - Animated GIF without transparency - `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//`: + +| 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 ``` @@ -105,6 +150,9 @@ avif-maker/ │ ├── drop_zone.rs # Drag-and-drop area │ ├── settings.rs # Settings panel │ └── queue.rs # Job queue display +├── docker/ # Cross-compilation Dockerfiles +├── scripts/ +│ └── build-all.sh # Build script for all platforms └── Cargo.toml ``` diff --git a/docker/Dockerfile.linux-arm64 b/docker/Dockerfile.linux-arm64 new file mode 100644 index 0000000..cb28be0 --- /dev/null +++ b/docker/Dockerfile.linux-arm64 @@ -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 diff --git a/docker/Dockerfile.linux-x86_64 b/docker/Dockerfile.linux-x86_64 new file mode 100644 index 0000000..31c323b --- /dev/null +++ b/docker/Dockerfile.linux-x86_64 @@ -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 diff --git a/docker/Dockerfile.windows-x86_64 b/docker/Dockerfile.windows-x86_64 new file mode 100644 index 0000000..2533fa6 --- /dev/null +++ b/docker/Dockerfile.windows-x86_64 @@ -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 diff --git a/scripts/build-all.sh b/scripts/build-all.sh new file mode 100755 index 0000000..877410f --- /dev/null +++ b/scripts/build-all.sh @@ -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/"