Skip to content
Draft
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
177 changes: 177 additions & 0 deletions .github/workflows/build-panda3d.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
# SPDX-FileCopyrightText: 2026 The RISE Project
# SPDX-License-Identifier: MIT
---
# This workflow is based on the `makepanda` job of
# https://github.com/panda3d/panda3d/blob/v1.10.16/.github/workflows/ci.yml
name: Build panda3d wheels (riscv64)

on:
workflow_dispatch:
inputs:
version:
description: 'Version glob to (re)build; empty builds every version of docs/packages/panda3d.yaml not released yet'
required: false
default: ''
pull_request:
branches: [main]
paths:
- '.github/workflows/build-panda3d.yml'
- 'docs/packages/panda3d.yaml'
- 'patches/panda3d/**'
push:
branches: [main]
paths:
- '.github/workflows/build-panda3d.yml'
- 'docs/packages/panda3d.yaml'
- 'patches/panda3d/**'

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

permissions:
contents: read

env:
MANYLINUX_RISCV64_IMAGE: quay.io/pypa/manylinux_2_39_riscv64

jobs:
setup:
uses: $/.github/workflows/_setup.yml
with:
package: panda3d
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 panda3d ${{ matrix.version }} manylinux_riscv64
runs-on: ubuntu-24.04-riscv
timeout-minutes: 600

env:
PANDA3D_VERSION: ${{ matrix.version }}

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

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

- name: Apply riscv64 patches
run: git apply -v python-wheels/patches/panda3d/${{ env.PANDA3D_VERSION }}/*.patch

- name: Build and test wheels
run: |
mkdir -p wheelhouse
docker run --rm -i --network=host \
-v "$(pwd):/work" \
-w /work \
-e PANDA3D_VERSION \
"${MANYLINUX_RISCV64_IMAGE}" \
bash <<'SCRIPT'
set -eux

# Matches upstream's own Ubuntu apt-get list (build-essential bison flex
# libfreetype6-dev libgl1-mesa-dev libjpeg-dev libode-dev libopenal-dev
# libpng-dev libssl-dev libvorbis-dev libx11-dev libxcursor-dev
# libxrandr-dev nvidia-cg-toolkit zlib1g-dev), minus ode-devel (not
# packaged for Rocky 10), nvidia-cg-toolkit (x86-only, no riscv64
# build ever existed), and openal-soft-devel (EPEL-only on RHEL
# derivatives -- manylinux installs no EPEL on riscv64 -- and not
# present under any name in Rocky 10's own BaseOS/AppStream/CRB for
# riscv64 either) -- makepanda's SmartPkgEnable probes for each
# package and silently drops the feature (ODE physics, Cg shaders,
# OpenAL audio) rather than failing when one is missing, the same
# way it already does for Bullet on upstream's own Linux CI.
dnf install -y --setopt=install_weak_deps=False \
bison flex freetype-devel mesa-libGL-devel libjpeg-turbo-devel \
libpng-devel openssl-devel libvorbis-devel libogg-devel \
libX11-devel libXcursor-devel libXrandr-devel zlib-devel

for pydir in cp312-cp312 cp313-cp313 cp314-cp314 cp314-cp314t; do
PY="/opt/python/${pydir}/bin/python3"
"${PY}" makepanda/makepanda.py --everything --no-eigen --wheel \
--outputdir=built --version="${PANDA3D_VERSION}" \
--threads="$(nproc)" --verbose

whl=$(ls panda3d-*.whl)
mv "${whl}" wheelhouse/

"${PY}" -m venv /tmp/test-venv
/tmp/test-venv/bin/pip install -q "wheelhouse/${whl}" pytest
/tmp/test-venv/bin/python -m pytest -x -q
rm -rf /tmp/test-venv
done
SCRIPT

- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: panda3d-${{ env.PANDA3D_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 for panda3d ${{ matrix.version }}
runs-on: ubuntu-24.04-riscv

env:
PANDA3D_VERSION: ${{ matrix.version }}

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

# The engine is compiled with the image's GCC and links its libstdc++;
# freetype's Rocky 10 build resolves to its GPLv2 option (same as
# build-pygame.yml's freetype entry, from the same image).
- uses: ./actions/collect-gpl-sources
with:
image: ${{ env.MANYLINUX_RISCV64_IMAGE }}
packages: gcc freetype
output: gpl-sources.tar

- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: panda3d-${{ env.PANDA3D_VERSION }}-gpl-sources
path: gpl-sources.tar
if-no-files-found: error

publish:
name: Publish panda3d ${{ 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: panda3d-${{ matrix.version }}-manylinux_riscv64
gpl-sources-artifact: panda3d-${{ matrix.version }}-gpl-sources
gpl-sources-description: gcc and freetype
13 changes: 13 additions & 0 deletions docs/packages/panda3d.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package-name: panda3d
source-code: https://github.com/panda3d/panda3d
license: BSD-3-Clause
versions:
- version: 1.10.16
patched: true
comment: >-
makepanda's own --wheel platform-tag detection only recognizes
manylinux1/2010/2014/2_24/2_28 by checking for a specific glibc file that
quay.io/pypa/manylinux_2_39_riscv64 (Rocky 10) doesn't have; the patch adds a
branch keyed on the target arch instead. ODE physics and Cg shader support
are dropped (no riscv64 package for either), matching how upstream's own
Linux wheels already drop Bullet for the same reason.
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ludovic Henry <git@ludovic.dev>
Date: Mon, 21 Sep 2026 00:00:00 +0000
Subject: [PATCH] makepanda: detect manylinux_2_39_riscv64

makepanda.py's own PLATFORM detection (used for --wheel's platform tag)
recognizes manylinux1/2010/2014/2_24/2_28 by checking for a specific
versioned /lib64/libc-X.Y.so file plus, for 2_28, /etc/almalinux-release.
None of those checks can ever match quay.io/pypa/manylinux_2_39_riscv64
(Rocky 10): modern glibc no longer ships a libc-X.Y.so symlink at all, and
riscv64 isn't one of the arches any existing branch maps to a tag (the
2_28 branch's "else" even raises for an unrecognized arch). Detection
falls through to the generic, non-cross-compiling branch, which just
takes sysconfig.get_platform() verbatim ("linux-riscv64"), so --wheel
produces a plain linux_riscv64-tagged wheel instead of a manylinux one.

Add a branch keyed on the target arch instead of a libc filename, mirroring
the existing per-release branches' shape.

Upstream-Status: To upstream [not yet submitted; needs a riscv64 CI leg upstream doesn't have yet to validate against]

Signed-off-by: Ludovic Henry <git@ludovic.dev>
---
diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py
index ad6230f..c80e4c6 100755
--- a/makepanda/makepanda.py
+++ b/makepanda/makepanda.py
@@ -533,6 +533,12 @@ elif target == 'linux' and os.path.isfile("/lib64/libc-2.28.so") and os.path.isf
else:
raise RuntimeError('Unhandled arch %s, please file a bug report!' % (target_arch))

+elif target == 'linux' and target_arch == 'riscv64' and os.path.isdir("/opt/python"):
+ # manylinux_2_39_riscv64 (quay.io/pypa/manylinux_2_39_riscv64, Rocky 10): glibc
+ # no longer ships the versioned libc-X.Y.so file the checks above rely on, so
+ # detect this image by arch instead.
+ PLATFORM = 'manylinux_2_39-riscv64'
+
elif not CrossCompiling():
if HasTargetArch():
# Replace the architecture in the platform string.
Loading