Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 108 additions & 0 deletions .github/workflows/build-gemmi.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# SPDX-FileCopyrightText: 2026 The RISE Project
# SPDX-License-Identifier: MIT
---
# Based on the `build_wheels` job of
# https://github.com/project-gemmi/gemmi/blob/v0.7.5/.github/workflows/wheels2.yml
name: Build gemmi wheels (riscv64)

on:
workflow_dispatch:
inputs:
version:
description: 'gemmi version/tag to build (git tag without leading v, e.g. 0.7.5)'
required: true
default: '0.7.5'
pull_request:
paths:
- '.github/workflows/build-gemmi.yml'
- 'patches/gemmi/**'

concurrency:
group: ${{ github.workflow }}-${{ inputs.version || '0.7.5' }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true

permissions:
contents: read # to fetch code (actions/checkout)

env:
GEMMI_VERSION: ${{ inputs.version || '0.7.5' }}
MANYLINUX_RISCV64_IMAGE: quay.io/pypa/manylinux_2_39_riscv64
MUSLLINUX_RISCV64_IMAGE: quay.io/pypa/musllinux_1_2_riscv64

jobs:
setup:
uses: $/.github/workflows/_setup.yml

build_wheels:
needs: [setup]
name: Build gemmi ${{ inputs.version || '0.7.5' }} ${{ matrix.python }}-${{ matrix.libc }}_riscv64
runs-on: ubuntu-24.04-riscv
timeout-minutes: 120
strategy:
fail-fast: false
matrix:
python: ["cp312", "cp313", "cp314", "cp314t"]
libc: [manylinux, musllinux]

steps:
- name: Checkout gemmi v${{ env.GEMMI_VERSION }}
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: project-gemmi/gemmi
ref: v${{ env.GEMMI_VERSION }}
persist-credentials: false

- name: Checkout python-wheels
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
path: python-wheels
persist-credentials: false

# stb_sprintf.h has no riscv64 entry in its 64-bit-pointer-arch allowlist.
- name: Patch gemmi source
run: git apply python-wheels/patches/gemmi/${{ env.GEMMI_VERSION }}/00*.patch

- uses: pypa/cibuildwheel@1828c10ab37f080699c7b81cea34097c684a7074 # v4.2.0
env:
CIBW_ARCHS: riscv64
CIBW_BUILD: ${{ matrix.python }}-${{ matrix.libc }}_riscv64
CIBW_MANYLINUX_RISCV64_IMAGE: ${{ env.MANYLINUX_RISCV64_IMAGE }}
CIBW_MUSLLINUX_RISCV64_IMAGE: ${{ env.MUSLLINUX_RISCV64_IMAGE }}
# find_package(nanobind 2.4.0) in CMakeLists.txt rejects nanobind 3.x as
# incompatible; pyproject.toml's build-system.requires has no upper bound.
CIBW_BEFORE_ALL: echo 'nanobind<3' > /nanobind-constraint.txt
# The fetched zlib-ng's RVV chunkset/inflate kernels SIGILL on the first
# gzipped file gemmi reads; fall back to its portable C implementation.
CIBW_ENVIRONMENT: >-
SKBUILD_CMAKE_ARGS='-DBUILD_GEMMI_PROGRAM=OFF;-DINSTALL_DEV_FILES=OFF;-DBUILD_SHARED_LIBS=OFF;-DFETCH_ZLIB_NG=ON;-DWITH_RVV=OFF'
PIP_CONSTRAINT=/nanobind-constraint.txt
PIP_BUILD_CONSTRAINT=/nanobind-constraint.txt

- name: Check wheel contents
run: |
python3 - wheelhouse/*.whl <<'EOF'
import sys, zipfile
path = sys.argv[1]
names = zipfile.ZipFile(path).namelist()
exts = [n for n in names if n.endswith(".so")]
assert exts and all("gemmi_ext" in n for n in exts), exts
licences = {n.split(".dist-info/licenses/", 1)[1] for n in names
if ".dist-info/licenses/" in n and not n.endswith("/")}
assert licences == {"LICENSE.txt"}, licences
EOF

- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: gemmi-${{ env.GEMMI_VERSION }}-${{ matrix.python }}-${{ matrix.libc }}_riscv64
path: ./wheelhouse/*.whl
if-no-files-found: error

publish:
name: Publish gemmi ${{ inputs.version || '0.7.5' }}
needs: [setup, build_wheels]
permissions:
contents: write
pull-requests: write
uses: $/.github/workflows/_publish-wheel.yml
with:
artifact-pattern: gemmi-${{ inputs.version || '0.7.5' }}-*riscv64
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
From dadacda267c6a3078c80576a103e970b4ed59ffc Mon Sep 17 00:00:00 2001
From: Ludovic Henry <git@ludovic.dev>
Date: Sun, 6 Sep 2026 13:48:56 +0200
Subject: [PATCH] third_party: detect riscv64 as a 64-bit pointer arch in
stb_sprintf

stb_sprintf.h's stbsp__uintptr allowlist (__ppc64__, __aarch64__,
__x86_64__, __s390x__, ...) has no riscv64 entry, so it falls back to
a 32-bit unsigned int on a platform with 64-bit pointers. Every
(stbsp__uintptr)ptr alignment check in the file then narrows a
pointer to 32 bits, which GCC 14 rejects as a hard error (cast ...
loses precision [-fpermissive]) rather than a warning.

Add the same __riscv/__riscv_xlen==64 test glibc and the Linux kernel
use to detect riscv64, matching the pattern the file already uses for
every other LP64 architecture.

Upstream-Status: Inappropriate [gemmi vendors stb_sprintf.h directly with no submodule; the actual gap is in nothings/stb's stb_sprintf.h itself, which has no riscv64 detection and no riscv64 CI]
---
third_party/stb_sprintf.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/third_party/stb_sprintf.h b/third_party/stb_sprintf.h
index 28e9d64..4ce0ec9 100644
--- a/third_party/stb_sprintf.h
+++ b/third_party/stb_sprintf.h
@@ -230,7 +230,7 @@ STBSP__PUBLICDEC void STB_SPRINTF_DECORATE(set_separators)(char comma, char peri
#define stbsp__uint16 unsigned short

#ifndef stbsp__uintptr
-#if defined(__ppc64__) || defined(__powerpc64__) || defined(__aarch64__) || defined(_M_X64) || defined(__x86_64__) || defined(__x86_64) || defined(__s390x__)
+#if defined(__ppc64__) || defined(__powerpc64__) || defined(__aarch64__) || defined(_M_X64) || defined(__x86_64__) || defined(__x86_64) || defined(__s390x__) || (defined(__riscv) && __riscv_xlen == 64)
#define stbsp__uintptr stbsp__uint64
#else
#define stbsp__uintptr stbsp__uint32
--
2.50.1 (Apple Git-155)