Commit 1931227
ci(appimage): build aarch64 against Qt 6.8.3 LTS and enable QRhi spectrum rendering (#4670)
The aarch64 AppImage was the only artifact still building against the
distro's Qt. It shipped **Qt 6.4.2** while x86_64, macOS Intel and
Windows all pin 6.8.3 — so README's "Release binaries ship Qt 6.8.3 LTS"
was simply untrue for the Pi build, and the platform least likely to
have a modern Qt available got the oldest one.
## Why it was like that, and why that reason is gone
Commit `49ea8a50` (2026-03) split ARM onto system Qt with an explicit
reason:
> Qt doesn't provide prebuilt ARM64 Linux binaries via aqtinstall.
That expired and nobody re-checked. Verified against aqt directly:
```
$ aqt list-qt linux_arm64 desktop
6.8.0 6.8.1 6.8.2 6.8.3
6.9.0 ... 6.12.0
$ aqt list-qt linux_arm64 desktop --arch 6.8.3
linux_gcc_arm64
```
All four modules this build needs (`qtmultimedia`, `qtwebsockets`,
`qtserialport`, `qtshadertools`) are published for `6.8.3
linux_gcc_arm64`, so the x86_64 recipe transplants directly.
**6.8.3, not a newer 6.8.** Qt's 6.8 LTS goes commercial-only after
6.8.3: 6.8.4 is source-only and 6.8.5+ are absent from the open-source
repo entirely. 6.8.3 is the newest 6.8 LTS obtainable under our licence,
and it is what every other artifact already pins.
## The runner stays on noble, and must
An earlier revision of this branch moved aarch64 to `ubuntu-22.04-arm`
to lower the AppImage's glibc floor, on the assumption that jammy would
do for ARM what it does for x86_64. It will not, and that change has
been reverted.
Qt does not build the two Linux hosts on the same base:
```
linux_x64 → qtbase-Linux-RHEL_8_10-GCC-Linux-RHEL_8_10-X86_64.7z
linux_arm64 → qtbase-Linux-Ubuntu_24_04-GCC-Linux-Ubuntu_24_04-AARCH64.7z
```
The "old glibc, new Qt" property x86_64 enjoys comes from Qt shipping
its x64 build from RHEL 8.10, not from the runner: `readelf -V` on the
shipped libraries gives **max `GLIBC_2.27` for x86_64 and `GLIBC_2.38`
for arm64**. Jammy is 2.35, so the arm64 Qt cannot run there at all —
the job would die at the aqt step's `qmake -query`, on release day. The
asymmetry is Qt's, not ours.
The floor therefore has two contributors: Qt sets a hard lower bound of
2.38 that no runner can undercut, and the app's own objects add the
builder's glibc on top, so the artifact assembled on noble floors at
**2.39** — unchanged from what ships today. Practical consequence for
the target platform: Raspberry Pi OS **Trixie** (glibc 2.41) is the
supported Pi baseline; **Bookworm** (2.36) cannot run it. That was
already true of the current aarch64 AppImage, so it is not a regression
— but "Qt 6.8.3 on the Pi" and "runs on Bookworm" cannot both be had
from Qt's prebuilt arm64 binaries, and that trade would need its own
decision.
## Four latent traps this had to clear
1. **Four** separate steps hardcoded `.../Qt/6.8.3/gcc_64` — configure,
`QMAKE` for `linuxdeploy-plugin-qt`, the multimedia-plugin copy, and the
env export. Flipping aarch64 to aqt while missing any one would have
pointed the ARM build at an x86_64 Qt. Now derived once into `QT_ROOT`,
with an assertion that `qmake` exists there — a wrong path would
otherwise pass configure via system Qt and only surface as a
mis-deployed AppImage.
2. The glslc steps gated on `runner == 'ubuntu-22.04'` vs `!=`, which
assumed "not jammy" meant "noble" — an equivalence that holds only by
accident of the current matrix. Both legs need glslc and only the
*source* differs, so that is now an explicit `glslc_source` matrix key
(`lunarg` / `apt`) driving the LunarG repo step and both install steps.
3. The multimedia plugin copy ended in `|| true`, so a wrong path
shipped an AppImage with no multimedia backend and a green build.
Dropped.
4. `AETHER_GPU_SPECTRUM` defaults ON and auto-disables only below Qt
6.7, so the bump would have flipped QRhi rendering on as a silent side
effect. Now set explicitly per-arch — see below.
## What must NOT be gated on `require_gpu`
Worth recording, because this branch got it wrong once and it is a
genuinely easy mistake: `REQUIRE_ASR_GPU` is the **release guard** — it
makes a missing GPU toolchain *fatal* at configure time. It is not the
enable switch. `ENABLE_ASR_VULKAN` defaults ON on everything non-Apple,
so the aarch64 leg has been resolving `find_package(Vulkan COMPONENTS
glslc)` against noble's own arm64 `glslc` package and compiling
ggml-vulkan into the shipped AppImage all along. The v26.7.4.1 release
run says so verbatim:
```
Get:2 http://ports.ubuntu.com/ubuntu-ports noble/universe arm64 glslc arm64 2023.8-1build1
-- ASR: Vulkan GPU backend enabled (glslc: /bin/glslc)
-- Enabling coopmat glslc support
```
Gating the glslc install on `require_gpu` would have taken that backend
away with no error at all — `Vulkan_glslc_FOUND` false,
`GGML_VULKAN=OFF`, `REQUIRE_ASR_GPU=OFF` so nothing fails. Green build,
backend gone. `glslc_source` avoids that: the ARM AppImage keeps exactly
the ASR backends it ships today, and this PR changes only Qt and the
spectrum renderer.
## GPU spectrum rendering on aarch64
Enabled deliberately. The CPU QPainter fallback on ARM was never a
decision about ARM; it was Qt 6.4.2 sitting below the 6.7 QRhiWidget
floor with CMake auto-disabling accordingly — the last release log shows
exactly that: `GPU spectrum rendering disabled (requires Qt 6.7+, found
6.4.2)`. 6.8.3 clears it, so the Pi gets the same renderer as everything
else.
**Asserted, not assumed.** `=ON` is only a request — CMakeLists silently
flips it back OFF when `Qt6GuiPrivate` isn't located, and it names
aqtinstall specifically as a layout that ships private QtGui headers
while omitting the `Qt6GuiPrivate` CMake package. That is exactly what
both legs now use, so a release could ship the CPU fallback with a green
workflow. A new step greps the configure output and fails the job
otherwise.
Confirmed this resolves on both legs rather than assumed: neither the
`linux_gcc_64` nor the `linux_gcc_arm64` tree ships a `Qt6GuiPrivate`
CMake package, and both ship
`include/QtGui/6.8.3/QtGui/private/qhighdpiscaling_p.h`, which is what
the `DEBIAN_PRIVATE_INC` fallback walks `Qt6::Gui`'s include dirs
looking for. The x86_64 leg of the last release already prints the pair
the assertion depends on:
```
-- Qt6GuiPrivate CMake package not found, searching for private headers directly...
-- GPU spectrum rendering enabled (QRhi, Qt 6.8.3)
```
Configure also now tees under `set -o pipefail` so a cmake failure still
fails the step.
## Verification and what is NOT verified
Verified: aqt package/module/arch availability for `linux_arm64`; the
installed arm64 tree's layout (`Qt/6.8.3/gcc_arm64/bin/qmake`, so the
`${QT_DIR#linux_}` derivation is right), its `plugins/multimedia/*` and
bundled `libav*`, and `bin/qsb`; `readelf -V` glibc requirements on both
hosts' `libQt6Gui.so.6`; the absence of `Qt6GuiPrivate` and presence of
the private headers on both; `ubuntu-24.04-arm` is a GA runner label;
both v26.7.4.1 AppImage job logs for the ASR-Vulkan and GPU-spectrum
evidence above; `actionlint` clean apart from the two pre-existing
`SC2046` warnings on `-j$(nproc)` that also fire on `main`.
Also verified, since it looks like a trap and isn't one: `pip3 install
aqtinstall` needs no `--break-system-packages` on `ubuntu-24.04-arm`.
GitHub's image build writes `/etc/pip.conf` with `break-system-packages
= true` on every non-jammy Ubuntu image, arm64 included
(`images/ubuntu/scripts/build/install-python.sh`, guarded by `if !
is_ubuntu22`).
**Not verified:** this workflow only fires on tag pushes, so CI here
will not exercise it — the first real run is a release. The Pi on hand
is offline, so the resulting aarch64 AppImage is untested on hardware
and whether Mesa V3D drives QRhi acceptably on a Pi 5 is unknown. The
assertion guarantees the renderer is compiled in, not that it performs
well; `AETHER_NO_GPU=1` (now documented in the README) is the no-rebuild
fallback if it does not. A `workflow_dispatch` run on this branch before
tagging would derisk the build itself.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>1 parent 65222e8 commit 1931227
3 files changed
Lines changed: 157 additions & 42 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
19 | | - | |
| 19 | + | |
| 20 | + | |
20 | 21 | | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
21 | 31 | | |
22 | 32 | | |
23 | | - | |
24 | | - | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
25 | 51 | | |
26 | 52 | | |
27 | 53 | | |
| |||
42 | 68 | | |
43 | 69 | | |
44 | 70 | | |
45 | | - | |
46 | | - | |
| 71 | + | |
| 72 | + | |
47 | 73 | | |
48 | 74 | | |
49 | 75 | | |
| |||
76 | 102 | | |
77 | 103 | | |
78 | 104 | | |
79 | | - | |
80 | | - | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
81 | 116 | | |
82 | 117 | | |
83 | 118 | | |
84 | 119 | | |
85 | | - | |
86 | | - | |
| 120 | + | |
| 121 | + | |
87 | 122 | | |
88 | 123 | | |
89 | 124 | | |
| |||
96 | 131 | | |
97 | 132 | | |
98 | 133 | | |
99 | | - | |
100 | | - | |
101 | | - | |
102 | | - | |
103 | | - | |
104 | | - | |
105 | | - | |
106 | | - | |
107 | | - | |
108 | | - | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
109 | 158 | | |
110 | 159 | | |
111 | | - | |
| 160 | + | |
112 | 161 | | |
113 | 162 | | |
114 | | - | |
115 | | - | |
116 | | - | |
117 | | - | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
118 | 187 | | |
119 | 188 | | |
120 | 189 | | |
| |||
145 | 214 | | |
146 | 215 | | |
147 | 216 | | |
148 | | - | |
149 | | - | |
150 | | - | |
151 | | - | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
152 | 222 | | |
153 | 223 | | |
154 | 224 | | |
| |||
157 | 227 | | |
158 | 228 | | |
159 | 229 | | |
| 230 | + | |
160 | 231 | | |
161 | 232 | | |
162 | | - | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
163 | 252 | | |
164 | 253 | | |
165 | 254 | | |
| |||
184 | 273 | | |
185 | 274 | | |
186 | 275 | | |
187 | | - | |
188 | | - | |
189 | | - | |
190 | | - | |
191 | | - | |
192 | | - | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
193 | 279 | | |
194 | | - | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
195 | 285 | | |
196 | 286 | | |
197 | 287 | | |
| |||
219 | 309 | | |
220 | 310 | | |
221 | 311 | | |
222 | | - | |
223 | | - | |
224 | | - | |
225 | | - | |
226 | | - | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
227 | 317 | | |
228 | 318 | | |
229 | 319 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
52 | 52 | | |
53 | 53 | | |
54 | 54 | | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
55 | 72 | | |
56 | 73 | | |
57 | 74 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
216 | 216 | | |
217 | 217 | | |
218 | 218 | | |
219 | | - | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
220 | 228 | | |
221 | 229 | | |
222 | 230 | | |
| |||
0 commit comments