summaryrefslogtreecommitdiff
path: root/docs/handbook/images4docker/qt6-verification.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/handbook/images4docker/qt6-verification.md')
-rw-r--r--docs/handbook/images4docker/qt6-verification.md283
1 files changed, 283 insertions, 0 deletions
diff --git a/docs/handbook/images4docker/qt6-verification.md b/docs/handbook/images4docker/qt6-verification.md
new file mode 100644
index 0000000000..b29343e19f
--- /dev/null
+++ b/docs/handbook/images4docker/qt6-verification.md
@@ -0,0 +1,283 @@
+# images4docker — Qt6 Verification
+
+## Purpose
+
+Every Dockerfile in images4docker includes a mandatory **Qt6 toolchain
+verification gate**. This gate runs at the end of the `RUN` instruction,
+after all packages have been installed. If the gate fails, the entire
+Docker build fails — there is **no fallback to Qt5** and no option to skip
+the check.
+
+This ensures that every image published to `ghcr.io/project-tick-infra/images/`
+is guaranteed to have a working Qt6 toolchain available.
+
+---
+
+## How the Gate Works
+
+### Step 1: PATH Extension
+
+Before checking for Qt6 binaries, the `PATH` environment variable is extended
+to include all known Qt6 installation directories:
+
+**Standard path extension** (most distributions):
+
+```sh
+export PATH="$PATH:/usr/lib/qt6/bin:/usr/lib64/qt6/bin:/opt/qt6/bin:/root/.nix-profile/bin"
+```
+
+**Extended path** (Amazon Linux 2023, Gentoo, NixOS, Oracle Linux, Void Linux):
+
+```sh
+export PATH="$PATH:/usr/lib/qt6/bin:/usr/lib64/qt6/bin:/usr/libexec/qt6:/opt/qt6/bin:/root/.nix-profile/bin"
+```
+
+The extended variant adds `/usr/libexec/qt6` for distributions where Qt6
+installs its binaries under `libexec`.
+
+### Step 2: Binary Search
+
+The gate checks for the presence of Qt6 binaries using a multi-pronged approach:
+
+**Command-based checks** (via `command -v` — checks `$PATH`):
+
+```sh
+command -v qmake6 >/dev/null 2>&1
+command -v qmake-qt6 >/dev/null 2>&1
+command -v qtpaths6 >/dev/null 2>&1
+```
+
+**Absolute path checks** (via `[ -x ... ]` — checks specific filesystem locations):
+
+Standard set:
+```sh
+[ -x /usr/lib/qt6/bin/qmake ]
+[ -x /usr/lib64/qt6/bin/qmake ]
+[ -x /usr/lib/qt6/bin/qtpaths ]
+[ -x /usr/lib64/qt6/bin/qtpaths ]
+```
+
+Extended set (Oracle Linux, Gentoo, NixOS, Amazon Linux 2023, Void Linux):
+```sh
+[ -x /usr/libexec/qt6/qmake ]
+[ -x /usr/libexec/qt6/qtpaths ]
+```
+
+### Step 3: Pass or Fail
+
+All checks are combined with `||` (logical OR). If **any single check**
+succeeds, the gate passes:
+
+```sh
+if command -v qmake6 >/dev/null 2>&1 \
+ || command -v qmake-qt6 >/dev/null 2>&1 \
+ || command -v qtpaths6 >/dev/null 2>&1 \
+ || [ -x /usr/lib/qt6/bin/qmake ] \
+ || [ -x /usr/lib64/qt6/bin/qmake ] \
+ || [ -x /usr/lib/qt6/bin/qtpaths ] \
+ || [ -x /usr/lib64/qt6/bin/qtpaths ]; then
+ true;
+ else
+ echo "Qt6 toolchain not found" >&2;
+ exit 1;
+ fi
+```
+
+If **all checks fail**, the gate prints "Qt6 toolchain not found" to stderr
+and exits with code 1, which causes the Docker `RUN` instruction to fail
+and aborts the build.
+
+---
+
+## Actual Dockerfile Snippet
+
+Here is the exact verification code as it appears in the Dockerfiles (shown
+in formatted form — the actual files have it on a single `RUN` line):
+
+```sh
+set -eux
+
+# ... package installation ...
+
+# PATH extension
+export PATH="$PATH:/usr/lib/qt6/bin:/usr/lib64/qt6/bin:/opt/qt6/bin:/root/.nix-profile/bin"
+
+# Qt6 verification gate
+if command -v qmake6 >/dev/null 2>&1 \
+ || command -v qmake-qt6 >/dev/null 2>&1 \
+ || command -v qtpaths6 >/dev/null 2>&1 \
+ || [ -x /usr/lib/qt6/bin/qmake ] \
+ || [ -x /usr/lib64/qt6/bin/qmake ] \
+ || [ -x /usr/lib/qt6/bin/qtpaths ] \
+ || [ -x /usr/lib64/qt6/bin/qtpaths ]; then
+ true
+else
+ echo "Qt6 toolchain not found" >&2
+ exit 1
+fi
+```
+
+---
+
+## Why These Specific Binaries?
+
+### qmake6
+
+`qmake6` is the Qt 6 version of the qmake build system. On most distributions,
+the `qt6-base-dev` or `qt6-qtbase-devel` package installs it as `qmake6`.
+
+### qmake-qt6
+
+Some distributions (especially Debian-based ones) install the Qt6 qmake as
+`qmake-qt6` instead of `qmake6`. The `-qt6` suffix is a Debian packaging
+convention to allow multiple Qt versions to coexist.
+
+### qtpaths6
+
+`qtpaths6` is a Qt6 utility that reports installation paths (plugin directory,
+library directory, etc.). It is a lightweight Qt6 binary that confirms the
+Qt6 runtime is properly installed, without needing a full build tool like qmake.
+
+### Why check absolute paths too?
+
+On some distributions, Qt6 binaries are installed to non-standard locations
+that may not be in `$PATH`:
+
+| Path | Used by |
+|-------------------------------|--------------------------------------------------|
+| `/usr/lib/qt6/bin/qmake` | Debian, Ubuntu (32-bit or arch-independent) |
+| `/usr/lib64/qt6/bin/qmake` | Fedora, RHEL family (64-bit lib directory) |
+| `/usr/libexec/qt6/qmake` | Oracle Linux, Gentoo, Amazon Linux 2023, Void |
+| `/usr/lib/qt6/bin/qtpaths` | Debian, Ubuntu |
+| `/usr/lib64/qt6/bin/qtpaths` | Fedora, RHEL family |
+| `/usr/libexec/qt6/qtpaths` | Oracle Linux, Gentoo, Amazon Linux 2023, Void |
+| `/opt/qt6/bin/` | Custom Qt6 installations (from source or installer)|
+| `/root/.nix-profile/bin/` | NixOS (Nix profile symlinks) |
+
+---
+
+## Which Dockerfiles Use Which Path Variant?
+
+### Standard Qt6 paths (7 check locations, 4 PATH dirs)
+
+Used by 30 Dockerfiles:
+
+- All **AlmaLinux** images (alma-9, alma-10)
+- All **Alpine** images (alpine-319 through alpine-latest)
+- **Arch** (arch-latest)
+- All **CentOS Stream** images (centos-stream9, centos-stream10)
+- All **Debian** images (bookworm, bookworm-slim, bullseye, bullseye-slim, stable-slim, trixie-slim)
+- All **Devuan** images (devuan-chimaera, devuan-daedalus)
+- All **Fedora** images (fedora-40, fedora-41, fedora-42, fedora-latest)
+- **Kali** (kali-rolling)
+- All **openSUSE** images (opensuse-leap-155, opensuse-leap-156, opensuse-tumbleweed)
+- All **Rocky** images (rocky-9, rocky-10)
+- All **Ubuntu** images (ubuntu-2004, ubuntu-2204, ubuntu-2404, ubuntu-latest)
+- **Amazon Linux 2** (amazonlinux-2)
+
+```sh
+export PATH="$PATH:/usr/lib/qt6/bin:/usr/lib64/qt6/bin:/opt/qt6/bin:/root/.nix-profile/bin"
+
+# Checks: qmake6, qmake-qt6, qtpaths6 (via command -v)
+# plus: /usr/lib/qt6/bin/qmake, /usr/lib64/qt6/bin/qmake,
+# /usr/lib/qt6/bin/qtpaths, /usr/lib64/qt6/bin/qtpaths
+```
+
+### Extended Qt6 paths (9 check locations, 5 PATH dirs)
+
+Used by 6 Dockerfiles:
+
+- **Amazon Linux 2023** (amazonlinux-2023)
+- **Gentoo** (gentoo-stage3)
+- **NixOS** (nix-latest)
+- **Oracle Linux** 8, 9, 10 (oraclelinux-8, oraclelinux-9, oraclelinux-10)
+- **Void Linux** (void-latest)
+
+```sh
+export PATH="$PATH:/usr/lib/qt6/bin:/usr/lib64/qt6/bin:/usr/libexec/qt6:/opt/qt6/bin:/root/.nix-profile/bin"
+
+# Checks: qmake6, qmake-qt6, qtpaths6 (via command -v)
+# plus: /usr/lib/qt6/bin/qmake, /usr/lib64/qt6/bin/qmake,
+# /usr/lib/qt6/bin/qtpaths, /usr/lib64/qt6/bin/qtpaths,
+# /usr/libexec/qt6/qmake, /usr/libexec/qt6/qtpaths
+```
+
+---
+
+## Images Excluded from Active CI Matrix
+
+The README notes that approximately **35 of 40** images are in the active CI
+build matrix. The ~5 excluded images are those where Qt6 packages are not
+reliably available:
+
+| Image | Reason for exclusion |
+|----------------------------------|-----------------------------------------------------|
+| `amazonlinux-2` | Based on RHEL 7 era; no Qt6 in default repos |
+| `debian-bullseye` / `bullseye-slim` | Debian 11 shipped Qt 5.15, not Qt6 |
+| `devuan-chimaera` | Based on Debian Bullseye, same Qt6 limitation |
+| `ubuntu-2004` | Ubuntu 20.04 does not ship Qt6 |
+
+These images are still maintained in the repository for potential future use
+(e.g., if Qt6 becomes available via backports or PPAs), but they are not built
+in the regular CI workflow.
+
+---
+
+## Failure Behaviour
+
+When the Qt6 gate fails:
+
+1. The `echo "Qt6 toolchain not found" >&2` message is printed to stderr.
+2. `exit 1` terminates the shell with a non-zero exit code.
+3. The `RUN` instruction fails.
+4. Docker aborts the build.
+5. The CI workflow reports a build failure for that image target.
+6. The failed image is **not** pushed to the container registry.
+
+Because `set -eux` is active at the top of the `RUN` block:
+- `-e`: Exit immediately if any command fails.
+- `-u`: Treat unset variables as errors.
+- `-x`: Print each command before executing (useful for debugging in CI logs).
+
+---
+
+## Why No Qt5 Fallback?
+
+The project has made a deliberate decision to require Qt6:
+
+1. **Qt5 is end-of-life** — Qt 5.15 LTS support ended. New features and
+ security fixes only go into Qt6.
+2. **API consistency** — supporting both Qt5 and Qt6 would require conditional
+ compilation paths, increasing maintenance burden.
+3. **Clear signal** — if a distribution cannot provide Qt6, it is too old to
+ be a supported build target.
+
+---
+
+## Verifying Qt6 Locally
+
+To test whether Qt6 would be found in a specific image, you can run:
+
+```bash
+docker run --rm <image> sh -c '
+ export PATH="$PATH:/usr/lib/qt6/bin:/usr/lib64/qt6/bin:/opt/qt6/bin"
+ echo "qmake6: $(command -v qmake6 2>/dev/null || echo NOT FOUND)"
+ echo "qmake-qt6: $(command -v qmake-qt6 2>/dev/null || echo NOT FOUND)"
+ echo "qtpaths6: $(command -v qtpaths6 2>/dev/null || echo NOT FOUND)"
+ for p in /usr/lib/qt6/bin/qmake /usr/lib64/qt6/bin/qmake \
+ /usr/lib/qt6/bin/qtpaths /usr/lib64/qt6/bin/qtpaths \
+ /usr/libexec/qt6/qmake /usr/libexec/qt6/qtpaths; do
+ [ -x "$p" ] && echo "Found: $p" || echo "Missing: $p"
+ done
+'
+```
+
+---
+
+## Related Documentation
+
+- [Overview](overview.md) — project summary
+- [Architecture](architecture.md) — Dockerfile template structure
+- [Base Images](base-images.md) — per-image deep dive
+- [CI/CD Integration](ci-cd-integration.md) — how the workflow builds and verifies
+- [Troubleshooting](troubleshooting.md) — debugging Qt6 failures