From 36c3699cf65ec17bf5eb50c7637728d4aff6e59a Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Thu, 15 Oct 2026 07:40:16 +0000 Subject: [PATCH 01/13] build-home-assistant-chip-core: add riscv64 port Port home-assistant-chip-core (chip-core/chip-clusters/chip-repl wheels from home-assistant-libs/chip-wheels, built on top of project-chip/connectedhomeip) to riscv64 at version 2025.7.0, the latest chip-wheels release. Mirrors chip-wheels' own build.yaml: a build_prepare job runs the x86_64-only ZAP code pre-generation step (project-chip/zap ships no riscv64 binaries) and tars the patched, bootstrapped Matter SDK tree for build_wheels to pick up inside the manylinux_2_39_riscv64 image. Two one-line pigweed/connectedhomeip patches unblock the Pigweed/CIPD client bootstrap on riscv64: cipd_setup/wrapper.py's arch_normalized() wrongly maps "riscv64" to "amd64" via its generic endswith("64") fallback, and its SUPPORTED_PLATFORMS tuple never listed "linux-riscv64" to begin with, even though the CIPD backend itself already serves a real linux-riscv64 client. gn, ninja and clang are pulled out of the CIPD fetch entirely (gen_pigweed_cipd_json.py's existing exclude-list mechanism, already used for rust/renode) since fuchsia/third_party/ninja has no riscv64 CIPD build at all; gn is built from source and ninja comes from its own riscv64 PyPI wheel, same as this repo's build-skia-python.yml/build-skia-pathops.yml. clang is dropped outright: nothing in BUILD.gn/python_wheel.gni references it, and the host toolchain defaults to GCC. chip_python_platform_tag is set to manylinux_2_39 (this repo's pinned riscv64 image), correcting upstream's own manylinux_2_31 mislabeling (their Linux job actually builds in a plain debian:12 container and never runs auditwheel). auditwheel repair here vendors glib2 (libglib/libgio/libgobject-2.0, pulled in by the Linux BLE stack's GDBus usage) and libnl3 (libnl-3/libnl-route-3, chip_minmdns_default_ policy="libnl"), both LGPL, hence the added gpl_sources job. --- .../build-home-assistant-chip-core.yml | 254 ++++++++++++++++++ docs/packages/home-assistant-chip-core.yaml | 5 + ..._setup-wrapper-support-linux-riscv64.patch | 54 ++++ ...tup-exclude-gn-ninja-clang-from-cipd.patch | 43 +++ 4 files changed, 356 insertions(+) create mode 100644 .github/workflows/build-home-assistant-chip-core.yml create mode 100644 docs/packages/home-assistant-chip-core.yaml create mode 100644 patches/home-assistant-chip-core/2025.7.0/0001-pigweed-cipd_setup-wrapper-support-linux-riscv64.patch create mode 100644 patches/home-assistant-chip-core/2025.7.0/0002-scripts-setup-exclude-gn-ninja-clang-from-cipd.patch diff --git a/.github/workflows/build-home-assistant-chip-core.yml b/.github/workflows/build-home-assistant-chip-core.yml new file mode 100644 index 000000000000..41ee25a7af9a --- /dev/null +++ b/.github/workflows/build-home-assistant-chip-core.yml @@ -0,0 +1,254 @@ +# SPDX-FileCopyrightText: 2026 The RISE Project +# SPDX-License-Identifier: MIT +--- +# This workflow is based on the `build_prepare`/`build_linux_python_lib` jobs of: +# https://github.com/home-assistant-libs/chip-wheels/blob/2025.7.0/.github/workflows/build.yaml +name: Build home-assistant-chip-core wheels (riscv64) + +on: + workflow_dispatch: + inputs: + version: + description: 'Version glob to (re)build; empty builds every version of docs/packages/home-assistant-chip-core.yaml not released yet' + required: false + default: '' + pull_request: + branches: [main] + paths: + - '.github/workflows/build-home-assistant-chip-core.yml' + - 'docs/packages/home-assistant-chip-core.yaml' + - 'patches/home-assistant-chip-core/**' + push: + branches: [main] + paths: + - '.github/workflows/build-home-assistant-chip-core.yml' + - 'docs/packages/home-assistant-chip-core.yaml' + - 'patches/home-assistant-chip-core/**' + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +permissions: + contents: read # to fetch code (actions/checkout) + +env: + GN_REVISION: 0625da07ece7b1a374ec0719b6f40ebe3d0950c1 + MANYLINUX_RISCV64_IMAGE: quay.io/pypa/manylinux_2_39_riscv64 + +jobs: + setup: + uses: $/.github/workflows/_setup.yml + with: + package: home-assistant-chip-core + version: ${{ inputs.version }} + + # ZAP code generation has no riscv64 build (project-chip/zap ships prebuilt + # Electron/node binaries for x86_64/arm64 only), so it runs once here on a + # regular x86_64 runner -- same split chip-wheels' own build.yaml uses + # between build_prepare (ubuntu-24.04) and its per-arch build job -- and the + # pre-generated output is carried into build_wheels via + # chip_code_pre_generated_directory, which never invokes ZAP itself. + build_prepare: + name: Prepare home-assistant-chip-core ${{ matrix.version }} + needs: [setup] + if: needs.setup.outputs.versions != '[]' + strategy: + fail-fast: false + matrix: + version: ${{ fromJSON(needs.setup.outputs.versions) }} + runs-on: ubuntu-24.04 + env: + CHIP_VERSION: ${{ matrix.version }} + + steps: + - name: Checkout home-assistant-libs/chip-wheels ${{ env.CHIP_VERSION }} + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + repository: home-assistant-libs/chip-wheels + ref: ${{ env.CHIP_VERSION }} + submodules: true + fetch-depth: 0 + persist-credentials: false + + - name: Checkout python-wheels + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + path: python-wheels + persist-credentials: false + + - name: Checkout connectedhomeip submodules + working-directory: connectedhomeip + run: scripts/checkout_submodules.py --shallow --platform linux + + - name: Patch CIPD bootstrap for riscv64 + working-directory: connectedhomeip + run: git apply ../python-wheels/patches/home-assistant-chip-core/${{ env.CHIP_VERSION }}/*.patch + + - name: Apply chip-wheels patches + working-directory: connectedhomeip + run: | + for patch in ../*.patch; do + echo "Applying ${patch}" + patch -p1 < "$patch" + done + + - name: Bootstrap + working-directory: connectedhomeip + run: bash scripts/bootstrap.sh -p all,linux + + - name: ZAP code pre-generation + working-directory: connectedhomeip + run: scripts/run_in_build_env.sh "scripts/codepregen.py ./zzz_pregenerated/" + + - name: Create Matter SDK tar + run: tar -caf connectedhomeip-${{ env.CHIP_VERSION }}.tar.zst --exclude ./connectedhomeip/.environment --use-compress-program=zstdmt connectedhomeip + + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: home-assistant-chip-core-${{ env.CHIP_VERSION }}-matter-sdk + path: connectedhomeip-${{ env.CHIP_VERSION }}.tar.zst + if-no-files-found: error + + build_wheels: + needs: [setup, build_prepare] + if: needs.setup.outputs.versions != '[]' + strategy: + fail-fast: false + matrix: + version: ${{ fromJSON(needs.setup.outputs.versions) }} + name: Build home-assistant-chip-core ${{ matrix.version }} cp37-abi3-manylinux_riscv64 + runs-on: ubuntu-24.04-riscv + timeout-minutes: 1440 # full Pigweed/GN/Ninja CHIP SDK compile from source + # container.image can't read the env context, so the image is repeated + # literally here; MANYLINUX_RISCV64_IMAGE below still pins gpl_sources to + # the same one. + container: + image: quay.io/pypa/manylinux_2_39_riscv64 + + defaults: + run: + working-directory: connectedhomeip + + env: + CHIP_VERSION: ${{ matrix.version }} + + steps: + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: home-assistant-chip-core-${{ env.CHIP_VERSION }}-matter-sdk + + - name: Extract Matter SDK from tar + working-directory: ./ + run: | + dnf install -y --enablerepo=crb zstd \ + openssl-devel glib2-devel libnl3-devel cairo-devel \ + gobject-introspection-devel dbus-devel python3-devel + tar -xaf connectedhomeip-${{ env.CHIP_VERSION }}.tar.zst --use-compress-program=zstdmt + git config --global --add safe.directory '*' + echo "/opt/python/cp312-cp312/bin" >> "$GITHUB_PATH" + + # Rocky 10's riscv64 CIPD backend has no fuchsia/third_party/ninja build + # at all, and gn_gen.sh's own gn/ninja fetch goes through the CIPD + # client this job's patched pigweed wrapper.py bootstraps -- same "no + # CIPD gn/ninja on riscv64" situation build-skia-python.yml/ + # build-skia-pathops.yml already solved: build gn from source and get + # ninja from its own riscv64 PyPI wheel, ahead of bootstrap.sh. + - name: Install gn and ninja + run: | + set -e + python3 -m pip install ninja + git clone https://gn.googlesource.com/gn /tmp/gn + git -C /tmp/gn checkout "${GN_REVISION}" + (cd /tmp/gn && CXX=g++ python3 build/gen.py --allow-warnings && ninja -C out gn) + install -m 0755 /tmp/gn/out/gn /usr/local/bin/gn + + - name: Bootstrap + run: bash scripts/bootstrap.sh -p linux + + - name: Setup build and run build + run: | + scripts/build/gn_gen.sh --args=" \ + chip_project_config_include_dirs=[\"//..\"] \ + chip_crypto=\"boringssl\" \ + enable_rtti=true \ + chip_config_memory_debug_checks=false \ + chip_config_memory_debug_dmalloc=false \ + chip_exchange_node_id_logging=true \ + chip_mdns=\"minimal\" \ + chip_minmdns_default_policy=\"libnl\" \ + chip_python_version=\"${{ env.CHIP_VERSION }}\" \ + chip_python_package_prefix=\"home-assistant-chip\" \ + chip_python_platform_tag=\"manylinux_2_39\" \ + chip_code_pre_generated_directory=\"$(pwd)/zzz_pregenerated\" \ + " + scripts/run_in_build_env.sh "ninja -C ./out chip-repl" + + - name: Run Python library specific unit tests + run: | + scripts/run_in_build_env.sh 'pip3 install ./out/controller/python/home_assistant_chip_core-${{ env.CHIP_VERSION }}-cp37-abi3-manylinux_2_39_riscv64.whl' + scripts/run_in_build_env.sh 'pip3 install ./out/controller/python/home_assistant_chip_clusters-${{ env.CHIP_VERSION }}-py3-none-any.whl' + scripts/run_in_build_env.sh 'pip3 install ./out/controller/python/home_assistant_chip_repl-${{ env.CHIP_VERSION }}-py3-none-any.whl' + scripts/run_in_build_env.sh '(cd src/controller/python/test/unit_tests/ && python3 -m unittest -v)' + + - name: Repair wheel + run: | + mkdir -p ../wheelhouse + pip3 install auditwheel + auditwheel repair -w ../wheelhouse --plat manylinux_2_39_riscv64 \ + out/controller/python/home_assistant_chip_core-${{ env.CHIP_VERSION }}-cp37-abi3-manylinux_2_39_riscv64.whl + cp out/controller/python/home_assistant_chip_clusters-${{ env.CHIP_VERSION }}-py3-none-any.whl ../wheelhouse/ + cp out/controller/python/home_assistant_chip_repl-${{ env.CHIP_VERSION }}-py3-none-any.whl ../wheelhouse/ + + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: home-assistant-chip-core-${{ env.CHIP_VERSION }}-manylinux_riscv64 + path: wheelhouse/*.whl + if-no-files-found: error + + gpl_sources: + needs: [setup] + if: needs.setup.outputs.versions != '[]' + strategy: + fail-fast: false + matrix: + version: ${{ fromJSON(needs.setup.outputs.versions) }} + name: Collect GPL sources (glib2, libnl3) for home-assistant-chip-core ${{ matrix.version }} + runs-on: ubuntu-24.04-riscv + env: + CHIP_VERSION: ${{ matrix.version }} + + steps: + # auditwheel vendors the image's libglib-2.0/libgobject-2.0/libgio-2.0 + # (glib2, LGPL) and libnl-3/libnl-route-3 (libnl3, LGPL) into the wheel. + - name: Collect glib2/libnl3 source RPMs from manylinux_riscv64 + uses: riseproject-dev/python-wheels/actions/collect-gpl-sources@main + with: + image: ${{ env.MANYLINUX_RISCV64_IMAGE }} + packages: glib2 libnl3 + output: gpl-sources.tar + + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: home-assistant-chip-core-${{ env.CHIP_VERSION }}-gpl-sources + path: gpl-sources.tar + if-no-files-found: error + + publish: + name: Publish home-assistant-chip-core ${{ matrix.version }} + needs: [setup, build_wheels, gpl_sources] + if: needs.setup.outputs.versions != '[]' + strategy: + fail-fast: false + matrix: + version: ${{ fromJSON(needs.setup.outputs.versions) }} + permissions: + contents: write + pull-requests: write + uses: $/.github/workflows/_publish-wheel.yml + secrets: + app-private-key: ${{ secrets.RISEPROJECT_APP_PRIVATE_KEY }} + with: + artifact-pattern: home-assistant-chip-core-${{ matrix.version }}-manylinux_riscv64 + gpl-sources-artifact: home-assistant-chip-core-${{ matrix.version }}-gpl-sources + gpl-sources-description: glib2, libnl3 diff --git a/docs/packages/home-assistant-chip-core.yaml b/docs/packages/home-assistant-chip-core.yaml new file mode 100644 index 000000000000..c7f272eab039 --- /dev/null +++ b/docs/packages/home-assistant-chip-core.yaml @@ -0,0 +1,5 @@ +package-name: home-assistant-chip-core +source-code: https://github.com/home-assistant-libs/chip-wheels +license: Apache-2.0 +versions: +- version: 2025.7.0 diff --git a/patches/home-assistant-chip-core/2025.7.0/0001-pigweed-cipd_setup-wrapper-support-linux-riscv64.patch b/patches/home-assistant-chip-core/2025.7.0/0001-pigweed-cipd_setup-wrapper-support-linux-riscv64.patch new file mode 100644 index 000000000000..4f0f2d88d079 --- /dev/null +++ b/patches/home-assistant-chip-core/2025.7.0/0001-pigweed-cipd_setup-wrapper-support-linux-riscv64.patch @@ -0,0 +1,54 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ludovic Henry +Date: Thu, 15 Oct 2026 00:00:00 +0000 +Subject: [PATCH] pigweed: cipd_setup/wrapper.py: support linux-riscv64 + +Upstream-Status: To upstream [not yet submitted to google/pigweed] + +cipd_setup/wrapper.py bootstraps the standalone `cipd` client binary +used by Pigweed's env setup. Two separate bugs there make it reject +riscv64 entirely, even though the CIPD backend itself already serves a +linux-riscv64 client (chrome-infra-packages.appspot.com, and +.cipd_version.digests lists a linux-riscv64 sha256 for the pinned +client version): + +- arch_normalized() only special-cases arm/aarch64; everything else + falls through to `machine.endswith('64')`, which maps the literal + string "riscv64" to "amd64" because it also ends in "64". +- SUPPORTED_PLATFORMS is a hardcoded tuple that never listed + "linux-riscv64" to begin with, so client_bytes() would raise + UnsupportedPlatform even with the arch mapping fixed. + +Neither function used by this wheel's actual package-selection logic +(cipd_setup/update.py:platform(), which already falls back to the +literal "riscv64" string) needs a patch; only the client bootstrap +path in this file does. + +Signed-off-by: Ludovic Henry +--- + third_party/pigweed/repo/pw_env_setup/py/pw_env_setup/cipd_setup/wrapper.py | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/third_party/pigweed/repo/pw_env_setup/py/pw_env_setup/cipd_setup/wrapper.py b/third_party/pigweed/repo/pw_env_setup/py/pw_env_setup/cipd_setup/wrapper.py +index 151745d..75228bc 100644 +--- a/third_party/pigweed/repo/pw_env_setup/py/pw_env_setup/cipd_setup/wrapper.py ++++ b/third_party/pigweed/repo/pw_env_setup/py/pw_env_setup/cipd_setup/wrapper.py +@@ -51,6 +51,7 @@ SUPPORTED_PLATFORMS = ( + 'linux-mipsle', + 'linux-ppc64', + 'linux-ppc64le', ++ 'linux-riscv64', + 'linux-s390x', + 'mac-amd64', + 'mac-arm64', +@@ -135,6 +136,8 @@ def arch_normalized(rosetta=False): + if machine == 'arm64': + return machine + return 'armv6l' ++ if machine == 'riscv64': ++ return machine + if machine.endswith('64'): + return 'amd64' + if machine.endswith('86'): +-- +2.50.1 diff --git a/patches/home-assistant-chip-core/2025.7.0/0002-scripts-setup-exclude-gn-ninja-clang-from-cipd.patch b/patches/home-assistant-chip-core/2025.7.0/0002-scripts-setup-exclude-gn-ninja-clang-from-cipd.patch new file mode 100644 index 000000000000..4a4642e5d0c7 --- /dev/null +++ b/patches/home-assistant-chip-core/2025.7.0/0002-scripts-setup-exclude-gn-ninja-clang-from-cipd.patch @@ -0,0 +1,43 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ludovic Henry +Date: Thu, 15 Oct 2026 00:00:00 +0000 +Subject: [PATCH] scripts/setup: exclude gn/ninja/clang from the Pigweed CIPD + fetch on riscv64 + +Upstream-Status: Inappropriate [riscv64 CI infra choice: gn/ninja/clang come from this repo's build-skia-python.yml precedent instead of CIPD, not a bug in gen_pigweed_cipd_json.py] + +fuchsia/third_party/ninja has no linux-riscv64 CIPD build at all (404 +against the live backend, confirmed at the pinned git_revision), and +while gn/gn and fuchsia/third_party/clang both do, chip_python_wheel_action +only runs Python scripts (build-chip-wheel.py) and nothing in +BUILD.gn/python_wheel.gni references clang or protoc directly, so +clang is unnecessary for this build. Reuse the mechanism this file +already uses to keep fuchsia/third_party/rust/ and +infra/3pp/tools/renode out of the generated CIPD package list, instead +of relying on CIPD's riscv64 coverage (or lack of it) for these three +tools: gn is built from source and ninja comes from its own riscv64 +PyPI wheel, exactly as this repo's build-skia-python.yml/ +build-skia-pathops.yml already do for the same gn/Ninja GN-based +family, put on PATH ahead of bootstrap.sh. + +Signed-off-by: Ludovic Henry +--- + scripts/setup/gen_pigweed_cipd_json.py | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/scripts/setup/gen_pigweed_cipd_json.py b/scripts/setup/gen_pigweed_cipd_json.py +index 4fe77aa..73784ac 100644 +--- a/scripts/setup/gen_pigweed_cipd_json.py ++++ b/scripts/setup/gen_pigweed_cipd_json.py +@@ -23,6 +23,9 @@ import platform + _LIST_OF_PACKAGES_TO_EXCLUDE = { + 'fuchsia/third_party/rust/', + 'infra/3pp/tools/renode', ++ 'gn/gn/', ++ 'fuchsia/third_party/ninja/', ++ 'fuchsia/third_party/clang/', + } + + +-- +2.50.1 From 449223dff66a284fd634c1b8825bc0c29e02e412 Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Thu, 15 Oct 2026 08:29:53 +0000 Subject: [PATCH 02/13] build-home-assistant-chip-core: only exclude gn/ninja/clang from CIPD on riscv64 gen_pigweed_cipd_json.py runs on both the x86_64 build_prepare job (ZAP codegen, which needs gn/ninja/clang fetched via CIPD) and the riscv64 build_wheels job (no CIPD coverage for them there). Patch 0002 added gn/gn/, fuchsia/third_party/ninja/ and fuchsia/third_party/clang/ to _LIST_OF_PACKAGES_TO_EXCLUDE unconditionally, so build_prepare lost gn/ninja/zap-cli too and failed with FileNotFoundError: 'gn' during pw_env_setup, then FAILED TO EXECUTE ZAP GENERATION: zap-cli during codepregen.py. Gate the three new exclusions on platform.machine() == 'riscv64', leaving the pre-existing rust/renode exclusions unconditional. --- ...tup-exclude-gn-ninja-clang-from-cipd.patch | 30 +++++++++++++------ 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/patches/home-assistant-chip-core/2025.7.0/0002-scripts-setup-exclude-gn-ninja-clang-from-cipd.patch b/patches/home-assistant-chip-core/2025.7.0/0002-scripts-setup-exclude-gn-ninja-clang-from-cipd.patch index 4a4642e5d0c7..f7c01be202f9 100644 --- a/patches/home-assistant-chip-core/2025.7.0/0002-scripts-setup-exclude-gn-ninja-clang-from-cipd.patch +++ b/patches/home-assistant-chip-core/2025.7.0/0002-scripts-setup-exclude-gn-ninja-clang-from-cipd.patch @@ -20,24 +20,36 @@ PyPI wheel, exactly as this repo's build-skia-python.yml/ build-skia-pathops.yml already do for the same gn/Ninja GN-based family, put on PATH ahead of bootstrap.sh. +This script runs on both the x86_64 build_prepare job (ZAP codegen, +which genuinely needs gn/ninja/clang from CIPD) and the riscv64 +build_wheels job (which carries over the same patched checkout and +runs its own bootstrap.sh), so the three riscv64-only exclusions are +gated on `platform.machine() == 'riscv64'` rather than applied +unconditionally; the pre-existing rust/renode exclusions are left +unconditional since they are unrelated to riscv64. + Signed-off-by: Ludovic Henry --- - scripts/setup/gen_pigweed_cipd_json.py | 3 +++ - 1 file changed, 3 insertions(+) + scripts/setup/gen_pigweed_cipd_json.py | 7 +++++++ + 1 file changed, 7 insertions(+) diff --git a/scripts/setup/gen_pigweed_cipd_json.py b/scripts/setup/gen_pigweed_cipd_json.py -index 4fe77aa..73784ac 100644 +index 4fe77aa..8ee7478 100644 --- a/scripts/setup/gen_pigweed_cipd_json.py +++ b/scripts/setup/gen_pigweed_cipd_json.py -@@ -23,6 +23,9 @@ import platform - _LIST_OF_PACKAGES_TO_EXCLUDE = { - 'fuchsia/third_party/rust/', +@@ -25,6 +25,13 @@ _LIST_OF_PACKAGES_TO_EXCLUDE = { 'infra/3pp/tools/renode', -+ 'gn/gn/', -+ 'fuchsia/third_party/ninja/', -+ 'fuchsia/third_party/clang/', } ++if platform.machine() == 'riscv64': ++ _LIST_OF_PACKAGES_TO_EXCLUDE.update({ ++ 'gn/gn/', ++ 'fuchsia/third_party/ninja/', ++ 'fuchsia/third_party/clang/', ++ }) ++ + def include_package(package: dict) -> bool: + if 'path' in package: -- 2.50.1 From 0794f5f5e2e85ac1762078b61dff40728920cdd4 Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Fri, 16 Oct 2026 02:24:02 +0000 Subject: [PATCH 03/13] build-home-assistant-chip-core: install libstdc++-static for gn link on riscv64 gn's own build (build/gen.py) links with -static-libstdc++, which needs libstdc++.a. The riscv64 manylinux_2_39 image doesn't ship it by default, so the link failed with "/usr/bin/ld: cannot find -lstdc++" (gotcha 77, the same fix build-skia-python.yml/build-skia-pathops.yml already apply). --- .github/workflows/build-home-assistant-chip-core.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-home-assistant-chip-core.yml b/.github/workflows/build-home-assistant-chip-core.yml index 41ee25a7af9a..b08a8e441edb 100644 --- a/.github/workflows/build-home-assistant-chip-core.yml +++ b/.github/workflows/build-home-assistant-chip-core.yml @@ -143,7 +143,8 @@ jobs: run: | dnf install -y --enablerepo=crb zstd \ openssl-devel glib2-devel libnl3-devel cairo-devel \ - gobject-introspection-devel dbus-devel python3-devel + gobject-introspection-devel dbus-devel python3-devel \ + libstdc++-static tar -xaf connectedhomeip-${{ env.CHIP_VERSION }}.tar.zst --use-compress-program=zstdmt git config --global --add safe.directory '*' echo "/opt/python/cp312-cp312/bin" >> "$GITHUB_PATH" @@ -154,6 +155,10 @@ jobs: # CIPD gn/ninja on riscv64" situation build-skia-python.yml/ # build-skia-pathops.yml already solved: build gn from source and get # ninja from its own riscv64 PyPI wheel, ahead of bootstrap.sh. + # + # gn's own link step passes -static-libstdc++, which needs + # libstdc++.a -- the riscv64 manylinux image doesn't ship it by + # default (CLAUDE.md gotcha 77), hence libstdc++-static above. - name: Install gn and ninja run: | set -e From 339f37b47b0f9b8dd8ceb2f1f46a7f188b261cc4 Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Sat, 17 Oct 2026 03:47:37 +0000 Subject: [PATCH 04/13] home-assistant-chip-core: make the connectedhomeip submodule self-contained before tarring Fixes PR #3279's build_wheels failure: actions/checkout's submodules:true leaves connectedhomeip/.git as a gitfile pointing at ../.git/modules/connectedhomeip in the outer chip-wheels checkout. Create Matter SDK tar packages only the connectedhomeip/ directory itself, so that gitlink's target never makes it into the tarball. build_wheels extracts the tar into a completely separate riscv64 container with no outer chip-wheels checkout at all, so every git command inside connectedhomeip/ fails with 'fatal: gitfile does not point to a valid repository' -- including pigweed's bootstrap.sh, which runs 'git submodule status --recursive' there. Move connectedhomeip's real git directory into connectedhomeip/.git itself (and drop the now-stale core.worktree it inherits) right after checkout, so it is a standalone repository before anything packages it. Verified the failure and the fix against a throwaway superproject/ submodule pair: tarring+extracting the submodule alone reproduces 'fatal: not a git repository' on the gitlink target exactly as seen in CI, and the same tar/extract round-trip succeeds once the git directory is relocated this way. --- .../build-home-assistant-chip-core.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.github/workflows/build-home-assistant-chip-core.yml b/.github/workflows/build-home-assistant-chip-core.yml index b08a8e441edb..314b71a8c015 100644 --- a/.github/workflows/build-home-assistant-chip-core.yml +++ b/.github/workflows/build-home-assistant-chip-core.yml @@ -71,6 +71,23 @@ jobs: fetch-depth: 0 persist-credentials: false + # actions/checkout's submodules:true leaves connectedhomeip/.git as a + # gitfile pointing at ../.git/modules/connectedhomeip (standard git + # 2.7+ layout) -- fine in this job, but "Create Matter SDK tar" below + # packages only connectedhomeip/ itself, dropping that gitlink's + # target. build_wheels then extracts the tar into a fresh riscv64 + # container with no outer chip-wheels checkout at all, so every git + # command inside connectedhomeip/ fails ("fatal: gitfile does not + # point to a valid repository") -- including pigweed's own bootstrap, + # which runs `git submodule status --recursive` there. Move the real + # git directory into connectedhomeip/.git itself so it survives the + # tar/extract boundary as a standalone repository. + - name: Make the connectedhomeip submodule self-contained + run: | + rm connectedhomeip/.git + cp -r .git/modules/connectedhomeip connectedhomeip/.git + git -C connectedhomeip config --unset core.worktree + - name: Checkout python-wheels uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: From 239a3f569796cfdb3b2ffb63d7786d294d2c01c5 Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Sat, 17 Oct 2026 03:59:58 +0000 Subject: [PATCH 05/13] home-assistant-chip-core: edit the copied git config directly, not via -C The previous commit's 'git -C connectedhomeip config --unset core.worktree' itself failed build_prepare: any git invocation resolves core.worktree as part of repository discovery before running the actual command, and the freshly-copied config's worktree setting (relative to its old location, .git/modules/connectedhomeip) now points one level too far up from connectedhomeip/.git -- 'fatal: cannot chdir to ../../../connectedhomeip: No such file or directory'. git config --file edits the given file directly with no repository discovery at all, sidestepping the chicken-and-egg problem. Verified end to end against a throwaway superproject/submodule pair: move the git directory, unset core.worktree this way, tar the submodule alone, extract it fresh elsewhere, and 'git submodule status --recursive' (what pigweed's bootstrap actually runs) succeeds. --- .github/workflows/build-home-assistant-chip-core.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-home-assistant-chip-core.yml b/.github/workflows/build-home-assistant-chip-core.yml index 314b71a8c015..4c1773646754 100644 --- a/.github/workflows/build-home-assistant-chip-core.yml +++ b/.github/workflows/build-home-assistant-chip-core.yml @@ -86,7 +86,13 @@ jobs: run: | rm connectedhomeip/.git cp -r .git/modules/connectedhomeip connectedhomeip/.git - git -C connectedhomeip config --unset core.worktree + # `git -C connectedhomeip ...` won't do: any git invocation + # resolves core.worktree as part of repo discovery, before running + # the command itself, and the copied config's worktree (relative + # to its old location, .git/modules/connectedhomeip) now points + # one level too far up ("cannot chdir to '../../../connectedhomeip'"). + # --file edits the config directly, with no repo discovery at all. + git config --file connectedhomeip/.git/config --unset core.worktree - name: Checkout python-wheels uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 From a1536b2f4aadb581959682c87f6c8232e1cd9f4c Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Sat, 17 Oct 2026 11:31:54 +0000 Subject: [PATCH 06/13] home-assistant-chip-core: add linux riscv64 GN toolchain, pin gn to Pigweed's revision Fixes PR #3279's build_wheels failure in Bootstrap: the `gn gen` that Pigweed's env setup runs to install the Python packages failed with every target reporting "needs //build/toolchain/linux:linux_riscv64_gcc()". connectedhomeip's build/config/BUILDCONFIG.gn selects the default Linux toolchain as //build/toolchain/linux:linux_${target_cpu}_gcc, and build/toolchain/linux/BUILD.gn only defines it for x64, x86, arm and arm64 (still the case on upstream master). New patch 0003 adds a linux_riscv64_gcc toolchain mirroring linux_x64_gcc (native host gcc/g++/ar, no cross prefix; build/config/compiler has no riscv64 flags to add). It also adds riscv64 to the host_cpu list behind chip_enable_python_modules in the root BUILD.gn: without that, //src/controller/python:chip-repl is left out of the graph on a riscv64 host and gn_gen.sh's --fail-on-unused-args rejects chip_python_package_prefix. Separately, GN_REVISION was carried over from build-skia-python.yml and is much newer than the gn/gn git_revision (487f8353) the pinned Pigweed's cipd_setup/pigweed.json gives every other platform. That newer gn checks all targets for duplicated outputs and rejects connectedhomeip's graph with "Two or more targets generate the same output" on pw_protobuf_compiler's *._includes files, on x86_64 as well as riscv64, so it would have failed the same Bootstrap step right after the toolchain fix. Pin the revision Pigweed itself uses instead. Verified with gn built at both revisions from source: the bootstrap `gn gen` and gn_gen.sh's `gn gen --check --fail-on-unused-args` with this workflow's args, run on a riscv64 gn binary under qemu-user (host_cpu = "riscv64") against the pinned connectedhomeip with all three patches plus chip-wheels' own applied, both succeed, emit native gcc/g++ rules with no x86/arm flags, and name the wheel manylinux_2_39_riscv64. Without patch 0003 the graph fails exactly as in CI; with gn 0625da07 even an x86_64 host fails on the duplicate outputs. --- .../build-home-assistant-chip-core.yml | 5 +- ...d-support-native-linux-riscv64-hosts.patch | 69 +++++++++++++++++++ 2 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 patches/home-assistant-chip-core/2025.7.0/0003-build-support-native-linux-riscv64-hosts.patch diff --git a/.github/workflows/build-home-assistant-chip-core.yml b/.github/workflows/build-home-assistant-chip-core.yml index 4c1773646754..b06e2f3f25c6 100644 --- a/.github/workflows/build-home-assistant-chip-core.yml +++ b/.github/workflows/build-home-assistant-chip-core.yml @@ -33,7 +33,8 @@ permissions: contents: read # to fetch code (actions/checkout) env: - GN_REVISION: 0625da07ece7b1a374ec0719b6f40ebe3d0950c1 + # gn/gn git_revision pinned by the Pigweed submodule's cipd_setup/pigweed.json + GN_REVISION: 487f8353f15456474437df32bb186187b0940b45 MANYLINUX_RISCV64_IMAGE: quay.io/pypa/manylinux_2_39_riscv64 jobs: @@ -104,7 +105,7 @@ jobs: working-directory: connectedhomeip run: scripts/checkout_submodules.py --shallow --platform linux - - name: Patch CIPD bootstrap for riscv64 + - name: Apply riscv64 patches working-directory: connectedhomeip run: git apply ../python-wheels/patches/home-assistant-chip-core/${{ env.CHIP_VERSION }}/*.patch diff --git a/patches/home-assistant-chip-core/2025.7.0/0003-build-support-native-linux-riscv64-hosts.patch b/patches/home-assistant-chip-core/2025.7.0/0003-build-support-native-linux-riscv64-hosts.patch new file mode 100644 index 000000000000..da12b5d8877b --- /dev/null +++ b/patches/home-assistant-chip-core/2025.7.0/0003-build-support-native-linux-riscv64-hosts.patch @@ -0,0 +1,69 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ludovic Henry +Date: Sat, 17 Oct 2026 00:00:00 +0000 +Subject: [PATCH] build: support native linux riscv64 hosts + +Upstream-Status: To upstream [not yet submitted to project-chip/connectedhomeip] + +Two places in the GN build only know about the Linux CPUs upstream +already builds on (x64, x86, arm, arm64), so a native riscv64 host +can't generate the build at all: + +- build/config/BUILDCONFIG.gn picks the default Linux toolchain as + //build/toolchain/linux:linux_${target_cpu}_${compiler}, which on a + riscv64 host is linux_riscv64_gcc, but build/toolchain/linux/BUILD.gn + never defines it. Every target then fails to resolve with "needs + //build/toolchain/linux:linux_riscv64_gcc()", starting with the + `gn gen` Pigweed's bootstrap runs to install the Python packages. + Add it next to the existing ones. It mirrors linux_x64_gcc rather + than the cross-prefixed arm/arm64 ones, since this is a native build + with the host gcc/g++/ar; build/config/compiler/BUILD.gn has no + riscv64-specific flags to add (its "riscv" branch is the embedded + FreeRTOS one), so the compiler's own rv64gc/lp64d defaults apply. +- chip_enable_python_modules defaults to false unless host_cpu is x64, + arm64 or arm, which leaves //src/controller/python:chip-repl out of + the graph (and rejects chip_python_package_prefix as an unused arg + under gn_gen.sh's --fail-on-unused-args). Add riscv64 to that list, + the same way arm was added for Raspbian. + +src/controller/python/BUILD.gn already falls back to cpu_tag = +current_cpu, so the wheel comes out as *_riscv64 with no change there. + +Signed-off-by: Ludovic Henry +--- + BUILD.gn | 3 ++- + build/toolchain/linux/BUILD.gn | 8 ++++++++ + 2 files changed, 10 insertions(+), 1 deletion(-) + +diff --git a/BUILD.gn b/BUILD.gn +index 465eccc..88be251 100644 +--- a/BUILD.gn ++++ b/BUILD.gn +@@ -43,7 +43,8 @@ if (current_toolchain != "${dir_pw_toolchain}/default:default") { + declare_args() { + chip_enable_python_modules = + (current_os == "mac" || current_os == "linux") && +- (host_cpu == "x64" || host_cpu == "arm64" || host_cpu == "arm") ++ (host_cpu == "x64" || host_cpu == "arm64" || host_cpu == "arm" || ++ host_cpu == "riscv64") + + # Build the Linux all clusters app example with default group + chip_build_all_clusters_app = false +diff --git a/build/toolchain/linux/BUILD.gn b/build/toolchain/linux/BUILD.gn +index abc61ab..5f912cf 100644 +--- a/build/toolchain/linux/BUILD.gn ++++ b/build/toolchain/linux/BUILD.gn +@@ -91,3 +91,11 @@ gcc_toolchain("linux_arm64_clang") { + is_clang = true + } + } ++ ++gcc_toolchain("linux_riscv64_gcc") { ++ toolchain_args = { ++ current_os = "linux" ++ current_cpu = "riscv64" ++ is_clang = false ++ } ++} +-- +2.50.1 From bf5a50235b60cebe062cd818a3ff57fe5ee3531e Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Sat, 17 Oct 2026 16:18:30 +0000 Subject: [PATCH 07/13] home-assistant-chip-core: build protoc from source for riscv64 Fixes PR #3279's build_wheels failure in Bootstrap: with the GN toolchain in place, Pigweed's env setup now gets as far as building :python_packages.install, and every generate_protos.py invocation (pw_protobuf common/codegen protos, pw_protobuf_compiler test protos, pw_system device_service, pw_tokenizer options) dies with "FileNotFoundError: No such file or directory: PosixPath('protoc')". generate_protos.py runs a bare `protoc` from PATH (pigweed only passes --protoc when pw_protobuf_compiler_PROTOC_TARGET is set, and CHIP does not set it). On every other platform that protoc comes from the infra/3pp/tools/protoc CIPD package in the pinned Pigweed's cipd_setup/pigweed.json (version:3@28.2). Its platforms list stops at linux-amd64/linux-arm64, so cipd_setup/update.py silently skips it on riscv64, and the CIPD backend has no infra/3pp/tools/protoc/linux-riscv64 package at all (only linux-amd64/arm64, mac and windows builds exist). The riscv64 alternatives that are already packaged don't work: - Rocky 10 CRB's protobuf-compiler is 3.19.6. generate_protos.py always passes --experimental_editions, which 3.19.6 rejects ("Missing value for flag: --experimental_editions"). - The riscv64 grpcio-tools wheels on pypi.riseproject.dev (1.83.1, 1.84.0) bundle libprotoc 35.1. Its Python gencode requires a protobuf 7.x runtime, but CHIP's constraints.txt pins protobuf==5.28.3. Neither PyPI nor the registry has a riscv64 protoc-wheel-0 or an older grpcio-tools. So build protoc 28.2, the version Pigweed's CIPD pin uses, from the protobuf git tag with its abseil-cpp submodule. The release tarball leaves third_party/abseil-cpp empty. Only the protoc target is built, with tests, libupb and zlib off. It is installed with the well-known .proto files into /opt/protoc, the same bin/ plus include/ layout as the CIPD package, and symlinked into /usr/local/bin like gn. protoc finds /include relative to its resolved binary, which field_options.proto and pw_tokenizer's options.proto need for google/protobuf/descriptor.proto. No patch change is needed, because CIPD already skips the package on riscv64. Verified locally with this step's exact cmake build and the two component installs. protoc 28.2 was built natively on x86_64 and cross-built for riscv64 with GCC 14. The riscv64 build was run under qemu-user. In both cases protoc was reached only as a bare `protoc` on PATH, and the five failing generate_protos.py --language python invocations from the CI log were replayed against the pinned Pigweed (3fe6ddb) sources. All five succeed and emit the _pb2.py/.pyi files, including the two that import google/protobuf/descriptor.proto, which resolves from /include. The riscv64 and x86_64 outputs are byte-identical. Every generated module imports under protobuf==5.28.3 with mypy-protobuf 3.5.0 present, as in CHIP's venv. The same replay with protoc 3.19.6 fails on --experimental_editions. The configure also passes under CMake 4.4, matching the image's pipx cmake. --- .../build-home-assistant-chip-core.yml | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/.github/workflows/build-home-assistant-chip-core.yml b/.github/workflows/build-home-assistant-chip-core.yml index b06e2f3f25c6..1113acedd054 100644 --- a/.github/workflows/build-home-assistant-chip-core.yml +++ b/.github/workflows/build-home-assistant-chip-core.yml @@ -35,6 +35,8 @@ permissions: env: # gn/gn git_revision pinned by the Pigweed submodule's cipd_setup/pigweed.json GN_REVISION: 487f8353f15456474437df32bb186187b0940b45 + # infra/3pp/tools/protoc version pinned by the same pigweed.json + PROTOC_VERSION: '28.2' MANYLINUX_RISCV64_IMAGE: quay.io/pypa/manylinux_2_39_riscv64 jobs: @@ -192,6 +194,26 @@ jobs: (cd /tmp/gn && CXX=g++ python3 build/gen.py --allow-warnings && ninja -C out gn) install -m 0755 /tmp/gn/out/gn /usr/local/bin/gn + # Pigweed's bootstrap runs a bare `protoc` from PATH to generate the + # Python protos, and infra/3pp/tools/protoc has no linux-riscv64 CIPD + # build. CRB's protobuf-compiler (3.19.6) rejects --experimental_editions + # and the riscv64 grpcio-tools bundles protoc 35, whose output won't load + # under CHIP's protobuf==5.28.3, so build Pigweed's own version. The + # well-known .protos go in /opt/protoc/include, found relative to the binary. + - name: Install protoc + run: | + set -e + git clone --depth 1 --branch "v${PROTOC_VERSION}" https://github.com/protocolbuffers/protobuf /tmp/protobuf + git -C /tmp/protobuf submodule update --init --depth 1 third_party/abseil-cpp + cmake -S /tmp/protobuf -B /tmp/protobuf/build -G Ninja \ + -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/opt/protoc \ + -Dprotobuf_BUILD_TESTS=OFF -Dprotobuf_BUILD_LIBUPB=OFF -Dprotobuf_WITH_ZLIB=OFF + cmake --build /tmp/protobuf/build --target protoc + cmake --install /tmp/protobuf/build --component protoc + cmake --install /tmp/protobuf/build --component protobuf-headers + ln -s /opt/protoc/bin/protoc /usr/local/bin/protoc + protoc --version + - name: Bootstrap run: bash scripts/bootstrap.sh -p linux From 76b2fc320c604285ae64ecf9a43ca55609c4d98c Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Sat, 17 Oct 2026 19:19:57 +0000 Subject: [PATCH 08/13] home-assistant-chip-core: build protobuf from sdist on riscv64 Fixes PR #3279's build_wheels failure in Bootstrap. With protoc in place, :python_packages.install now gets past --python_out, but the --mypy_out plugin that runs in the same protoc call fails for every proto (pw_protobuf common/codegen protos, pw_protobuf_compiler test protos, pw_system device_service, pw_tokenizer options): mypy_protobuf/extensions_pb2.py, line 23 google_dot_protobuf_dot_descriptor__pb2.FieldOptions.RegisterExtension(options) AttributeError: type object 'FieldOptions' has no attribute 'RegisterExtension' The pins match every other platform. CHIP's constraints.txt has protobuf==5.28.3 and mypy-protobuf==3.5.0, and Pigweed's pw_protobuf_compiler requires mypy-protobuf<3.6.0. The difference is which protobuf wheel gets installed. protobuf 5.28.3 ships binary (upb) wheels for manylinux x86_64/aarch64 only. A riscv64 cp312 pip falls back to protobuf-5.28.3-py3-none-any.whl, the pure-Python backend, and pypi.riseproject.dev only carries riscv64 protobuf 7.x. In 5.28.3 the pure-Python backend's python_message.py has no RegisterExtension, while the upb extension still provides it. mypy-protobuf 3.5.0's prebuilt extensions_pb2.py calls it, so protoc-gen-mypy cannot even import. Set PIP_NO_BINARY=protobuf for build_wheels. pip then builds protobuf 5.28.3 from its sdist, which compiles the same google._upb._message extension the binary wheels ship. The version stays as pinned, and mypy-protobuf's generated code is left untouched. Verified locally with CPython 3.12, the pinned Pigweed (3fe6ddb) protos and protoc 28.2. pip download for manylinux_2_39_riscv64 cp312 resolves both pins to py3-none-any wheels. A venv with exactly those wheels reproduces the CI traceback on all five protos. A venv installed with PIP_NO_BINARY=protobuf against CHIP's constraints.txt builds protobuf-5.28.3-cp312 from the sdist, reports the upb backend, and runs protoc --python_out --mypy_out cleanly on the same five protos. That holds with both the x86_64 protoc and the riscv64 protoc under qemu-user, and every generated _pb2 module imports. --- .github/workflows/build-home-assistant-chip-core.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/build-home-assistant-chip-core.yml b/.github/workflows/build-home-assistant-chip-core.yml index 1113acedd054..85920e47343b 100644 --- a/.github/workflows/build-home-assistant-chip-core.yml +++ b/.github/workflows/build-home-assistant-chip-core.yml @@ -158,6 +158,14 @@ jobs: env: CHIP_VERSION: ${{ matrix.version }} + # CHIP's constraints.txt pins protobuf==5.28.3, which ships binary (upb) + # wheels for x86_64/aarch64 only, so on riscv64 pip picks its + # py3-none-any wheel: the pure-Python backend. That backend has no + # FieldOptions.RegisterExtension, which the extensions_pb2.py bundled in + # the pinned mypy-protobuf 3.5.0 calls, so every protoc --mypy_out step + # in Bootstrap fails. Build protobuf from its sdist instead, which + # compiles the same upb extension the other platforms get. + PIP_NO_BINARY: protobuf steps: - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 From 32c2ad40044e3b46cbdcb76b7d06cda00e8e07af Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Sat, 17 Oct 2026 21:58:28 +0000 Subject: [PATCH 09/13] home-assistant-chip-core: hand only the ZAP output to the riscv64 job build_wheels downloaded a ~4.1 GB tar of the whole bootstrapped Matter SDK from build_prepare. The riscv64 runners pull Actions artifacts from Azure blob storage at ~1 MB/s, in a single stream that actions/download-artifact restarts from byte zero on any stall, so the download took 62-68 minutes when it worked and failed after ~60 minutes twice in a row. The tar grew from 1.8 GB to 4.1 GB once connectedhomeip's full-history git directory was copied into it. Only the ZAP pre-generation needs x86_64. build_wheels now checks out chip-wheels and the connectedhomeip submodules itself and applies both patch sets, which takes minutes from GitHub on these runners, and only zzz_pregenerated/ crosses jobs. Since the outer chip-wheels checkout is present again, the self-contained-submodule workaround is gone, and chip_project_config_include_dirs=["//.."] finds chip-wheels' CHIPProjectConfig.h as it does upstream. --- .../build-home-assistant-chip-core.yml | 80 ++++++++++--------- 1 file changed, 44 insertions(+), 36 deletions(-) diff --git a/.github/workflows/build-home-assistant-chip-core.yml b/.github/workflows/build-home-assistant-chip-core.yml index 85920e47343b..05688c89369a 100644 --- a/.github/workflows/build-home-assistant-chip-core.yml +++ b/.github/workflows/build-home-assistant-chip-core.yml @@ -48,10 +48,13 @@ jobs: # ZAP code generation has no riscv64 build (project-chip/zap ships prebuilt # Electron/node binaries for x86_64/arm64 only), so it runs once here on a - # regular x86_64 runner -- same split chip-wheels' own build.yaml uses - # between build_prepare (ubuntu-24.04) and its per-arch build job -- and the - # pre-generated output is carried into build_wheels via - # chip_code_pre_generated_directory, which never invokes ZAP itself. + # regular x86_64 runner, as in chip-wheels' own build_prepare, and + # build_wheels consumes it via chip_code_pre_generated_directory, which + # never invokes ZAP itself. Unlike chip-wheels, only zzz_pregenerated/ is + # handed over, not a tar of the whole SDK: the riscv64 runners download + # Actions artifacts at ~1 MB/s in one non-resumable stream, so that ~4 GB tar + # took over an hour and failed whenever the stream broke, while the same + # checkout and patches straight from GitHub take minutes there. build_prepare: name: Prepare home-assistant-chip-core ${{ matrix.version }} needs: [setup] @@ -71,32 +74,8 @@ jobs: repository: home-assistant-libs/chip-wheels ref: ${{ env.CHIP_VERSION }} submodules: true - fetch-depth: 0 persist-credentials: false - # actions/checkout's submodules:true leaves connectedhomeip/.git as a - # gitfile pointing at ../.git/modules/connectedhomeip (standard git - # 2.7+ layout) -- fine in this job, but "Create Matter SDK tar" below - # packages only connectedhomeip/ itself, dropping that gitlink's - # target. build_wheels then extracts the tar into a fresh riscv64 - # container with no outer chip-wheels checkout at all, so every git - # command inside connectedhomeip/ fails ("fatal: gitfile does not - # point to a valid repository") -- including pigweed's own bootstrap, - # which runs `git submodule status --recursive` there. Move the real - # git directory into connectedhomeip/.git itself so it survives the - # tar/extract boundary as a standalone repository. - - name: Make the connectedhomeip submodule self-contained - run: | - rm connectedhomeip/.git - cp -r .git/modules/connectedhomeip connectedhomeip/.git - # `git -C connectedhomeip ...` won't do: any git invocation - # resolves core.worktree as part of repo discovery, before running - # the command itself, and the copied config's worktree (relative - # to its old location, .git/modules/connectedhomeip) now points - # one level too far up ("cannot chdir to '../../../connectedhomeip'"). - # --file edits the config directly, with no repo discovery at all. - git config --file connectedhomeip/.git/config --unset core.worktree - - name: Checkout python-wheels uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: @@ -127,13 +106,13 @@ jobs: working-directory: connectedhomeip run: scripts/run_in_build_env.sh "scripts/codepregen.py ./zzz_pregenerated/" - - name: Create Matter SDK tar - run: tar -caf connectedhomeip-${{ env.CHIP_VERSION }}.tar.zst --exclude ./connectedhomeip/.environment --use-compress-program=zstdmt connectedhomeip + - name: Create ZAP pre-generated code tar + run: tar -caf zzz_pregenerated-${{ env.CHIP_VERSION }}.tar.zst --use-compress-program=zstdmt -C connectedhomeip zzz_pregenerated - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: - name: home-assistant-chip-core-${{ env.CHIP_VERSION }}-matter-sdk - path: connectedhomeip-${{ env.CHIP_VERSION }}.tar.zst + name: home-assistant-chip-core-${{ env.CHIP_VERSION }}-zap-pregenerated + path: zzz_pregenerated-${{ env.CHIP_VERSION }}.tar.zst if-no-files-found: error build_wheels: @@ -168,21 +147,50 @@ jobs: PIP_NO_BINARY: protobuf steps: - - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + - name: Checkout home-assistant-libs/chip-wheels ${{ env.CHIP_VERSION }} + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + repository: home-assistant-libs/chip-wheels + ref: ${{ env.CHIP_VERSION }} + submodules: true + persist-credentials: false + + - name: Checkout python-wheels + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: - name: home-assistant-chip-core-${{ env.CHIP_VERSION }}-matter-sdk + path: python-wheels + persist-credentials: false - - name: Extract Matter SDK from tar + - name: Install system dependencies working-directory: ./ run: | dnf install -y --enablerepo=crb zstd \ openssl-devel glib2-devel libnl3-devel cairo-devel \ gobject-introspection-devel dbus-devel python3-devel \ libstdc++-static - tar -xaf connectedhomeip-${{ env.CHIP_VERSION }}.tar.zst --use-compress-program=zstdmt git config --global --add safe.directory '*' echo "/opt/python/cp312-cp312/bin" >> "$GITHUB_PATH" + - name: Checkout connectedhomeip submodules + run: scripts/checkout_submodules.py --shallow --platform linux + + - name: Apply riscv64 patches + run: git apply ../python-wheels/patches/home-assistant-chip-core/${{ env.CHIP_VERSION }}/*.patch + + - name: Apply chip-wheels patches + run: | + for patch in ../*.patch; do + echo "Applying ${patch}" + patch -p1 < "$patch" + done + + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: home-assistant-chip-core-${{ env.CHIP_VERSION }}-zap-pregenerated + + - name: Extract ZAP pre-generated code + run: tar -xaf ../zzz_pregenerated-${{ env.CHIP_VERSION }}.tar.zst --use-compress-program=zstdmt + # Rocky 10's riscv64 CIPD backend has no fuchsia/third_party/ninja build # at all, and gn_gen.sh's own gn/ninja fetch goes through the CIPD # client this job's patched pigweed wrapper.py bootstraps -- same "no From 1a407489f375e688257077101cb2406c69e1c7db Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Sun, 18 Oct 2026 00:15:30 +0000 Subject: [PATCH 10/13] home-assistant-chip-core: take cryptography from the registry on riscv64 Fixes PR #3279's build_wheels failure in :python_packages.install (run 39073160824): Collecting cryptography (from pigweed==0.0.21+...) Using cached cryptography-43.0.0.tar.gz (686 kB) BackendUnavailable: ... ModuleNotFoundError: No module named 'maturin' Pigweed's pip_install_pigweed_package target (pw_python_pip_install in pw_build/python_dist.gni) always runs pip with --no-build-isolation, so any dependency of the generated `pigweed` package that has no wheel for the host is built inside the Pigweed venv, with only what that venv holds. pw_tls_client and pw_software_update require cryptography, which CHIP's constraints.txt pins to 43.0.0. That release has no riscv64 wheel on PyPI, so pip took its sdist, whose maturin backend isn't in the venv. Installing maturin there would not be enough either: the build also needs a Rust toolchain the manylinux image doesn't ship. pypi.riseproject.dev carries cryptography 43.0.1 for riscv64 (cp39-abi3, manylinux_2_35). 43.0.1 only rebuilds the upstream wheels against OpenSSL 3.3.2, with no code change. Patch 0004 bumps the constraint to 43.0.1, and build_wheels sets PIP_EXTRA_INDEX_URL to the registry plus PIP_ONLY_BINARY=cryptography,cffi. With that, pip installs the wheel instead of building, and so does cffi, whose cp312 riscv64 wheel is also only on the registry and whose sdist would need libffi-devel. Checked with a riscv64 cp312 dry-run resolve (PyPI plus the registry, patched constraints) over the install_requires of every Pigweed setup.cfg. cryptography is the only package in that closure with a non-setuptools native build backend. The remaining sdist-only pins (psutil 5.9.4, websockets 10.4, markupsafe 2.1.2, watchdog 2.3.1, docopt) are setuptools builds, which work without build isolation. --- .../build-home-assistant-chip-core.yml | 6 +++ ...tup-constrain-cryptography-to-43.0.1.patch | 42 +++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 patches/home-assistant-chip-core/2025.7.0/0004-scripts-setup-constrain-cryptography-to-43.0.1.patch diff --git a/.github/workflows/build-home-assistant-chip-core.yml b/.github/workflows/build-home-assistant-chip-core.yml index 05688c89369a..bb2e94936e72 100644 --- a/.github/workflows/build-home-assistant-chip-core.yml +++ b/.github/workflows/build-home-assistant-chip-core.yml @@ -145,6 +145,12 @@ jobs: # in Bootstrap fails. Build protobuf from its sdist instead, which # compiles the same upb extension the other platforms get. PIP_NO_BINARY: protobuf + # Pigweed pip-installs its own package with --no-build-isolation, so a + # dependency with no riscv64 wheel is built in the Pigweed venv, which + # has no maturin (or Rust) for cryptography's sdist. Take cryptography + # (pinned to 43.0.1 by patch 0004) and its cffi from our registry. + PIP_EXTRA_INDEX_URL: https://pypi.riseproject.dev/simple/ + PIP_ONLY_BINARY: cryptography,cffi steps: - name: Checkout home-assistant-libs/chip-wheels ${{ env.CHIP_VERSION }} diff --git a/patches/home-assistant-chip-core/2025.7.0/0004-scripts-setup-constrain-cryptography-to-43.0.1.patch b/patches/home-assistant-chip-core/2025.7.0/0004-scripts-setup-constrain-cryptography-to-43.0.1.patch new file mode 100644 index 000000000000..90cf09905e27 --- /dev/null +++ b/patches/home-assistant-chip-core/2025.7.0/0004-scripts-setup-constrain-cryptography-to-43.0.1.patch @@ -0,0 +1,42 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ludovic Henry +Date: Sun, 18 Oct 2026 00:00:00 +0000 +Subject: [PATCH] scripts/setup: constrain cryptography to 43.0.1 + +Upstream-Status: Inappropriate [riscv64 wheel availability: cryptography 43.0.0 has no riscv64 wheel, 43.0.1 is on pypi.riseproject.dev] + +Pigweed's pip_install_pigweed_package target (pw_python_pip_install) +always installs the generated `pigweed` package with +--no-build-isolation, so every third-party dependency it pulls in that +has no wheel for the host is built inside the Pigweed venv itself. +cryptography==43.0.0 ships no riscv64 wheel on PyPI, so pip falls back +to its sdist, whose maturin build backend isn't in that venv +(ModuleNotFoundError: No module named 'maturin'); building it would +also need a Rust toolchain the manylinux image doesn't have. + +pypi.riseproject.dev ships cryptography 43.0.1 for riscv64 +(cp39-abi3), a patch release whose only change is the OpenSSL version +compiled into the upstream wheels. Pin that version so the riscv64 +build_wheels job can install it as a wheel. x86_64 (build_prepare) +gets 43.0.1 from PyPI just like 43.0.0. + +Signed-off-by: Ludovic Henry +--- + scripts/setup/constraints.txt | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/scripts/setup/constraints.txt b/scripts/setup/constraints.txt +index 905ef7c..89cd541 100644 +--- a/scripts/setup/constraints.txt ++++ b/scripts/setup/constraints.txt +@@ -55,7 +55,7 @@ contextlib2==21.6.0 + # via + # idf-component-manager + # schema +-cryptography==43.0.0 ++cryptography==43.0.1 + # via + # -c constraints.esp32.txt + # -r requirements.all.txt +-- +2.50.1 From 42f1e4fa20c209b6b535b7a56210ce43a18da201 Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Sun, 18 Oct 2026 02:12:08 +0000 Subject: [PATCH 11/13] home-assistant-chip-core: run Pigweed's bootstrap venv on pip 24.3.1 Fixes PR #3279's build_wheels failure in :python_packages.install (run 39082118553): ERROR: Cannot install pigweed==0.0.21+20261018014909 because these package versions have conflicting dependencies. pigweed 0.0.21+20261018014909 depends on cryptography The user requested (constraint) cryptography==43.0.1 This is not a version-range conflict. pw_tls_client/py/setup.cfg, the only Pigweed package that needs cryptography at this submodule revision (3fe6ddbf82e6), asks for a bare `cryptography`, with no specifier. pip found no installable candidate for cryptography==43.0.1 at all. Pigweed's virtualenv setup upgrades the bootstrap venv's pip under CHIP's constraints.txt, which pins pip==23.2.1. That pip vendors packaging 21.3, whose manylinux arch allowlist has no riscv64, so it reports only linux_riscv64 tags (gotchas 234/640). It therefore rejects pypi.riseproject.dev's cryptography-43.0.1-cp39-abi3-manylinux_2_35_riscv64 wheel. PIP_ONLY_BINARY=cryptography rules out the sdist, so no candidate is left. Patch 0005 pins pip==24.3.1, the version this Pigweed revision's own python_base_requirements.txt pins and already installs in the GN build venv. pip 24.1 is the first release that knows riscv64 manylinux tags. Checked with a cp312 venv made to report linux-riscv64 (glibc 2.39, the same glibc as manylinux_2_39), against PyPI plus the registry, with build_wheels' PIP_* settings. The resolve covered every third-party install_requires of Pigweed's setup.cfg/pyproject.toml files plus requirements.build.txt: - pip 23.2.1 lists 27 riscv64 tags, all linux_riscv64. The resolve fails with the same ResolutionImpossible as CI. - pip 24.3.1 lists 675 tags, headed by cp312-cp312-manylinux_2_39_riscv64. The resolve succeeds with cryptography 43.0.1 and cffi 2.1.1, both from registry wheels. The only sdists left are setuptools builds (MarkupSafe, docopt, protobuf via PIP_NO_BINARY, psutil, watchdog, websockets). - On x86_64, build_prepare's requirements.all.txt plus the Pigweed set resolve under pip 24.3.1 just as they do under 23.2.1. - pip-tools 7.0.0, still pinned by constraints.txt, installs alongside pip 24.3.1 (it only requires pip>=22.2). --- .../build-home-assistant-chip-core.yml | 3 ++ ...cripts-setup-constrain-pip-to-24.3.1.patch | 42 +++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 patches/home-assistant-chip-core/2025.7.0/0005-scripts-setup-constrain-pip-to-24.3.1.patch diff --git a/.github/workflows/build-home-assistant-chip-core.yml b/.github/workflows/build-home-assistant-chip-core.yml index bb2e94936e72..6d4d1feecc22 100644 --- a/.github/workflows/build-home-assistant-chip-core.yml +++ b/.github/workflows/build-home-assistant-chip-core.yml @@ -149,6 +149,9 @@ jobs: # dependency with no riscv64 wheel is built in the Pigweed venv, which # has no maturin (or Rust) for cryptography's sdist. Take cryptography # (pinned to 43.0.1 by patch 0004) and its cffi from our registry. + # Patch 0005 also moves that venv's pip off CHIP's 23.2.1, which lists + # no manylinux_*_riscv64 tags and so can't see these wheels at all + # (gotchas 234/640). PIP_EXTRA_INDEX_URL: https://pypi.riseproject.dev/simple/ PIP_ONLY_BINARY: cryptography,cffi diff --git a/patches/home-assistant-chip-core/2025.7.0/0005-scripts-setup-constrain-pip-to-24.3.1.patch b/patches/home-assistant-chip-core/2025.7.0/0005-scripts-setup-constrain-pip-to-24.3.1.patch new file mode 100644 index 000000000000..527f3ba819b1 --- /dev/null +++ b/patches/home-assistant-chip-core/2025.7.0/0005-scripts-setup-constrain-pip-to-24.3.1.patch @@ -0,0 +1,42 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ludovic Henry +Date: Sun, 18 Oct 2026 00:00:00 +0000 +Subject: [PATCH] scripts/setup: constrain pip to 24.3.1 + +Upstream-Status: Inappropriate [riscv64 wheel availability: pip 23.2.1 lists no manylinux_*_riscv64 tags, so it can't install any riscv64 wheel] + +Pigweed's virtualenv setup upgrades the bootstrap venv's pip under +CHIP's constraints.txt, which pins pip==23.2.1. That pip vendors +packaging 21.3, whose manylinux arch allowlist has no riscv64, so on a +riscv64 host it reports only linux_riscv64 tags and treats every +manylinux_*_riscv64 wheel as incompatible. With cryptography taken as a +binary only (patch 0004, PIP_ONLY_BINARY), pip then finds no candidate +for cryptography==43.0.1, even though pypi.riseproject.dev serves it as +cp39-abi3-manylinux_2_35_riscv64, and the install of the generated +`pigweed` package fails with ResolutionImpossible. + +pip 24.1 is the first release whose vendored packaging (24.1) lists +riscv64. Pin 24.3.1, the version this Pigweed revision's own +python_base_requirements.txt pins and the one it already installs in +the GN build venv, which ignores constraints.txt for that step. + +Signed-off-by: Ludovic Henry +--- + scripts/setup/constraints.txt | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/scripts/setup/constraints.txt b/scripts/setup/constraints.txt +index 89cd541..2a95ba8 100644 +--- a/scripts/setup/constraints.txt ++++ b/scripts/setup/constraints.txt +@@ -277,7 +277,7 @@ wheel==0.38.4 ; sys_platform == "linux" + # pip-tools + + # The following packages are considered to be unsafe in a requirements file: +-pip==23.2.1 ++pip==24.3.1 + # via + # fastcore + # ghapi +-- +2.50.1 From c8295818264c9a7aaf66654ebb692698035887ac Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Sun, 18 Oct 2026 04:25:16 +0000 Subject: [PATCH 12/13] home-assistant-chip-core: install cairo-gobject-devel for chip-repl's pygobject Fixes build_wheels' pygobject==3.50.0 build (a home-assistant-chip-repl dependency): meson's cairo-gobject pkg-config/cmake probe reports NO, and pygi-foreign-cairo.c's #include then fails with "No such file or directory". cairo-devel alone doesn't ship this header or its .pc file; they're in the separate cairo-gobject-devel package. --- .github/workflows/build-home-assistant-chip-core.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-home-assistant-chip-core.yml b/.github/workflows/build-home-assistant-chip-core.yml index 6d4d1feecc22..9702baeea8e0 100644 --- a/.github/workflows/build-home-assistant-chip-core.yml +++ b/.github/workflows/build-home-assistant-chip-core.yml @@ -173,10 +173,12 @@ jobs: - name: Install system dependencies working-directory: ./ run: | + # cairo-gobject-devel ships cairo-gobject.h; chip-repl's pygobject==3.50.0 + # dependency needs it for its pygi-foreign-cairo.c Cairo integration. dnf install -y --enablerepo=crb zstd \ openssl-devel glib2-devel libnl3-devel cairo-devel \ - gobject-introspection-devel dbus-devel python3-devel \ - libstdc++-static + cairo-gobject-devel gobject-introspection-devel dbus-devel \ + python3-devel libstdc++-static git config --global --add safe.directory '*' echo "/opt/python/cp312-cp312/bin" >> "$GITHUB_PATH" From c6c1782dc50365ce78e7078dac4a5458a15c85a1 Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Sun, 18 Oct 2026 08:00:37 +0000 Subject: [PATCH 13/13] home-assistant-chip-core: publish only the chip-core wheel Fixes the publish job of run 39097039954, where _publish-wheel.yml's release step stopped with "Wheels contain mixed projects or versions": the wheelhouse held home_assistant_chip_core plus the home_assistant_chip_clusters and home_assistant_chip_repl wheels the CHIP build also emits. The publish workflow and update_doc.py publish exactly one project per run, and docs/packages/ only declares home-assistant-chip-core. Upstream already ships clusters and repl 2025.7.0 on PyPI as pure-Python py3-none-any wheels (Root-Is-Purelib, no extension module), so riscv64 installs them from PyPI with no port needed. Keep building and installing them for the unit tests, but stop copying them into the wheelhouse. --- .github/workflows/build-home-assistant-chip-core.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-home-assistant-chip-core.yml b/.github/workflows/build-home-assistant-chip-core.yml index 9702baeea8e0..35b24b446b7b 100644 --- a/.github/workflows/build-home-assistant-chip-core.yml +++ b/.github/workflows/build-home-assistant-chip-core.yml @@ -269,14 +269,19 @@ jobs: scripts/run_in_build_env.sh 'pip3 install ./out/controller/python/home_assistant_chip_repl-${{ env.CHIP_VERSION }}-py3-none-any.whl' scripts/run_in_build_env.sh '(cd src/controller/python/test/unit_tests/ && python3 -m unittest -v)' + # Only chip-core goes in the wheelhouse. The build also emits + # home_assistant_chip_clusters and home_assistant_chip_repl, which the + # unit tests above install, but those are separate PyPI projects that + # upstream already ships as pure-Python py3-none-any wheels (no + # extension, Root-Is-Purelib), so riscv64 installs them from PyPI as is. + # _publish-wheel.yml also publishes exactly one project per run and + # rejects a wheelhouse mixing project names. - name: Repair wheel run: | mkdir -p ../wheelhouse pip3 install auditwheel auditwheel repair -w ../wheelhouse --plat manylinux_2_39_riscv64 \ out/controller/python/home_assistant_chip_core-${{ env.CHIP_VERSION }}-cp37-abi3-manylinux_2_39_riscv64.whl - cp out/controller/python/home_assistant_chip_clusters-${{ env.CHIP_VERSION }}-py3-none-any.whl ../wheelhouse/ - cp out/controller/python/home_assistant_chip_repl-${{ env.CHIP_VERSION }}-py3-none-any.whl ../wheelhouse/ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: