2.0.11-rc3 fixes - #1688
Merged
Merged
Conversation
Pin curl, libarchive, libusb, nghttp2, xz, zlib and zstd as git submodules under src/dependencies/vendor and build them from source via CMake (fetch-vendor.cmake + per-dependency *.cmake). This links the imager against known-good upstream versions independent of the host distribution.
Add a patch fixing Qt6 QTestSupport chrono atomics on 32-bit targets (armhf) and adjust the shared Qt build helper and armhf build notes.
Add a release pipeline that builds the desktop, CLI and embedded AppImages and wraps them into .debs for amd64, arm64 and armhf. The host architecture builds locally; foreign arches build in rootless mmdebstrap chroots, with prebuilt AppImages and Qt injected via bind mounts. Includes release.sh orchestration, chroot/mirror/keyring helpers, per-arch apt sources, Qt caching and the updated packaging metadata (rules, control, changelog, install files).
Retarget the rootless mmdebstrap chroots from trixie to bookworm and parameterise the apt source templates on CHROOT_DIST, adding the bookworm sources those templated paths resolve to. Packaging fixes on top of that pipeline: * build-source.sh collected three of the four files listed in _source.changes; the generated _source.buildinfo was destroyed with the temporary build directory, so the source upload referenced a file that was never written out. * The chroot build path never invoked linuxdeploy, so the AppImages bundled Qt and nothing else, silently resolving around twenty libraries from the host (PCRE2, zstd, brotli, GnuTLS, glib, double-conversion, liburing). Cross-architecture builds never invoked it either, since linuxdeploy cannot introspect foreign binaries, so arm64 and armhf had never been bundled correctly. Replace it with appimage_deploy_lib_closure(), which walks DT_NEEDED using readelf and so works unchanged on a foreign-architecture AppDir, and which fails the build rather than silently under-bundling. * The embedded package copies Qt from a hand-maintained list but copies the QML tree wholesale, so sixteen libraries its plugins reference were never shipped: libQt6Quick could not resolve libQt6QmlModels or libQt6OpenGL, and the QtQuick.Controls plugin could not resolve libQt6QuickControls2. Complete the closure there too, additively, so the curated list stays authoritative for payload size. * Build Qt with -no-feature-icu. No ICU-backed Qt feature is used (UTF-8 conversion only, no QCollator, timezones handled as IANA identifier strings) and it was enabled purely by configure autodetection. Saves about 12.6 MB per binary package and removes the per-release libicu soname pin that tied the packages to a single Debian release. * Prune the QML tree to the eight modules the UI imports, with one policy shared between the AppImage and embedded paths. Each unused module's plugin links a Qt library of its own, so pruning modules is what removes the libraries; libQt6QmlWorkerScript is retained because libQt6QmlMeta links it directly. * Drop the JPEG 2000 image format plugin, staged on amd64 only, whose libjasper dependency was never shipped or declared. * Declare the host-coupled libraries all three packages resolve from the system. dh_shlibdeps cannot inspect an AppImage payload, so these were previously undeclared. Verified across amd64, arm64 and armhf plus embedded: ELF machine types match their filename architecture, 60/60 checksums verify, and the dependency sets are exactly right in both directions with nothing under-declared and nothing surplus.
A singular `user:` block is merged over the distro's default_user from /etc/cloud/cloud.cfg, which upstream populates with `sudo: ["ALL=(ALL) NOPASSWD:ALL"]` for every variant including raspberry-pi-os. Omitting the key therefore inherited passwordless sudo via /etc/sudoers.d/90-cloud-init-users regardless of what the user chose. Emit `sudo: null` explicitly, which suppresses the sudoers rules while still inheriting the default user's groups, so the account keeps `sudo` group membership and is simply prompted for a password. `false` behaves the same but has been deprecated since cloud-init 22.2.
…_uring file_operations_linux.cpp uses io_uring_sqe_set_data64 and io_uring_prep_cancel64, added in liburing 2.2. Some distributions ship an older liburing that provides the library but not these helpers (Ubuntu 22.04 carries 2.1), where pkg-config succeeds and the build then fails to link. Compile-probe for the two helpers and gate both -DHAVE_LIBURING and the link against the result, warning and falling back to synchronous writes when the library is present but too old.
A package built against the host's libraries is not the package it claims to be. Building on a newer glibc than bookworm yields binaries that will not start on bookworm at all; building on an older one silently drops features -- a host with liburing < 2.2 fails the io_uring API probe and produces a functionally slower binary -- and in both cases the artifact still gets labelled for bookworm. Nothing in the artifact reveals which happened. BUILDER=auto/local existed as an escape hatch for environments that could not run sbuild. The rootless mmdebstrap chroots removed that constraint: they need no sudo, and CHROOT_AUTO_CREATE=auto creates them on demand, so there is no environment that cannot use one. Nothing in the tree selected it, and no CI referenced it. Remove choose_builder() and the BUILDER variable, the _local_build() branches in build-appimages.sh, and build-binary-local.sh, which becomes unreachable. build-embedded.sh had a separate host-arch shortcut that never consulted BUILDER at all -- invisible today only because the embedded package is arm64-only and is built on amd64 -- so make that unconditional too. Rebuilt all three architectures plus embedded: identical output, 60/60 checksums verify, ELF machine types match their filename architecture.
The embedded package shipped through a standalone path in create-embedded.sh that hand-wrote its own DEBIAN/control, so it diverged from debian/control: the Depends stanza was stale (missing the host-coupled libraries the vendored tree needs), it carried no md5sums, and its version (2.0.10) did not match the other packages. Route the packaging through debhelper instead, so debian/control is the single source of the package's dependencies and metadata: * create-embedded.sh now stages the vendored /opt tree and assembles the .deb with dh_gencontrol / dh_md5sums / dh_builddeb. Version is taken from the changelog (2.0.10-1), md5sums are generated, and Depends come from debian/control. dh_shlibdeps is deliberately not used -- on a vendored /opt tree it demands ~19 libraries from the target that are bundled precisely so a netboot micro image need not carry them -- so debian/control lists the genuinely-external libraries (C/C++ runtime, GPU stack, X11, libsystemd) explicitly. * Bake the deployed rpath in at build time (CMAKE_INSTALL_RPATH=$ORIGIN/../lib, CMAKE_BUILD_WITH_INSTALL_RPATH). The binary was copied to /opt carrying the cmake build rpath, an absolute build-host path: a privacy leak, a reproducibility hazard, and the reason dpkg-shlibdeps could not resolve the bundled libraries. * Dereference the fontconfig conf.d symlinks (cp -rL) so the bundle is self-contained instead of shipping 21 links that dangle on a target without fontconfig installed. * Remove the ICU detection and copy code. Qt is built with -no-feature-icu, so no ICU is linked or bundled; the code only ever emitted a spurious "ICU not found" warning. * CONTRIBUTING.md: document the real build (debian/release.sh embedded arm64), dropping the obsolete build-qt-embedded.sh and dpkg-buildpackage steps. Verified on the rebuilt arm64 package: version 2.0.10-1, md5sums present, Depends complete (external closure fully covered, nothing surplus), binary rpath $ORIGIN/../lib with no build-host path in any shipped ELF, no dangling symlinks, no ICU, 83/83 ELF objects aarch64.
The embedded (linuxfb netboot) target runs on a pi-gen-micro image with no session bus (SYSTEMD=0) and a five-package base. Linking QtDBus there is pure liability: it drags in libQt6DBus -> libdbus-1 -> libsystemd, none of which the image carries, so the binary could not even load. Nothing embedded actually needs DBus at runtime. The three DBus users degrade to nothing useful on that image anyway: the XDG portal file dialog (embedded already forces QML dialogs), the NetworkManager WiFi-credential backend (no NM daemon to read from), and the Pi Connect rpi-imager:// URI handler (no browser to sign in from). Drop Qt6::DBus from find_package/link for BUILD_EMBEDDED. With it unlinked Qt's QT_DBUS_LIB macro goes undefined, which compiles out the guarded DBus paths: platformquirks_linux.cpp already used that guard; extend it to the main.cpp single-instance/URI-handler blocks and to nativefiledialog_linux.cpp (whose portal implementation falls back to the QML dialog stub). Platform.cmake routes embedded to the existing CLI stubs for the WiFi-credential and suspend-inhibitor backends and drops the NetworkManager and URI-handler sources. Desktop and CLI builds are unchanged (desktop keeps DBus; CLI never had it).
Embedded was quietly using the desktop release Qt, which is built with OpenGL, DBus and (by autodetection) ICU. On the pi-gen-micro netboot image that is wrong on every count: there is no Mesa (far too large for a network-loaded image), no session bus, and the embedded build ships none of the complex-script languages that could want ICU. The result linked libEGL/libGL/libX11 and libQt6DBus and would not load on the target at all. Build a dedicated embedded Qt as its own cache variant (gcc_arm64_embedded), configured -no-opengl -qpa linuxfb (software rendering over DRM, no GL/X11), -no-dbus, and -no-feature-icu. Remove the custom from-source ICU build from build-qt-embedded.sh -- it cloned and compiled ICU only to feed a feature we no longer enable, and needs network access the chroot does not have. Wire the variant into the release pipeline: qt_embedded_path()/qt_embedded_ok() in lib.sh, and build-embedded.sh builds it on cache miss and passes it to create-embedded.sh. The cache-miss check is by file presence, not qt_embedded_ok (which runs `qmake -query`): the cached qmake is arm64 and the orchestrator runs on the host, so executing it would always fail and force a needless full Qt rebuild. Embedded is arm64 only -- the only platform the netboot installer targets.
With the app built without QtDBus and Qt built -no-opengl, the vendored tree no longer references libQt6DBus, libEGL/libGL or libX11. Two loose ends remained: create-embedded.sh still copied libQt6DBus and libdbus-1 in explicitly. The libQt6DBus copy carried a "# Required by linuxfb plugin" comment, but that was a misattribution: libqlinuxfb.so never linked it -- the app binary did (via the unconditional Qt6::DBus link, now removed), and the copy had been added in the same debugging pass as the genuine linuxfb input libraries. Drop both copies; they only dragged libdbus-1 -> libsystemd back in, and libsystemd is absent from the netboot image. debian/control still declared libegl1/libgl1/libopengl0/libx11-6/libsystemd0 in the embedded Depends. These are now not merely unnecessary but harmful: apt enforces Depends when building the image, so declaring them would pull Mesa and X11 into it -- exactly the bloat the -no-opengl build exists to avoid. Trim the Depends to the genuinely-external, base-provided set. Verified on the rebuilt package: external sonames down to five (ld-linux, libc, libm, libgcc_s, libstdc++), no libEGL/libGL/libX11/libQt6DBus/libdbus/libsystemd anywhere, no ICU, md5sums present, version 2.0.10-1.
tdewey-rpi
force-pushed
the
dev/tdewey/2.0.11-rc3-fixes
branch
from
August 12, 2026 13:51
97b31e8 to
83aa533
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.