Skip to content

Commit 64bdbb6

Browse files
committed
Switch to cibuildwheel for PyPI-compatible wheel building
Problem: PyPI rejected wheels with 'linux_x86_64' platform tag. PyPI requires manylinux tags for Linux wheels to ensure binary compatibility across distros. Solution: Replace custom build process with cibuildwheel, the industry standard for building cross-platform Python wheels. Changes: - Use pypa/cibuildwheel@v2.21 action instead of manual python -m build - Build on manylinux2014 containers for Linux (ensures PyPI compatibility) - Use auditwheel to repair wheels and embed shared libraries - Build for Python 3.12 on Linux x86_64 and macOS Intel (macos-13) - Install NEURON, MPI, and build dependencies in cibuildwheel environment - Update artifact names to match cibuildwheel output structure - Update test matrix to use macos-13 for consistency Benefits: - Wheels accepted by PyPI with proper manylinux tags - Better binary compatibility across Linux distributions - Automatic dependency bundling via auditwheel - Standard approach used by most Python packages
1 parent 81d8d1c commit 64bdbb6

2 files changed

Lines changed: 29 additions & 43 deletions

File tree

.github/workflows/build-wheels.yml

Lines changed: 27 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -19,61 +19,46 @@ jobs:
1919
runs-on: ${{ matrix.os }}
2020
strategy:
2121
matrix:
22-
# Only Linux has full NEURON support via pip
23-
# Windows requires manual NEURON installer
24-
os: [ubuntu-latest, macos-latest]
25-
python-version: ["3.12"]
22+
os: [ubuntu-latest, macos-13] # macos-13 for Intel, macos-latest for ARM
2623

2724
steps:
2825
- uses: actions/checkout@v4
2926

30-
- name: Set up Python ${{ matrix.python-version }}
31-
uses: actions/setup-python@v5
32-
with:
33-
python-version: ${{ matrix.python-version }}
27+
- name: Build wheels
28+
uses: pypa/cibuildwheel@v2.21
29+
env:
30+
# Only build for Python 3.12+
31+
CIBW_BUILD: "cp312-*"
3432

35-
- name: Install system dependencies (Ubuntu)
36-
if: runner.os == 'Linux'
37-
run: |
38-
sudo apt-get update
39-
sudo apt-get install -y \
40-
openmpi-bin openmpi-common libopenmpi-dev \
41-
librdmacm-dev libpsm2-dev \
42-
infiniband-diags ibverbs-utils libibverbs-dev \
43-
libfabric1 libfabric-dev \
44-
build-essential
33+
# Skip 32-bit builds and musl (Alpine) on Linux
34+
CIBW_SKIP: "*-win32 *-manylinux_i686 *-musllinux_*"
4535

46-
- name: Install system dependencies (macOS)
47-
if: runner.os == 'macOS'
48-
run: |
49-
brew install open-mpi
36+
# Install system dependencies before building (Linux)
37+
CIBW_BEFORE_ALL_LINUX: |
38+
yum install -y openmpi-devel || apt-get update && apt-get install -y libopenmpi-dev
5039
51-
- name: Install NEURON (Linux)
52-
if: runner.os == 'Linux'
53-
run: |
54-
python -m pip install --upgrade pip
55-
pip install neuron==8.2.7
40+
# Install system dependencies before building (macOS)
41+
CIBW_BEFORE_ALL_MACOS: |
42+
brew install open-mpi
5643
57-
- name: Install NEURON (macOS)
58-
if: runner.os == 'macOS'
59-
run: |
60-
python -m pip install --upgrade pip
61-
pip install neuron
44+
# Install Python build dependencies including NEURON
45+
CIBW_BEFORE_BUILD_LINUX: |
46+
pip install neuron==8.2.7 setuptools Cython numpy scipy
6247
48+
CIBW_BEFORE_BUILD_MACOS: |
49+
pip install neuron setuptools Cython numpy scipy
6350
64-
- name: Install build dependencies
65-
run: |
66-
python -m pip install build wheel setuptools Cython numpy scipy
51+
# Set manylinux image
52+
CIBW_MANYLINUX_X86_64_IMAGE: manylinux2014
6753

68-
- name: Build wheel
69-
run: |
70-
python -m build --wheel --outdir dist/
54+
# Repair wheel to embed shared libraries (Linux only)
55+
CIBW_REPAIR_WHEEL_COMMAND_LINUX: "auditwheel repair -w {dest_dir} {wheel}"
7156

7257
- name: Upload wheels
7358
uses: actions/upload-artifact@v4
7459
with:
75-
name: wheels-${{ matrix.os }}-py${{ matrix.python-version }}
76-
path: dist/*.whl
60+
name: wheels-${{ matrix.os }}
61+
path: wheelhouse/*.whl
7762
retention-days: 7
7863

7964
build_sdist:
@@ -108,7 +93,7 @@ jobs:
10893
runs-on: ${{ matrix.os }}
10994
strategy:
11095
matrix:
111-
os: [ubuntu-latest, macos-latest]
96+
os: [ubuntu-latest, macos-13]
11297
python-version: ["3.12"]
11398

11499
steps:
@@ -120,7 +105,7 @@ jobs:
120105
- name: Download wheels
121106
uses: actions/download-artifact@v4
122107
with:
123-
name: wheels-${{ matrix.os }}-py${{ matrix.python-version }}
108+
name: wheels-${{ matrix.os }}
124109
path: dist/
125110

126111
- name: Install system dependencies (Ubuntu)

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1616
- Platform-specific NMODL compilation for Linux (nrnivmodl) and Windows (mknrndll.bat)
1717
- No more manual `uv run poe setup_myogen` required for end users installing via pip
1818
- **CI/CD Workflow**: GitHub Actions workflow for automated wheel building and publishing
19-
- Automatic wheel building for Linux and macOS with pre-compiled NMODL mechanisms
19+
- Uses `cibuildwheel` for PyPI-compatible manylinux wheels (Linux) and universal wheels (macOS)
20+
- Automatic wheel building for Linux (x86_64) and macOS (Intel) with pre-compiled NMODL mechanisms
2021
- Multi-platform testing of built wheels before publishing
2122
- OIDC-based PyPI publishing (no API tokens needed)
2223
- Automated MPI/OpenMPI installation in CI for both Linux and macOS

0 commit comments

Comments
 (0)