From c32b60fc314a6fed86df5863afc905c5f1da6d6f Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Tue, 13 Oct 2026 13:23:33 +0000 Subject: [PATCH 1/2] Add riscv64 wheel build for openbabel-wheel 3.1.1.23 Open Babel's own CMake/C++ source has no x86-specific code (checked src/, src/formats/libinchi/ and the build scripts); upstream's pyproject.toml already builds linux_aarch64 wheels with the same cibuildwheel recipe, and swig/cmeel-eigen (the two build-time deps) both ship riscv64-portable wheels on PyPI already. Only the Linux before-all is overridden, installing cairo-devel from the (modern) Rocky 10 image instead of building cairo 1.15.14 from source the way upstream does to work around manylinux2014's broken CentOS cairo-devel. --- .github/workflows/build-openbabel-wheel.yml | 107 ++++++++++++++++++++ docs/packages/openbabel-wheel.yaml | 5 + 2 files changed, 112 insertions(+) create mode 100644 .github/workflows/build-openbabel-wheel.yml create mode 100644 docs/packages/openbabel-wheel.yaml diff --git a/.github/workflows/build-openbabel-wheel.yml b/.github/workflows/build-openbabel-wheel.yml new file mode 100644 index 000000000000..b614ba8041d6 --- /dev/null +++ b/.github/workflows/build-openbabel-wheel.yml @@ -0,0 +1,107 @@ +# SPDX-FileCopyrightText: 2026 The RISE Project +# SPDX-License-Identifier: MIT +--- +# pyproject.toml's own [tool.cibuildwheel] table (build-command, cmake defines, the +# cp312-cp314t matrix, the forcefield/obabel test-command) is used as-is; only the +# riscv64 image and the Linux native deps (replacing the manylinux2014 before-all at +# https://github.com/njzjz/openbabel-wheel/blob/v3.1.1.23/pyproject.toml) are overridden +# here. +name: Build openbabel-wheel wheels (riscv64) + +on: + workflow_dispatch: + inputs: + version: + description: 'Version glob to (re)build; empty builds every version of docs/packages/openbabel-wheel.yaml not released yet' + required: false + default: '' + pull_request: + branches: [main] + paths: + - '.github/workflows/build-openbabel-wheel.yml' + - 'docs/packages/openbabel-wheel.yaml' + push: + branches: [main] + paths: + - '.github/workflows/build-openbabel-wheel.yml' + - 'docs/packages/openbabel-wheel.yaml' + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +permissions: + contents: read # to fetch code (actions/checkout) + +env: + MANYLINUX_RISCV64_IMAGE: quay.io/pypa/manylinux_2_39_riscv64 + +jobs: + setup: + uses: $/.github/workflows/_setup.yml + with: + package: openbabel-wheel + version: ${{ inputs.version }} + + build_wheels: + needs: [setup] + if: needs.setup.outputs.versions != '[]' + name: Build openbabel-wheel ${{ matrix.version }} ${{ matrix.python }}-manylinux_riscv64 + runs-on: ubuntu-24.04-riscv + strategy: + fail-fast: false + matrix: + version: ${{ fromJSON(needs.setup.outputs.versions) }} + python: + - "cp312" + - "cp313" + - "cp314" + - "cp314t" + + env: + OPENBABEL_WHEEL_VERSION: ${{ matrix.version }} + + steps: + - name: Checkout openbabel-wheel ${{ env.OPENBABEL_WHEEL_VERSION }} + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + repository: njzjz/openbabel-wheel + ref: v${{ env.OPENBABEL_WHEEL_VERSION }} + persist-credentials: false + + - name: Build wheels + uses: pypa/cibuildwheel@1828c10ab37f080699c7b81cea34097c684a7074 # v4.2.0 + with: + output-dir: wheelhouse/ + only: ${{ matrix.python }}-manylinux_riscv64 + env: + CIBW_MANYLINUX_RISCV64_IMAGE: ${{ env.MANYLINUX_RISCV64_IMAGE }} + # manylinux2014's cairo-devel is too old for OpenBabel's depiction code, + # which is why upstream builds cairo 1.15.14 from source instead; Rocky 10 + # (this image) ships a current one, so installing it directly is simpler + # and the other libraries it names (freetype/libpng/pixman) come in as its + # dependencies. + CIBW_BEFORE_ALL_LINUX: dnf install -y libxml2-devel zlib-devel cairo-devel + + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: openbabel-wheel-${{ env.OPENBABEL_WHEEL_VERSION }}-${{ matrix.python }}-manylinux_riscv64 + path: wheelhouse/*.whl + if-no-files-found: error + + publish: + name: Publish openbabel-wheel ${{ matrix.version }} + needs: [setup, build_wheels] + 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: openbabel-wheel-${{ matrix.version }}-*-manylinux_riscv64 diff --git a/docs/packages/openbabel-wheel.yaml b/docs/packages/openbabel-wheel.yaml new file mode 100644 index 000000000000..a0fadc292319 --- /dev/null +++ b/docs/packages/openbabel-wheel.yaml @@ -0,0 +1,5 @@ +package-name: openbabel-wheel +source-code: https://github.com/njzjz/openbabel-wheel +license: GPL-2.0-only +versions: +- version: 3.1.1.23 From d8e6b85437f816aa3621db0d895c278213156199 Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Fri, 16 Oct 2026 01:07:33 +0000 Subject: [PATCH 2/2] openbabel-wheel: patch the dropped cpython-freethreading enable group All four riscv64 build legs fail in ~1 minute with cibuildwheel: 'Failed to parse enable group. Unknown enable group: cpython-freethreading.' pyproject.toml's [tool.cibuildwheel] table sets enable = ["cpython-freethreading"], which was cibuildwheel's opt-in for free-threaded wheels; the value was deprecated in cibuildwheel 3.4.1 and removed outright in 4.0.0 (CPython 3.14+ free-threaded builds no longer need an enable flag). This repo pins cibuildwheel 4.2.0, which parses the whole [tool.cibuildwheel] table up front and rejects it before selecting any interpreter or starting a container, so every matrix leg fails identically and fast. Upstream's own release workflow still pins cibuildwheel v3.3, where the option remains valid, so their tag isn't broken for them. Carry a one-line patch dropping the enable entry (porting-playbook gotcha 184), tagged Upstream-Status: To upstream since no later upstream release has fixed this yet. --- .github/workflows/build-openbabel-wheel.yml | 16 +++++++-- docs/packages/openbabel-wheel.yaml | 1 + ...d-cpython-freethreading-enable-group.patch | 36 +++++++++++++++++++ 3 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 patches/openbabel-wheel/3.1.1.23/0001-pyproject-drop-the-removed-cpython-freethreading-enable-group.patch diff --git a/.github/workflows/build-openbabel-wheel.yml b/.github/workflows/build-openbabel-wheel.yml index b614ba8041d6..46bb8f58f62d 100644 --- a/.github/workflows/build-openbabel-wheel.yml +++ b/.github/workflows/build-openbabel-wheel.yml @@ -2,8 +2,9 @@ # SPDX-License-Identifier: MIT --- # pyproject.toml's own [tool.cibuildwheel] table (build-command, cmake defines, the -# cp312-cp314t matrix, the forcefield/obabel test-command) is used as-is; only the -# riscv64 image and the Linux native deps (replacing the manylinux2014 before-all at +# cp312-cp314t matrix, the forcefield/obabel test-command) is used as-is apart from the +# patch below; only the riscv64 image and the Linux native deps (replacing the +# manylinux2014 before-all at # https://github.com/njzjz/openbabel-wheel/blob/v3.1.1.23/pyproject.toml) are overridden # here. name: Build openbabel-wheel wheels (riscv64) @@ -20,11 +21,13 @@ on: paths: - '.github/workflows/build-openbabel-wheel.yml' - 'docs/packages/openbabel-wheel.yaml' + - 'patches/openbabel-wheel/**' push: branches: [main] paths: - '.github/workflows/build-openbabel-wheel.yml' - 'docs/packages/openbabel-wheel.yaml' + - 'patches/openbabel-wheel/**' concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} @@ -69,6 +72,15 @@ jobs: ref: v${{ env.OPENBABEL_WHEEL_VERSION }} persist-credentials: false + - name: Checkout python-wheels + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + path: python-wheels + persist-credentials: false + + - name: Patch openbabel-wheel source + run: git apply python-wheels/patches/openbabel-wheel/${{ env.OPENBABEL_WHEEL_VERSION }}/*.patch + - name: Build wheels uses: pypa/cibuildwheel@1828c10ab37f080699c7b81cea34097c684a7074 # v4.2.0 with: diff --git a/docs/packages/openbabel-wheel.yaml b/docs/packages/openbabel-wheel.yaml index a0fadc292319..94576fb595e3 100644 --- a/docs/packages/openbabel-wheel.yaml +++ b/docs/packages/openbabel-wheel.yaml @@ -3,3 +3,4 @@ source-code: https://github.com/njzjz/openbabel-wheel license: GPL-2.0-only versions: - version: 3.1.1.23 + patched: true diff --git a/patches/openbabel-wheel/3.1.1.23/0001-pyproject-drop-the-removed-cpython-freethreading-enable-group.patch b/patches/openbabel-wheel/3.1.1.23/0001-pyproject-drop-the-removed-cpython-freethreading-enable-group.patch new file mode 100644 index 000000000000..58ad72fc1983 --- /dev/null +++ b/patches/openbabel-wheel/3.1.1.23/0001-pyproject-drop-the-removed-cpython-freethreading-enable-group.patch @@ -0,0 +1,36 @@ +From 178b5b8ed98042762e011b9f321fd19a50d43a86 Mon Sep 17 00:00:00 2001 +From: Ludovic Henry +Date: Fri, 16 Oct 2026 01:05:08 +0000 +Subject: [PATCH] pyproject: drop the removed cpython-freethreading enable + group + +cibuildwheel 4.2.0 (the version this repo pins for riscv64 builds) no +longer recognises "cpython-freethreading" as an enable group -- it +errors "Failed to parse enable group" before any build starts, on +every interpreter, since [tool.cibuildwheel] is parsed as a whole. +The enable value was deprecated in cibuildwheel 3.4.1 and removed +outright in 4.0.0 (CPython 3.14+ free-threaded wheels build without +any enable flag now); upstream's own release workflow still pins +cibuildwheel v3.3, where the option remains valid, so the tag is not +broken for them yet. + +Upstream-Status: To upstream [not yet submitted] +--- + pyproject.toml | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/pyproject.toml b/pyproject.toml +index f624e43..4ea0758 100644 +--- a/pyproject.toml ++++ b/pyproject.toml +@@ -76,7 +76,6 @@ test-command = [ + ] + build = ["cp38-*", "cp39-*", "cp310-*", "cp311-*", "cp312-*", "cp313-*", "cp313t-*", "cp314-*", "cp314t-*"] + skip = ["*-win32", "*-manylinux_i686", "*-musllinux*", "cp314t-win_amd64"] +-enable = ["cpython-freethreading"] + manylinux-x86_64-image = "manylinux2014" + manylinux-aarch64-image = "manylinux2014" + +-- +2.43.0 +