Skip to content

Commit a52fc8d

Browse files
committed
fix(ci): place NVX .so at wheel root and fix PyPy ARM64 build
Two fixes for CI failures: 1. hatch_build.py: Place NVX .so files at WHEEL ROOT (not autobahn/nvx/) - CFFI creates top-level modules (e.g., "_nvx_utf8validator") - Python imports them as `import _nvx_utf8validator` (top-level) - When installed from wheel, the .so must be in site-packages root - This fixes: "RuntimeError: NVX native acceleration explicitly requested via AUTOBAHN_USE_NVX=1, but NVX modules are not available" 2. build-arm64-wheel.sh: Disable py-ubjson C extension for PyPy on ARM64 - The C extension segfaults (exit -11) under QEMU ARM64 emulation - py-ubjson works fine as pure Python under PyPy's JIT - Sets PYUBJSON_NO_EXTENSION=1 when building for PyPy Note: This work was completed with AI assistance (Claude Code).
1 parent d0bf026 commit a52fc8d

File tree

2 files changed

+15
-11
lines changed

2 files changed

+15
-11
lines changed

.github/scripts/build-arm64-wheel.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,14 @@ echo "auditwheel: $(auditwheel --version || echo 'not available')"
5050
# nh3 is a Rust package (indirect dep of twine) that segfaults under QEMU
5151
export AUTOBAHN_USE_NVX=1
5252

53+
# Disable py-ubjson C extension for PyPy on ARM64
54+
# The C extension build segfaults under QEMU ARM64 emulation (exit code -11)
55+
# py-ubjson works fine as pure Python under PyPy's JIT
56+
if python3 -c "import platform; exit(0 if 'pypy' in platform.python_implementation().lower() else 1)" 2>/dev/null; then
57+
echo "==> PyPy detected: disabling py-ubjson C extension (QEMU ARM64 incompatible)"
58+
export PYUBJSON_NO_EXTENSION=1
59+
fi
60+
5361
# Build only specified Python versions (or all if not specified)
5462
if [ -n "$PYTHON_VERSIONS" ]; then
5563
echo "==> Building wheels for specific Python versions: $PYTHON_VERSIONS"

hatch_build.py

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -110,22 +110,18 @@ def _build_cffi_modules(self, build_data):
110110

111111
# Find the compiled artifact matching CURRENT Python and add to build_data
112112
# Only include .so files that match the current interpreter's extension suffix
113+
#
114+
# IMPORTANT: The .so files must be placed at the WHEEL ROOT (not in autobahn/nvx/)
115+
# because CFFI creates top-level modules (e.g., "_nvx_utf8validator")
116+
# and the Python code does `import _nvx_utf8validator` (top-level import).
113117
for artifact in nvx_dir.glob("_nvx_*" + ext_suffix):
114118
src_file = str(artifact)
115-
dest_path = f"autobahn/nvx/{artifact.name}"
119+
# Place at wheel root for top-level import
120+
dest_path = artifact.name
116121
build_data["force_include"][src_file] = dest_path
117-
print(f" -> Added artifact: {artifact.name} -> {dest_path}")
122+
print(f" -> Added artifact: {artifact.name} -> {dest_path} (wheel root)")
118123
built_any = True
119124

120-
# Handle Windows .pyd files
121-
if ext_suffix.endswith(".pyd"):
122-
for artifact in nvx_dir.glob("_nvx_*" + ext_suffix):
123-
src_file = str(artifact)
124-
dest_path = f"autobahn/nvx/{artifact.name}"
125-
build_data["force_include"][src_file] = dest_path
126-
print(f" -> Added artifact: {artifact.name} -> {dest_path}")
127-
built_any = True
128-
129125
except Exception as e:
130126
print(f"Warning: Could not build {module_file}: {e}")
131127
import traceback

0 commit comments

Comments
 (0)