🎡 cibuildwheel 4.0

cibuildwheel 4.0.0 is out, with some very big additions. We’ve added pyemscripten 3.13 wheels (uploadable to PyPI!), Python 3.15 (and 3.15t) betas, and much more! We’ve got a new stage: audit, which applies abi3audit to stable ABI wheels. We now default to running delvewheel to repair Windows wheels. We now have {project} and {package} placeholders for config-settings, and we set CIBUILDWHEEL_BUILD_IDENTIFIER in the build step. We’ve also made some nice Android improvements. We’ve removed support for Python 3.8, Python 3.13t, GraalPy 3.11, and Cirrus CI.

Pyemscripten wheels

After (well) over a year, you can now upload pyodide wheels with the new pyemscripten tag to PyPI! We’ve moved pyodide 3.13 and 3.14 (in alpha) over to the new standard tag. You’ll need at least Pyodide 0.29.4 to be able to install the wheels by default.

To build a wheel, use the pyodide platform, like before. Only now the wheels will have the correct tag to upload to PyPI!

There’s an alpha for 3.14, too. You’ll need the enable: pyodide-prerelease, since you should not upload these to PyPI yet. We’ve got the old 3.12 available, too, under pyodide-eol; it does not produce wheel tags you can upload to PyPI as there’s no pyodide 3.12 version that supports that.

New and old Pythons

We’ve got 3.15 support! As always, you’ll want to use enable: cpython-prerelease, since you should not upload these to PyPI yet. Beta 2 is exciting, and fixes a lot of beta 1 issues, but it does cause pip’s terrible hacks to leak build isolation. We don’t have much in our outer environments, so it should be pretty safe, but if that’s a problem, we’ll update once a new pip is released.

We’ve also dropped Python 3.8 (well past EoL, also dropped from manylinux), and Python 3.13t (always was experimental, harder to develop for than 3.14t, and also removed from manylinux). We’ve also removed GraalPy 3.11, which had a lot of workarounds and was replaced by GraalPy 3.12 over six months ago.

We’ve also dropped support for Cirrus CI, which shut down June 1, 2026.

Android and iOS

Android (added in 3.1) got a lot of attention this release. Building NumPy and related packages is much nicer now, with auditwheel support, pkg-config and Fortran configuration, and a new xbuild-files option (the Android counterpart to iOS’s xbuild-tools) for listing files that are safe to use from the host during the cross-compile.

iOS for 3.15 now comes directly from CPython (like Android), rather than from the BeeWare support package used for earlier versions. We are vendoring support files for iOS for now, while we wait for xbuild to replace our vendor soon.

Audit wheel stage

There’s a brand new stage! This is the audit stage, which runs after the repair step, used to run abi3audit on ABI3 wheels by default. You can set audit-command to control it; if you set it to something containing {abi3_wheel}, this will only run when ABI3 wheels are produced, otherwise, if you use {wheel}, this will audit all wheels. There’s also audit-requires for dependencies for this stage.

You can disable it with:

[tool.cibuildwheel]
audit-command = ""

Windows repairs

We now run delvewheel repair by default. If you want to restore the old default, set this:

[tool.cibuildwheel.windows]
repair-wheel-command = ""

You also might need to tell delvewheel where your libraries are so it can bundle them.

CUDA (docs change only)

It doesn’t require a cibuildwheel update, but there are now CUDA images that you can use to build CUDA wheels (see the docs). You can use them like this:

CIBW_MANYLINUX_X86_64_IMAGE: >-
  quay.io/manylinux_cuda/manylinux2_28_x86_64_cuda13_1:latest
CIBW_MANYLINUX_AARCH64_IMAGE: >-
  quay.io/manylinux_cuda/manylinux2_28_aarch64_cuda13_1:latest

There are (manylinux2_28, manylinux2_34) x (x86_64, aarch64) x (cuda12.9, cuda13.1) = 8 images.

Smaller things

cibuildwheel is more secure now; we check SHA256 for most of our downloads. We properly filter tar file extraction if you run on an SDist directly.

Lots of user requests have been addressed. You have access to a new CIBUILDWHEEL_BUILD_IDENTIFIER environment variable to identify what wheel is being built. config-settings now supports {project} and {package} placeholders. We support intersphinx linking to our docs.

We also did several AI sweeps of our codebase (using Kimi K2.6 and Claude Opus 4.8) and fixed several edge cases and potential issues found with those.

Previous additions and changes

A few highlights since 3.0:

  • Selected build identifiers print out (3.4.1)
  • You can now use our action even if fully pinned actions are required (3.4.1)
  • You can use uv directly as a build frontend. This includes building an item from a workspace. (3.4.0)
  • Verbosity handled better across build frontends. (3.4.0)
  • New test-runtime option (3.3.3)
  • New manylinux_2_35 images on 32-bit ARM armv7l (3.3.0)
  • build[uv] now supported on Android (3.3.0)
  • Extras option with the GitHub Action (3.3.0)
  • {project} and {package} placeholders in repair-wheel-command (3.3.0)
  • GraalPy 3.12 (3.2.0)
  • --clean-cache command (3.1.4)
  • riscv64 now supported on PyPI, no enable required (3.1.2)
  • Python 3.14 enabled by default (3.1.0)
  • Pyodide 3.13 (3.1.0)
  • Android wheels (3.1.0)
  • 32-bit manylinux_2_28 added, manylinux_2_34 added (3.1.0)
  • Markdown summary for GHA output (3.1.0)

Final words

Enjoy the new version! See the full changelog for everything else.

Categories: Python