diff --git a/.github/workflows/build-cppyy-cling.yml b/.github/workflows/build-cppyy-cling.yml new file mode 100644 index 000000000000..891f6dac8a11 --- /dev/null +++ b/.github/workflows/build-cppyy-cling.yml @@ -0,0 +1,131 @@ +# SPDX-FileCopyrightText: 2026 The RISE Project +# SPDX-License-Identifier: MIT +--- +# This workflow is based on: https://github.com/wlav/cppyy-backend/blob/cppyy-cling-6.32.8/.github/workflows/cling-wheels.yml +name: Build cppyy-cling wheels (riscv64) + +on: + workflow_dispatch: + inputs: + version: + description: 'Version glob to (re)build; empty builds every version of docs/packages/cppyy-cling.yaml not released yet' + required: false + default: '' + pull_request: + branches: [main] + paths: + - '.github/workflows/build-cppyy-cling.yml' + - 'docs/packages/cppyy-cling.yaml' + - 'patches/cppyy-cling/**' + push: + branches: [main] + paths: + - '.github/workflows/build-cppyy-cling.yml' + - 'docs/packages/cppyy-cling.yaml' + - 'patches/cppyy-cling/**' + +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 + WHEEL_PLATFORM_TAG: manylinux_2_39_riscv64 + +jobs: + setup: + uses: $/.github/workflows/_setup.yml + with: + package: cppyy-cling + version: ${{ inputs.version }} + + build_wheels: + needs: [setup] + if: needs.setup.outputs.versions != '[]' + strategy: + fail-fast: false + matrix: + version: ${{ fromJSON(needs.setup.outputs.versions) }} + name: Build cppyy-cling ${{ matrix.version }} py2.py3-none-manylinux_riscv64 + runs-on: ubuntu-24.04-riscv + timeout-minutes: 1440 # full LLVM/Clang + Cling build from source + + env: + CPPYY_CLING_VERSION: ${{ matrix.version }} + + steps: + - name: Checkout cppyy-backend cppyy-cling-${{ env.CPPYY_CLING_VERSION }} + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + repository: wlav/cppyy-backend + ref: cppyy-cling-${{ env.CPPYY_CLING_VERSION }} + path: cppyy-backend + persist-credentials: false + + - name: Checkout python-wheels + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + path: python-wheels + persist-credentials: false + + - name: Apply patches + working-directory: cppyy-backend + run: git apply -v ../python-wheels/patches/cppyy-cling/${{ env.CPPYY_CLING_VERSION }}/*.patch + + # Upstream's own cibuildwheel config runs this as `before-all`; it pulls + # ROOT's release source tarball from root.cern.ch and copies its + # interpreter/ subtree (Cling + the LLVM/Clang monorepo) into cling/src. + - name: Fetch Cling's ROOT source tree + working-directory: cppyy-backend/cling + run: python3 create_src_directory.py + + - name: Pull manylinux_riscv64 image + run: docker pull "${MANYLINUX_RISCV64_IMAGE}" + + - name: Build the wheel + run: | + docker run --rm -v "$(pwd)/cppyy-backend/cling:/work" -w /work \ + -e WHEEL_PLATFORM_TAG \ + "${MANYLINUX_RISCV64_IMAGE}" bash -c ' + set -euxo pipefail + pybin=/opt/python/cp312-cp312/bin + # setup.py does `import distutils`, removed from the stdlib in 3.12; + # setuptools (unlike wheel alone) installs the shim that resolves it. + "$pybin/pip" install -q -U setuptools wheel + # AUDITWHEEL_PLAT/_PYTHON_HOST_PLATFORM: setup.py only recognizes + # manylinux1/2010/2014 by /etc/redhat-release (gotcha patch 1); set + # the former so it builds Release (not debug-laden RelWithDebInfo) + # like every other published platform, and the latter is what the + # custom bdist_wheel command (via distutils get_platform()) tags + # the wheel with. + AUDITWHEEL_PLAT="${WHEEL_PLATFORM_TAG}" _PYTHON_HOST_PLATFORM="${WHEEL_PLATFORM_TAG}" \ + "$pybin/python3" setup.py bdist_wheel + "$pybin/pip" install -q dist/*.whl + "$pybin/python3" -c "import cppyy_backend" + ' + + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: cppyy-cling-${{ env.CPPYY_CLING_VERSION }}-py2.py3-none-manylinux_riscv64 + path: cppyy-backend/cling/dist/*.whl + if-no-files-found: error + + publish: + name: Publish cppyy-cling ${{ 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: cppyy-cling-${{ matrix.version }}-*-manylinux_riscv64 diff --git a/docs/packages/cppyy-cling.yaml b/docs/packages/cppyy-cling.yaml new file mode 100644 index 000000000000..8074e9ee3311 --- /dev/null +++ b/docs/packages/cppyy-cling.yaml @@ -0,0 +1,5 @@ +package-name: cppyy-cling +source-code: https://github.com/wlav/cppyy-backend +license: 'LLVM/Cling: University of Illinois/NCSA Open Source License; ROOT: LGPL 2.1' +versions: +- version: 6.32.8 diff --git a/patches/cppyy-cling/6.32.8/0001-setup-recognize-current-generation-manylinux-images.patch b/patches/cppyy-cling/6.32.8/0001-setup-recognize-current-generation-manylinux-images.patch new file mode 100644 index 000000000000..44a686888a08 --- /dev/null +++ b/patches/cppyy-cling/6.32.8/0001-setup-recognize-current-generation-manylinux-images.patch @@ -0,0 +1,48 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ludovic Henry +Date: Thu, 15 Oct 2026 06:29:40 +0000 +Subject: [PATCH] setup: recognize current-generation manylinux images + +Upstream-Status: To upstream [not yet submitted; generalizes a check that predates manylinux_2_28+] + +is_manylinux() only recognizes manylinux1/manylinux2010/manylinux2014 by +matching three hardcoded /etc/redhat-release strings (CentOS 5.11/6.10/ +7.9.2009). quay.io/pypa/manylinux_2_39_riscv64 (this repo's riscv64 image, +PEP 600) is Rocky Linux 10-based and matches none of them, so +is_manylinux() silently returns False inside it. That flag drives two +decisions in my_cmake_build.run(): the CMake build type (Release vs. +RelWithDebInfo, the latter keeping full debug info -- "too large for +wheels" per this same file's own comment) and the default STDCXX (17 vs. +20), plus my_install.run()'s cxxversion-advertising rewrite ("reset the +default cxxversion to 20 if no user override" on real manylinux builds). +Misdetecting manylinux here would ship a riscv64 wheel built differently +(bigger, debug-laden, and advertising a C++ standard it wasn't actually +built with) from every other published platform. + +All pypa/manylinux images, including the newer PEP 600 (_2_28/_2_34/ +_2_39) generations, bake in AUDITWHEEL_PLAT (the policy auditwheel itself +targets, e.g. manylinux_2_39_riscv64) -- a stable, generation-independent +marker. Check it first and keep the existing string match as a fallback +for the images it already recognized. + +Signed-off-by: Ludovic Henry +--- + cling/setup.py | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/cling/setup.py b/cling/setup.py +index d7826bf..8dbdf4e 100755 +--- a/cling/setup.py ++++ b/cling/setup.py +@@ -44,6 +44,11 @@ def is_manylinux(): + global _is_manylinux + if _is_manylinux is None: + _is_manylinux = False ++ # all pypa/manylinux images, including the PEP 600 generations that ++ # post-date the CentOS-release checks below, export this. ++ if os.environ.get('AUDITWHEEL_PLAT', '').startswith('manylinux'): ++ _is_manylinux = True ++ return _is_manylinux + try: + for line in open('/etc/redhat-release').readlines(): + # mark manylinux1, manylinux2010, or manylinux2014 diff --git a/patches/cppyy-cling/6.32.8/0002-setup-scope-llvm-targets-to-build-on-riscv64-linux.patch b/patches/cppyy-cling/6.32.8/0002-setup-scope-llvm-targets-to-build-on-riscv64-linux.patch new file mode 100644 index 000000000000..91957ab65cce --- /dev/null +++ b/patches/cppyy-cling/6.32.8/0002-setup-scope-llvm-targets-to-build-on-riscv64-linux.patch @@ -0,0 +1,44 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ludovic Henry +Date: Thu, 15 Oct 2026 06:30:19 +0000 +Subject: [PATCH] setup: scope LLVM targets to build on riscv64 linux + +Upstream-Status: To upstream [not yet submitted; mirrors the existing macOS arm64 branch below it] + +my_cmake_build.run() never passes -DLLVM_TARGETS_TO_BUILD on Linux (only +macOS arm64 and Windows get an explicit value); src/interpreter/ +CMakeLists.txt does have a `ROOT_ARCHITECTURE MATCHES riscv64` branch that +would set it to "RISCV;NVPTX", the same shape as its AArch64/ARM/PowerPC/ +SystemZ branches, but ROOT_ARCHITECTURE is never set in this cling-only +build (src/CMakeLists.txt never include()s ROOT's SetUpLinux.cmake), so +that branch is unreachable and dispatch falls through to the "all" case: +every LLVM backend (x86, arm, aarch64, powerpc, systemz, riscv, ...), not +just the one the build runs on. That turns an already multi-hour +from-source LLVM+Clang+Cling build into one compiling backends that can +never be used on this host. + +LLVM_TARGETS_TO_BUILD is a CACHE variable; src/interpreter/CMakeLists.txt +only set()s it (no FORCE), so a value supplied on the cmake command line +-- as this patch adds -- wins over that fallback, the same way the macOS +arm64 branch immediately above already overrides it for that platform. + +Signed-off-by: Ludovic Henry +--- + cling/setup.py | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/cling/setup.py b/cling/setup.py +index 8dbdf4e..d390f5b 100755 +--- a/cling/setup.py ++++ b/cling/setup.py +@@ -169,6 +169,10 @@ class my_cmake_build(_build): + import platform + if 'arm64' in platform.machine(): + CMAKE_COMMAND += ['-DLLVM_TARGETS_TO_BUILD=ARM;AArch64;NVPTX'] ++ elif 'linux' in sys.platform: ++ import platform ++ if 'riscv64' in platform.machine(): ++ CMAKE_COMMAND += ['-DLLVM_TARGETS_TO_BUILD=RISCV;NVPTX'] + CMAKE_COMMAND.append('-DCMAKE_INSTALL_PREFIX='+prefix) + + log.info('Running cmake for cppyy-cling: %s', ' '.join(CMAKE_COMMAND))