From e1b504dc54e5c14adeb0e12b2405c07bf9bdb920 Mon Sep 17 00:00:00 2001 From: Viktor Petersson Date: Thu, 11 Jun 2026 15:43:38 +0000 Subject: [PATCH 1/2] fix(build): replace retired Linaro armhf toolchain with Debian's MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit releases.linaro.org has been retired, so the pi2/pi3 webview-builder's download of gcc-linaro-7.4.1 fails to connect (curl exit 7). Every master Docker build has gone red since, and because publish-latest only advances the floating latest- tags on a fully green matrix, the latest-* images froze — users tracking latest stopped getting any merged fixes. - Install Debian's supported crossbuild-essential-armhf (gcc 14, same arm-linux-gnueabihf- prefix) instead of fetching the dead tarball - Symlink it under the legacy gcc-linaro path the frozen Qt 5 qmake.conf bakes into CROSS_COMPILE, so the pinned WebView-v2026.04.1 artifact needs no rebuild; the app still links against the Raspbian /sysroot, so the target glibc is unchanged - Apply the same swap to the offline toolchain-rebuild path (build_qt5.sh + its Dockerfile) so the dead URL is gone everywhere Validated by building the pi2 viewer image: qmake/make link the AnthiasViewer binary against the pinned Qt 5 libs with the Debian cross-gcc, producing a valid ARM EABI5 hardfloat executable. Co-Authored-By: Claude Opus 4.8 (1M context) --- docker/Dockerfile.qt5-webview-builder.j2 | 48 ++++++++++++++---------- src/anthias_webview/Dockerfile | 1 + src/anthias_webview/build_qt5.sh | 22 ++++++----- 3 files changed, 42 insertions(+), 29 deletions(-) diff --git a/docker/Dockerfile.qt5-webview-builder.j2 b/docker/Dockerfile.qt5-webview-builder.j2 index 2d4f45156..1bbe7baec 100644 --- a/docker/Dockerfile.qt5-webview-builder.j2 +++ b/docker/Dockerfile.qt5-webview-builder.j2 @@ -151,10 +151,13 @@ USER root # stage must run on x86_64. CI is amd64; arm64 build hosts (e.g. Apple # Silicon) will execute this stage under QEMU. # -# Host build tools only. The webview app builds against the pre-built -# Qt 5 toolchain, so we don't need the Qt 5 / QtWebEngine source-build -# stack (chromium's bison/flex/gperf/ninja/gyp/python2.7). python3 is -# required for sysroot-relativelinks.py. +# Host build tools plus the armhf cross-toolchain. The webview app +# builds against the pre-built Qt 5 toolchain, so we don't need the +# Qt 5 / QtWebEngine source-build stack (chromium's +# bison/flex/gperf/ninja/gyp/python2.7). python3 is required for +# sysroot-relativelinks.py; crossbuild-essential-armhf provides the +# arm-linux-gnueabihf- cross-compiler the Qt 5 qmake.conf invokes (see +# the symlink step below). {% if disable_cache_mounts %} RUN \ {% else %} @@ -164,9 +167,9 @@ RUN --mount=type=cache,target=/var/cache/apt,id=qt5-host-apt,sharing=locked \ apt-get install -y --no-install-recommends \ build-essential \ ca-certificates \ + crossbuild-essential-armhf \ curl \ - python3 \ - xz-utils + python3 WORKDIR /build @@ -189,19 +192,26 @@ COPY --from=qt5-sysroot /usr/share/pkgconfig/ /sysroot/usr/share/pkgconfig/ RUN python3 /usr/local/bin/sysroot-relativelinks.py /sysroot -# Linaro gcc-7.4.1 — hardcoded path matches the CROSS_COMPILE setting -# baked into the Qt 5 toolchain's qmake.conf at original toolchain -# build time (src/anthias_webview/build_qt5.sh -# `-device-option CROSS_COMPILE=`). -# SHA256-pinned: Linaro doesn't publish signed manifests for these -# legacy 7.4 binaries, so the hash is the trust anchor. -RUN mkdir -p /src && \ - cd /src && \ - curl --proto '=https' --tlsv1.2 -fsSL -o gcc-linaro.tar.xz \ - https://releases.linaro.org/components/toolchain/binaries/7.4-2019.02/arm-linux-gnueabihf/gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf.tar.xz && \ - echo '3c951cf1941d0fa06d64cc0d5e88612b209d8123b273fa26c16d70bd7bc6b163 gcc-linaro.tar.xz' | sha256sum -c - && \ - tar xf gcc-linaro.tar.xz && \ - rm gcc-linaro.tar.xz +# armhf cross-compiler. The pre-built Qt 5 toolchain's qmake.conf bakes +# CROSS_COMPILE=/src/gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf- +# (set in src/anthias_webview/build_qt5.sh at toolchain-build time), so +# qmake invokes the cross-gcc from that exact path and prefix. +# +# We used to fetch Linaro's legacy gcc-7.4.1 tarball here, but Linaro +# retired releases.linaro.org — the download now fails to connect and +# broke every pi2/pi3 CI build (which froze the floating latest-* tags, +# since publish-latest only advances on a fully green matrix). Use +# Debian's own supported armhf cross-toolchain (crossbuild-essential-armhf, +# installed above) and expose it under the legacy path the pinned +# qmake.conf expects. The prefix is identical (arm-linux-gnueabihf-), so +# the frozen Qt 5 artifact needs no rebuild, and the app still links +# against the Raspbian /sysroot (-sysroot) so the target glibc is +# unchanged. +RUN mkdir -p /src/gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf/bin && \ + for tool in /usr/bin/arm-linux-gnueabihf-*; do \ + ln -s "$tool" \ + "/src/gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf/bin/$(basename "$tool")"; \ + done # Pre-built Qt 5 toolchain — pinned permanently to WebView-v2026.04.1 # (Qt 5 is frozen for pi2/pi3). The qt5pi/ tree contains both host diff --git a/src/anthias_webview/Dockerfile b/src/anthias_webview/Dockerfile index 0bb25c57e..f7ad9f59b 100644 --- a/src/anthias_webview/Dockerfile +++ b/src/anthias_webview/Dockerfile @@ -162,6 +162,7 @@ RUN apt-get update && \ build-essential \ ccache \ cowsay \ + crossbuild-essential-armhf \ curl \ flex \ freetds-dev \ diff --git a/src/anthias_webview/build_qt5.sh b/src/anthias_webview/build_qt5.sh index e917213d5..c6b275506 100755 --- a/src/anthias_webview/build_qt5.sh +++ b/src/anthias_webview/build_qt5.sh @@ -33,16 +33,18 @@ if [ "${BUILD_WEBENGINE-x}" == "1" ]; then fi function fetch_cross_compile_tool () { - # The Raspberry Pi Foundation's cross compiling tools are too old so we need newer ones. - # References: - # * https://github.com/UvinduW/Cross-Compiling-Qt-for-Raspberry-Pi-4 - # * https://releases.linaro.org/components/toolchain/binaries/latest-7/armv8l-linux-gnueabihf/ - if [ ! -d "/src/gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf" ]; then - pushd /src/ - wget -q https://releases.linaro.org/components/toolchain/binaries/7.4-2019.02/arm-linux-gnueabihf/gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf.tar.xz - tar xf gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf.tar.xz - rm gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf.tar.xz - popd + # The Raspberry Pi Foundation's cross compiling tools are too old, so + # we use Debian's supported armhf cross-toolchain. (We previously + # fetched Linaro's gcc-7.4.1, but Linaro retired releases.linaro.org.) + # Expose it under the legacy gcc-linaro path so the CROSS_COMPILE + # baked into qmake.conf below keeps resolving. crossbuild-essential-armhf + # must be installed in the builder image (see ./Dockerfile). + local linaro_path="/src/gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf" + if [ ! -d "$linaro_path" ]; then + mkdir -p "$linaro_path/bin" + for tool in /usr/bin/arm-linux-gnueabihf-*; do + ln -s "$tool" "$linaro_path/bin/$(basename "$tool")" + done fi } From e5d7816063a7e0871ed16f67b41b354401674d71 Mon Sep 17 00:00:00 2001 From: Viktor Petersson Date: Thu, 11 Jun 2026 15:48:58 +0000 Subject: [PATCH 2/2] fix(build): harden toolchain shim and correct amd64-pin comment Addresses Copilot review on #3070: - build_qt5.sh: fail fast with a clear message if the armhf cross toolchain is absent (else the glob expands to a literal and errors confusingly), and use `ln -sf` so reruns are idempotent. - Dockerfile.qt5-webview-builder.j2: the amd64-pin comment referenced the removed Linaro download; the real reason is the pinned Qt 5 bundle's x86_64 host qmake (and the x86_64-hosted Debian cross-gcc). Co-Authored-By: Claude Opus 4.8 (1M context) --- docker/Dockerfile.qt5-webview-builder.j2 | 9 +++++---- src/anthias_webview/build_qt5.sh | 19 +++++++++++-------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/docker/Dockerfile.qt5-webview-builder.j2 b/docker/Dockerfile.qt5-webview-builder.j2 index 1bbe7baec..910bf29fc 100644 --- a/docker/Dockerfile.qt5-webview-builder.j2 +++ b/docker/Dockerfile.qt5-webview-builder.j2 @@ -146,10 +146,11 @@ FROM --platform=linux/amd64 {{ base_image }}:{{ base_image_tag }} AS webview-bui USER root -# Pinned to linux/amd64 (not $BUILDPLATFORM): the Linaro 7.4.1 -# cross-compiler downloaded below is the x86_64 host tarball, so this -# stage must run on x86_64. CI is amd64; arm64 build hosts (e.g. Apple -# Silicon) will execute this stage under QEMU. +# Pinned to linux/amd64 (not $BUILDPLATFORM): the pre-built Qt 5 +# toolchain bundle ships an x86_64 host qmake under qt5pi/bin, and the +# Debian armhf cross-compiler installed below is the x86_64-hosted +# toolchain — so this stage must run on x86_64. CI is amd64; arm64 +# build hosts (e.g. Apple Silicon) will execute this stage under QEMU. # # Host build tools plus the armhf cross-toolchain. The webview app # builds against the pre-built Qt 5 toolchain, so we don't need the diff --git a/src/anthias_webview/build_qt5.sh b/src/anthias_webview/build_qt5.sh index c6b275506..ccf5c2727 100755 --- a/src/anthias_webview/build_qt5.sh +++ b/src/anthias_webview/build_qt5.sh @@ -37,15 +37,18 @@ function fetch_cross_compile_tool () { # we use Debian's supported armhf cross-toolchain. (We previously # fetched Linaro's gcc-7.4.1, but Linaro retired releases.linaro.org.) # Expose it under the legacy gcc-linaro path so the CROSS_COMPILE - # baked into qmake.conf below keeps resolving. crossbuild-essential-armhf - # must be installed in the builder image (see ./Dockerfile). - local linaro_path="/src/gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf" - if [ ! -d "$linaro_path" ]; then - mkdir -p "$linaro_path/bin" - for tool in /usr/bin/arm-linux-gnueabihf-*; do - ln -s "$tool" "$linaro_path/bin/$(basename "$tool")" - done + # baked into qmake.conf below keeps resolving. + if ! command -v arm-linux-gnueabihf-g++ >/dev/null 2>&1; then + echo "error: arm-linux-gnueabihf cross toolchain not found — " \ + "install crossbuild-essential-armhf (see ./Dockerfile)." >&2 + exit 1 fi + # ln -sf (no -d skip) so reruns refresh the shim idempotently. + local linaro_path="/src/gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf" + mkdir -p "$linaro_path/bin" + for tool in /usr/bin/arm-linux-gnueabihf-*; do + ln -sf "$tool" "$linaro_path/bin/$(basename "$tool")" + done } function fetch_rpi_firmware () {