Phase 1 of plan 009. The app still builds and runs on v2 — nothing in main.go or backend/ has moved yet — but the v3 CLI, its pinned runtime and its build-asset tree are now present, which is what Phase 2 needs. - wails/v3 v3.0.0-beta.8 pinned per D5, and wails3 added to the `tool` block beside the v2 CLI per D3. Both are vendored; neither is a global install. - build/ now holds the v3 build assets, copied wholesale from a `wails3 init` scaffold rather than hand-written. That collides with this repo's existing use of build/ as ignored build *output*, so .gitignore narrows to build/bin/ and bin/ and the assets are tracked. The mobile platforms are not carried: this is a desktop player (MPRIS over D-Bus, beep, XDG paths) and cannot target them. - build/config.yml's info block is filled from wails.json, which stays for now because the v2 CLI still reads it. - Taskfile.yml defaults PACKAGE_MANAGER to pnpm, since the scaffold assumes npm and frontend/package.json.md5 is part of the dep-caching scheme. One deviation from the plan worth recording. webkitgtk-6.0 is not installed on this machine, so the default GTK4 path is unavailable and the gtk3 fallback is in use. That also means `go tool wails3` does not work — the CLI itself fails to compile without webkitgtk-6.0 — while `go run -tags gtk3 .../cmd/wails3` does. The Makefile rewrite in the next commit has to account for that, and it goes away once the GTK4 dependency is installed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UDCbcCZQepnpSQYJ6SxxZm
226 lines
6.6 KiB
Docker
226 lines
6.6 KiB
Docker
# Cross-compile Wails v3 apps to any platform
|
|
#
|
|
# Darwin: Zig + macOS SDK
|
|
# Linux: Native GCC when host matches target, Zig for cross-arch
|
|
# Windows: Zig + bundled mingw
|
|
#
|
|
# Usage:
|
|
# docker build -t wails-cross -f Dockerfile.cross .
|
|
# docker run --rm -v $(pwd):/app wails-cross darwin arm64
|
|
# docker run --rm -v $(pwd):/app wails-cross darwin amd64
|
|
# docker run --rm -v $(pwd):/app wails-cross linux amd64
|
|
# docker run --rm -v $(pwd):/app wails-cross linux arm64
|
|
# docker run --rm -v $(pwd):/app wails-cross windows amd64
|
|
# docker run --rm -v $(pwd):/app wails-cross windows arm64
|
|
|
|
# Debian 13 provides the GTK >= 4.14 API baseline used by the default Linux backend.
|
|
FROM golang:1.26-trixie
|
|
|
|
ARG TARGETARCH
|
|
ARG GARBLE_VERSION=v0.16.0
|
|
|
|
# Install base tools, GCC, and GTK/WebKit dev packages
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
curl xz-utils python3 nodejs npm pkg-config gcc libc6-dev \
|
|
libgtk-3-dev libwebkit2gtk-4.1-dev \
|
|
libgtk-4-dev libwebkitgtk-6.0-dev \
|
|
&& pkg-config --atleast-version=4.14 gtk4 \
|
|
&& pkg-config --exists webkitgtk-6.0 \
|
|
&& pkg-config --exists gtk+-3.0 \
|
|
&& pkg-config --exists webkit2gtk-4.1 \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
RUN go install mvdan.cc/garble@${GARBLE_VERSION}
|
|
|
|
# Install Zig - automatically selects correct binary for host architecture.
|
|
# The SHA-256 is fetched from Zig's official download manifest and verified
|
|
# before extraction to protect against MITM or corrupted downloads.
|
|
ARG ZIG_VERSION=0.14.0
|
|
RUN ZIG_ARCH=$(case "${TARGETARCH}" in arm64) echo "aarch64" ;; *) echo "x86_64" ;; esac) && \
|
|
ZIG_FILE="zig-linux-${ZIG_ARCH}-${ZIG_VERSION}.tar.xz" && \
|
|
curl -fSL "https://ziglang.org/download/${ZIG_VERSION}/${ZIG_FILE}" -o "/tmp/${ZIG_FILE}" && \
|
|
EXPECTED=$(curl -fsSL "https://ziglang.org/download/index.json" | \
|
|
python3 -c "import json,sys; d=json.load(sys.stdin); print(d[sys.argv[1]][sys.argv[2]+'-linux']['shasum'])" \
|
|
"${ZIG_VERSION}" "${ZIG_ARCH}") && \
|
|
echo "${EXPECTED} /tmp/${ZIG_FILE}" | sha256sum -c - && \
|
|
tar -xJ -f "/tmp/${ZIG_FILE}" -C /opt && \
|
|
rm "/tmp/${ZIG_FILE}" && \
|
|
ln -s /opt/zig-linux-${ZIG_ARCH}-${ZIG_VERSION}/zig /usr/local/bin/zig
|
|
|
|
# Download macOS SDK (required for darwin targets)
|
|
ARG MACOS_SDK_VERSION=14.5
|
|
RUN curl -L "https://github.com/joseluisq/macosx-sdks/releases/download/${MACOS_SDK_VERSION}/MacOSX${MACOS_SDK_VERSION}.sdk.tar.xz" \
|
|
| tar -xJ -C /opt \
|
|
&& mv /opt/MacOSX${MACOS_SDK_VERSION}.sdk /opt/macos-sdk
|
|
|
|
ENV MACOS_SDK_PATH=/opt/macos-sdk
|
|
|
|
# Create Zig CC wrappers for cross-compilation targets
|
|
# Darwin and Windows use Zig; Linux uses native GCC (run with --platform for cross-arch)
|
|
|
|
# Darwin arm64
|
|
COPY <<'ZIGWRAP' /usr/local/bin/zcc-darwin-arm64
|
|
#!/bin/sh
|
|
ARGS=""
|
|
SKIP_NEXT=0
|
|
for arg in "$@"; do
|
|
if [ $SKIP_NEXT -eq 1 ]; then
|
|
SKIP_NEXT=0
|
|
continue
|
|
fi
|
|
case "$arg" in
|
|
-target) SKIP_NEXT=1 ;;
|
|
-mmacosx-version-min=*) ;;
|
|
*) ARGS="$ARGS $arg" ;;
|
|
esac
|
|
done
|
|
exec zig cc -fno-sanitize=all -target aarch64-macos-none -isysroot /opt/macos-sdk -I/opt/macos-sdk/usr/include -L/opt/macos-sdk/usr/lib -F/opt/macos-sdk/System/Library/Frameworks -w $ARGS
|
|
ZIGWRAP
|
|
RUN chmod +x /usr/local/bin/zcc-darwin-arm64
|
|
|
|
# Darwin amd64
|
|
COPY <<'ZIGWRAP' /usr/local/bin/zcc-darwin-amd64
|
|
#!/bin/sh
|
|
ARGS=""
|
|
SKIP_NEXT=0
|
|
for arg in "$@"; do
|
|
if [ $SKIP_NEXT -eq 1 ]; then
|
|
SKIP_NEXT=0
|
|
continue
|
|
fi
|
|
case "$arg" in
|
|
-target) SKIP_NEXT=1 ;;
|
|
-mmacosx-version-min=*) ;;
|
|
*) ARGS="$ARGS $arg" ;;
|
|
esac
|
|
done
|
|
exec zig cc -fno-sanitize=all -target x86_64-macos-none -isysroot /opt/macos-sdk -I/opt/macos-sdk/usr/include -L/opt/macos-sdk/usr/lib -F/opt/macos-sdk/System/Library/Frameworks -w $ARGS
|
|
ZIGWRAP
|
|
RUN chmod +x /usr/local/bin/zcc-darwin-amd64
|
|
|
|
# Windows amd64 - uses Zig's bundled mingw
|
|
COPY <<'ZIGWRAP' /usr/local/bin/zcc-windows-amd64
|
|
#!/bin/sh
|
|
ARGS=""
|
|
SKIP_NEXT=0
|
|
for arg in "$@"; do
|
|
if [ $SKIP_NEXT -eq 1 ]; then
|
|
SKIP_NEXT=0
|
|
continue
|
|
fi
|
|
case "$arg" in
|
|
-target) SKIP_NEXT=1 ;;
|
|
-Wl,*) ;;
|
|
*) ARGS="$ARGS $arg" ;;
|
|
esac
|
|
done
|
|
exec zig cc -target x86_64-windows-gnu $ARGS
|
|
ZIGWRAP
|
|
RUN chmod +x /usr/local/bin/zcc-windows-amd64
|
|
|
|
# Windows arm64 - uses Zig's bundled mingw
|
|
COPY <<'ZIGWRAP' /usr/local/bin/zcc-windows-arm64
|
|
#!/bin/sh
|
|
ARGS=""
|
|
SKIP_NEXT=0
|
|
for arg in "$@"; do
|
|
if [ $SKIP_NEXT -eq 1 ]; then
|
|
SKIP_NEXT=0
|
|
continue
|
|
fi
|
|
case "$arg" in
|
|
-target) SKIP_NEXT=1 ;;
|
|
-Wl,*) ;;
|
|
*) ARGS="$ARGS $arg" ;;
|
|
esac
|
|
done
|
|
exec zig cc -target aarch64-windows-gnu $ARGS
|
|
ZIGWRAP
|
|
RUN chmod +x /usr/local/bin/zcc-windows-arm64
|
|
|
|
# Build script
|
|
COPY <<'SCRIPT' /usr/local/bin/build.sh
|
|
#!/bin/sh
|
|
set -e
|
|
|
|
OS=${1:-darwin}
|
|
ARCH=${2:-arm64}
|
|
|
|
case "${OS}-${ARCH}" in
|
|
darwin-arm64|darwin-aarch64)
|
|
export CC=zcc-darwin-arm64
|
|
export GOARCH=arm64
|
|
export GOOS=darwin
|
|
;;
|
|
darwin-amd64|darwin-x86_64)
|
|
export CC=zcc-darwin-amd64
|
|
export GOARCH=amd64
|
|
export GOOS=darwin
|
|
;;
|
|
linux-arm64|linux-aarch64)
|
|
export CC=gcc
|
|
export GOARCH=arm64
|
|
export GOOS=linux
|
|
;;
|
|
linux-amd64|linux-x86_64)
|
|
export CC=gcc
|
|
export GOARCH=amd64
|
|
export GOOS=linux
|
|
;;
|
|
windows-arm64|windows-aarch64)
|
|
export CC=zcc-windows-arm64
|
|
export GOARCH=arm64
|
|
export GOOS=windows
|
|
;;
|
|
windows-amd64|windows-x86_64)
|
|
export CC=zcc-windows-amd64
|
|
export GOARCH=amd64
|
|
export GOOS=windows
|
|
;;
|
|
*)
|
|
echo "Usage: <os> <arch>"
|
|
echo " os: darwin, linux, windows"
|
|
echo " arch: amd64, arm64"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
export CGO_ENABLED=1
|
|
export CGO_CFLAGS="-w"
|
|
|
|
# Build frontend if exists and not already built (host may have built it)
|
|
if [ -d "frontend" ] && [ -f "frontend/package.json" ] && [ ! -d "frontend/dist" ]; then
|
|
(cd frontend && npm install --silent && npm run build --silent)
|
|
fi
|
|
|
|
# Build
|
|
APP=${APP_NAME:-$(basename $(pwd))}
|
|
mkdir -p bin
|
|
|
|
EXT=""
|
|
LDFLAGS="-s -w"
|
|
if [ "$GOOS" = "windows" ]; then
|
|
EXT=".exe"
|
|
LDFLAGS="-s -w -H windowsgui"
|
|
fi
|
|
|
|
TAGS="production"
|
|
if [ -n "$EXTRA_TAGS" ]; then
|
|
TAGS="${TAGS},${EXTRA_TAGS}"
|
|
fi
|
|
|
|
COMPILER="go build"
|
|
if [ "$OBFUSCATED" = "true" ]; then
|
|
COMPILER="garble ${GARBLE_ARGS} build"
|
|
TAGS="${TAGS},wails_obfuscated"
|
|
fi
|
|
|
|
${COMPILER} -tags "$TAGS" -trimpath -buildvcs=false -ldflags="$LDFLAGS" -o bin/${APP}-${GOOS}-${GOARCH}${EXT} .
|
|
echo "Built: bin/${APP}-${GOOS}-${GOARCH}${EXT}"
|
|
SCRIPT
|
|
RUN chmod +x /usr/local/bin/build.sh
|
|
|
|
WORKDIR /app
|
|
ENTRYPOINT ["/usr/local/bin/build.sh"]
|
|
CMD ["darwin", "arm64"]
|