Skip to content

Commit 9fc91be

Browse files
authored
Merge pull request #233 from larsoner/abi3
MAINT: Build abi3 wheels and use native arm64 Linux
2 parents baa9d6e + 8dee24e commit 9fc91be

File tree

4 files changed

+79
-66
lines changed

4 files changed

+79
-66
lines changed

.github/workflows/wheels.yml

Lines changed: 8 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -15,26 +15,6 @@ concurrency:
1515
cancel-in-progress: true
1616

1717
jobs:
18-
job_metadata:
19-
runs-on: ubuntu-latest
20-
outputs:
21-
commit_message: ${{ steps.get_commit_message.outputs.commit_message }}
22-
steps:
23-
- name: Checkout
24-
uses: actions/checkout@v5
25-
with:
26-
fetch-depth: 2
27-
- name: Print head git commit message
28-
id: get_commit_message
29-
run: |
30-
if [[ -z "$COMMIT_MSG" ]]; then
31-
COMMIT_MSG=$(git show -s --format=%s $REF)
32-
fi
33-
echo commit_message=$COMMIT_MSG | tee -a $GITHUB_OUTPUT
34-
env:
35-
COMMIT_MSG: ${{ github.event.head_commit.message }}
36-
REF: ${{ github.event.pull_request.head.sha }}
37-
3818
build-sdist:
3919
name: Build sdist
4020
runs-on: ubuntu-latest
@@ -50,47 +30,32 @@ jobs:
5030
path: ./dist/*.tar.gz
5131

5232
build-wheel:
53-
name: Build wheel for ${{ matrix.python }}-${{ matrix.buildplat[1] }}
54-
needs: [job_metadata]
33+
name: Build wheel for ${{ matrix.buildplat[1] }}
5534
runs-on: ${{ matrix.buildplat[0] }}
56-
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') || contains(needs.job_metadata.outputs.commit_message, '[build wheels]')
5735
strategy:
5836
fail-fast: false
5937
matrix:
6038
buildplat:
6139
- [ubuntu-latest, musllinux_x86_64]
62-
- [ubuntu-latest, manylinux_aarch64]
63-
- [macos-15-intel, macosx_x86_64] # native Intel hardware
40+
- [ubuntu-latest, manylinux_x86_64]
41+
- [ubuntu-24.04-arm, manylinux_aarch64]
42+
- [macos-latest, macosx_arm64]
43+
- [macos-15-intel, macosx_x86_64]
6444
- [windows-latest, win_amd64]
65-
python: ["cp310", "cp311", "cp312", "cp313", "cp314"]
66-
include:
67-
# Manylinux and arm64 builds (on native hardware) are cheap, do all in one
68-
- { buildplat: ["ubuntu-latest", "manylinux_x86_64"], python: "*" }
69-
- { buildplat: ["macos-14", "macosx_arm64"], python: "*" }
7045

7146
steps:
7247
- uses: actions/checkout@v5
7348
with:
7449
fetch-depth: 0
7550

76-
- name: Install the latest version of uv
77-
uses: astral-sh/setup-uv@v6
78-
79-
# For aarch64 support
80-
# https://cibuildwheel.pypa.io/en/stable/faq/#emulation
81-
- uses: docker/setup-qemu-action@v3
82-
with:
83-
platforms: all
84-
if: runner.os == 'Linux' && endsWith(matrix.buildplat[1], 'aarch64')
85-
8651
- name: Build wheel(s)
87-
run: uvx cibuildwheel
52+
uses: pypa/cibuildwheel@v3.2.1
8853
env:
89-
CIBW_BUILD: ${{ matrix.python }}-${{ matrix.buildplat[1] }}
54+
CIBW_BUILD: "cp310-${{ matrix.buildplat[1] }} cp311-${{ matrix.buildplat[1] }} "
9055

9156
- uses: actions/upload-artifact@v5
9257
with:
93-
name: ${{ matrix.python == '*' && 'all' || matrix.python }}-${{ startsWith(matrix.buildplat[1], 'macosx') && 'macosx' || matrix.buildplat[1] }}-dist
58+
name: ${{ matrix.buildplat[1] }}-dist
9459
path: ./wheelhouse/*.whl
9560

9661
test-sdist:

pyproject.toml

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,19 +64,37 @@ test = [
6464
[tool.cibuildwheel]
6565
# Disable PyPy
6666
skip = "pp*"
67-
67+
# 3.11 is abi3
68+
build = "cp310-* cp311-*"
6869
# 64-bit builds only; 32-bit builds seem pretty niche these days, so
6970
# don't bother unless someone asks
7071
archs = ["native"]
71-
72+
before-build = "pip install abi3audit"
7273
test-requires = [
7374
"pytest",
7475
"nitime[full]", # Enable all optional behavior
7576
]
7677
test-command = "pytest -rsx --pyargs nitime"
7778

7879
[tool.cibuildwheel.linux]
79-
archs = ["x86_64", "aarch64"]
80+
repair-wheel-command = [
81+
"auditwheel repair -w {dest_dir} {wheel}",
82+
"bash tools/audit_wheel.sh {wheel}",
83+
]
84+
85+
[tool.cibuildwheel.macos]
86+
archs = ["native"]
87+
repair-wheel-command = [
88+
"delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel}",
89+
"bash tools/audit_wheel.sh {wheel}",
90+
]
91+
92+
[tool.cibuildwheel.windows]
93+
before-build = "pip install delvewheel abi3audit"
94+
repair-wheel-command = [
95+
"delvewheel repair -w {dest_dir} {wheel}",
96+
"bash tools/audit_wheel.sh {wheel}",
97+
]
8098

8199
[tool.pytest.ini_options]
82100
minversion = "8"

setup.py

Lines changed: 41 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,47 @@
44
This file only contains cython components.
55
See pyproject.toml for the remaining configuration.
66
"""
7-
from setuptools import setup
8-
9-
try:
10-
from setuptools import Extension
11-
from Cython.Build import cythonize
12-
from numpy import get_include
13-
14-
# add Cython extensions to the setup options
15-
exts = [
16-
Extension(
17-
'nitime._utils',
18-
['nitime/_utils.pyx'],
19-
include_dirs=[get_include()],
20-
define_macros=[('NPY_NO_DEPRECATED_API', 'NPY_1_7_API_VERSION')],
21-
)
22-
]
23-
opts = {'ext_modules': cythonize(exts, language_level='3')}
24-
except ImportError:
25-
# no loop for you!
26-
opts = {}
7+
import platform
8+
import sys
9+
10+
from Cython.Build import cythonize
11+
from numpy import get_include
12+
from setuptools import setup, Extension
13+
from wheel.bdist_wheel import bdist_wheel
14+
15+
# add Cython extensions to the setup options
16+
17+
18+
# https://github.com/joerick/python-abi3-package-sample/blob/main/setup.py
19+
class bdist_wheel_abi3(bdist_wheel): # noqa: D101
20+
def get_tag(self): # noqa: D102
21+
python, abi, plat = super().get_tag()
22+
23+
if python.startswith("cp"):
24+
return "cp311", "abi3", plat
25+
26+
return python, abi, plat
27+
28+
29+
macros = [('NPY_NO_DEPRECATED_API', 'NPY_1_7_API_VERSION')]
30+
ext_kwargs = {}
31+
setup_kwargs = {}
32+
if sys.version_info.minor >= 11 and platform.python_implementation() == "CPython":
33+
# Can create an abi3 wheel (typed memoryviews first available in 3.11)!
34+
macros.append(("Py_LIMITED_API", "0x030B0000"))
35+
ext_kwargs["py_limited_api"] = True
36+
setup_kwargs["cmdclass"] = {"bdist_wheel": bdist_wheel_abi3}
37+
38+
39+
exts = [
40+
Extension(
41+
'nitime._utils',
42+
['nitime/_utils.pyx'],
43+
include_dirs=[get_include()],
44+
define_macros=macros,
45+
)
46+
]
47+
opts = {'ext_modules': cythonize(exts, language_level='3'), **setup_kwargs}
2748

2849
# Now call the actual setup function
2950
if __name__ == '__main__':

tools/audit_wheel.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#!/bin/bash -eo pipefail
2+
set -x
3+
4+
PY_MINOR=$(python -c "import sys; print(sys.version_info.minor)")
5+
if [ "$PY_MINOR" -lt 11 ]; then
6+
echo "Not checking abi3audit for Python $PY_MINOR < 3.11"
7+
exit 0
8+
fi
9+
abi3audit --strict --report --verbose "$1"

0 commit comments

Comments
 (0)