142 lines
5.4 KiB
Docker
142 lines
5.4 KiB
Docker
# syntax=docker/dockerfile:1.7
|
|
#
|
|
# Reproducible build for libghostty + the Qt frontend (ghastty).
|
|
#
|
|
# Usage:
|
|
# docker build -t ghastty .
|
|
# docker run --rm -v "$PWD/out:/host-out" ghastty \
|
|
# sh -c 'cp -a /out/. /host-out/'
|
|
#
|
|
# The runtime container does not ship a usable terminal — the Qt
|
|
# frontend wants a Wayland socket from the host. This image is for
|
|
# building (and CI testing) only.
|
|
#
|
|
# Stage layout:
|
|
# - base : Fedora + the Qt/Wayland deps both stages need
|
|
# - zig : pinned Zig toolchain (kept separate so a deps-only
|
|
# rebuild doesn't re-fetch Zig)
|
|
# - libghostty : zig build of libghostty (-Dapp-runtime=none) + tests
|
|
# - qt : cmake build of qt/ against the libghostty artifact
|
|
# - out : minimal final stage holding only the built binaries
|
|
#
|
|
# Why Fedora rather than Debian? We need recent Qt 6 (>= 6.6 for the
|
|
# non-deprecated LayerShellQt screen API) and recent LayerShellQt.
|
|
# Fedora 42 ships Qt 6.9 and a current LayerShellQt; Debian trixie was
|
|
# stuck on Qt 6.8.2 + LayerShellQt 6.3.4 which deprecated
|
|
# setScreenConfiguration.
|
|
|
|
ARG FEDORA_VERSION=42
|
|
|
|
# Pinned to the project's minimum_zig_version (build.zig.zon).
|
|
ARG ZIG_VERSION=0.15.2
|
|
|
|
# ---------------------------------------------------------------------
|
|
# base — system packages shared across the build stages.
|
|
# ---------------------------------------------------------------------
|
|
FROM fedora:${FEDORA_VERSION} AS base
|
|
|
|
# Single dnf layer so the package cache is dropped before the next
|
|
# stage. The list mixes:
|
|
# - build tooling (cmake, ninja, pkg-config, gcc, gcc-c++)
|
|
# - libghostty build deps via Zig (most are vendored; libxml2-devel
|
|
# is pulled in by the Sentry/breakpad path on Linux)
|
|
# - Qt 6 modules the frontend uses (Gui, Widgets, OpenGL, DBus,
|
|
# Multimedia, Svg) plus LayerShellQt
|
|
# - native-protocol deps the frontend hits directly (xkbcommon,
|
|
# wayland-client, wayland-scanner, xcb)
|
|
RUN dnf install -y --setopt=install_weak_deps=False \
|
|
ca-certificates \
|
|
curl \
|
|
xz \
|
|
tar \
|
|
git \
|
|
pkgconfig \
|
|
cmake \
|
|
ninja-build \
|
|
gcc \
|
|
gcc-c++ \
|
|
qt6-qtbase-devel \
|
|
qt6-qtbase-private-devel \
|
|
qt6-qtmultimedia-devel \
|
|
qt6-qtsvg-devel \
|
|
layer-shell-qt-devel \
|
|
libxkbcommon-devel \
|
|
wayland-devel \
|
|
wayland-protocols-devel \
|
|
libxcb-devel \
|
|
libxml2-devel \
|
|
&& dnf clean all
|
|
|
|
# ---------------------------------------------------------------------
|
|
# zig — fetch and unpack the pinned Zig toolchain.
|
|
#
|
|
# Kept separate from `base` so changing dnf deps does not invalidate
|
|
# the (large) Zig download layer.
|
|
# ---------------------------------------------------------------------
|
|
FROM base AS zig
|
|
ARG ZIG_VERSION
|
|
|
|
RUN set -eux; \
|
|
arch="$(uname -m)"; \
|
|
case "$arch" in \
|
|
x86_64) zig_arch=x86_64 ;; \
|
|
aarch64) zig_arch=aarch64 ;; \
|
|
*) echo "unsupported arch: $arch" >&2; exit 1 ;; \
|
|
esac; \
|
|
tarball="zig-${zig_arch}-linux-${ZIG_VERSION}.tar.xz"; \
|
|
curl -fsSL -o "/tmp/${tarball}" \
|
|
"https://ziglang.org/download/${ZIG_VERSION}/${tarball}"; \
|
|
mkdir -p /opt/zig; \
|
|
tar -xJf "/tmp/${tarball}" -C /opt/zig --strip-components=1; \
|
|
rm "/tmp/${tarball}"; \
|
|
ln -s /opt/zig/zig /usr/local/bin/zig; \
|
|
zig version
|
|
|
|
# ---------------------------------------------------------------------
|
|
# libghostty — Zig build of the libghostty shared library + tests.
|
|
#
|
|
# We mount the source tree rather than COPY so a `docker build` run
|
|
# does not bake the entire repo into this layer. Caches:
|
|
# - /root/.cache/zig : Zig's per-user cache (compiled deps)
|
|
# - /src/.zig-cache : project-local cache (incremental rebuilds)
|
|
# ---------------------------------------------------------------------
|
|
FROM zig AS libghostty
|
|
WORKDIR /src
|
|
COPY . /src
|
|
|
|
# `-Dapp-runtime=none` makes the Zig build emit libghostty (the .so
|
|
# our Qt frontend links against) and skips the GTK frontend. Tests
|
|
# run first so a regression in libghostty fails the build cleanly,
|
|
# rather than later in the slower Qt stage.
|
|
RUN --mount=type=cache,target=/root/.cache/zig \
|
|
--mount=type=cache,target=/src/.zig-cache \
|
|
set -eux; \
|
|
zig build test -Dapp-runtime=none -Doptimize=Debug; \
|
|
zig build -Dapp-runtime=none -Doptimize=ReleaseFast
|
|
|
|
# ---------------------------------------------------------------------
|
|
# qt — CMake build of the Qt frontend against the libghostty artifact.
|
|
# ---------------------------------------------------------------------
|
|
FROM libghostty AS qt
|
|
WORKDIR /src/qt
|
|
|
|
# The CMake project links against zig-out/lib/ghostty-internal.so and
|
|
# materialises libghostty.so as a build-tree symlink (see qt/CMakeLists.txt).
|
|
# `--install` lays the binary, .so, .desktop entry and icon into /out
|
|
# under the standard FHS layout (bin/, lib/, share/...).
|
|
RUN set -eux; \
|
|
cmake -S /src/qt -B /src/qt/build -G Ninja \
|
|
-DCMAKE_BUILD_TYPE=Release; \
|
|
cmake --build /src/qt/build --parallel "$(nproc)"; \
|
|
cmake --install /src/qt/build --prefix /out
|
|
|
|
# ---------------------------------------------------------------------
|
|
# out — only the final artifacts. Run this image to extract them.
|
|
# ---------------------------------------------------------------------
|
|
FROM fedora:${FEDORA_VERSION} AS out
|
|
COPY --from=qt /out /out
|
|
|
|
# Default command lists the artifacts so `docker run --rm ghastty`
|
|
# is informative without --entrypoint heroics.
|
|
CMD ["sh", "-c", "find /out -type f -o -type l | sort"]
|