cibuildwheel
Python wheels 很棒。但在 Mac、Linux、Windows 上,针对 多个 Python 版本 构建它们则不然。
cibuildwheel 在此提供帮助。cibuildwheel 在你的 CI 服务器上运行——目前它支持 GitHub Actions、Azure Pipelines、CircleCI 和 GitLab CI——并在你的所有平台上构建和测试你的 wheels。
它做什么?
虽然 cibuildwheel 本身需要较新的 Python 版本才能运行(我们支持最近三个版本),但它可以针对以下版本来构建 wheels:
| macOS Intel | macOS Apple Silicon | Windows 64bit | Windows 32bit | Windows Arm64 | manylinux musllinux x86_64 | manylinux musllinux i686 | manylinux musllinux aarch64 | manylinux musllinux ppc64le | manylinux musllinux s390x | manylinux musllinux armv7l | Android | iOS | Pyodide | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| CPython 3.9 | ✅ | ✅ | ✅ | ✅ | ✅2 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅4 | N/A | N/A | N/A |
| CPython 3.10 | ✅ | ✅ | ✅ | ✅ | ✅2 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅4 | N/A | N/A | N/A |
| CPython 3.11 | ✅ | ✅ | ✅ | ✅ | ✅2 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅4 | N/A | N/A | N/A |
| CPython 3.12 | ✅ | ✅ | ✅ | ✅ | ✅2 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅4 | N/A | N/A | ✅3 |
| CPython 3.13 | ✅ | ✅ | ✅ | ✅ | ✅2 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅4 | ✅ | ✅ | ✅ |
| CPython 3.14 | ✅ | ✅ | ✅ | ✅ | ✅2 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅4 | ✅ | ✅ | ✅ |
| CPython 3.15 | ✅ | ✅ | ✅ | ✅ | ✅2 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅4 | ✅ | ✅ | ✅ |
| PyPy 3.9 v7.3 | ✅ | ✅ | ✅ | N/A | N/A | ✅1 | ✅1 | ✅1 | N/A | N/A | N/A | N/A | N/A | N/A |
| PyPy 3.10 v7.3 | ✅ | ✅ | ✅ | N/A | N/A | ✅1 | ✅1 | ✅1 | N/A | N/A | N/A | N/A | N/A | N/A |
| PyPy 3.11 v7.3 | ✅ | ✅ | ✅ | N/A | N/A | ✅1 | ✅1 | ✅1 | N/A | N/A | N/A | N/A | N/A | N/A |
| GraalPy 3.12 v25.0 | ✅ | ✅ | ✅ | N/A | N/A | ✅1 | N/A | ✅1 | N/A | N/A | N/A | N/A | N/A | N/A |
1 PyPy 和 GraalPy 仅支持 manylinux 轮子。
2 Windows arm64 支持为实验性功能。
3 在 PyPI 上不受支持,使用旧的 pyodide 标签而非 pyemscripten。需要 pyodide-eol enable。
4 manylinux armv7l 支持为实验性功能。由于该架构没有基于 RHEL 的镜像,因此改用基于 Ubuntu 的镜像。
- 构建 manylinux、musllinux、macOS、Windows、pyemscripten、iOS 和 Android 轮子
- 支持 CPython、PyPy 和 GraalPy
- 适用于 GitHub Actions、Azure Pipelines、CircleCI 和 GitLab CI
- 在 Linux 上通过 auditwheel 捆绑共享库依赖,在 macOS 上通过 delocate,在 Windows 上通过 delvewheel
- 针对通过轮子安装的库版本运行库的测试
如需构建不受支持的 Python 版本(例如 Python 2),请参阅 cibuildwheel 1 文档。
用法
cibuildwheel 在 CI 服务中运行。支持的平台取决于您使用的服务:
| Linux | macOS | Windows | Linux ARM | macOS ARM | Windows ARM | Android | iOS | Pyodide | |
|---|---|---|---|---|---|---|---|---|---|
| GitHub Actions | ✅ | ✅ | ✅ | ✅ | ✅ | ✅2 | ✅4 | ✅3 | ✅ |
| Azure Pipelines | ✅ | ✅ | ✅ | ✅ | ✅2 | ✅4 | ✅3 | ✅5 | |
| CircleCI | ✅ | ✅ | ✅ | ✅ | ✅45 | ✅35 | ✅5 | ||
| GitLab CI | ✅ | ✅ | ✅ | ✅1 | ✅ | ✅45 | ✅35 | ✅5 |
1 需要模拟,单独分发。其他服务也可能通过模拟或第三方构建主机支持 Linux ARM,但这些未在我们的 CI 中进行测试。
2 使用交叉编译。无法在此 CI 平台上测试 arm64。
3 需要 macOS runner;在 runner 架构的模拟器上运行测试。
4 为 Android 构建要求 runner 为 Linux x86_64、macOS ARM64 或 macOS x86_64。测试有额外要求。
5 构建可能有效,但未在 cibuildwheel 的 CI 中测试。
示例配置
要在 GitHub Actions 上构建 manylinux、musllinux、macOS 和 Windows 的 wheels,你可以使用此 .github/workflows/wheels.yml:
name: Build
on: [push, pull_request]
jobs:
build_wheels:
name: Build wheels on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, ubuntu-24.04-arm, windows-latest, windows-11-arm, macos-15-intel, macos-latest]
steps:
- uses: actions/checkout@v6
with:
persist-credentials: false
# Used to host cibuildwheel
- uses: actions/setup-python@v6
- name: Install cibuildwheel
run: python -m pip install cibuildwheel==4.2.0
- name: Build wheels
run: python -m cibuildwheel --output-dir wheelhouse
# to supply options, put them in 'env', like:
# env:
# CIBW_SOME_OPTION: value
# ...
- uses: actions/upload-artifact@v6
with:
name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}
path: ./wheelhouse/*.whl
有关更多信息,包括 PyPI 部署,以及其他 CI 服务或专用 GitHub Action 的使用,请参阅 documentation 和 examples。
工作原理
以下图表总结了 cibuildwheel 在每个平台上执行的步骤。

在文档中探索此图表的交互式版本。
[!WARNING] 构建和测试 wheel 会执行来自您的项目及其依赖项的任意代码。尽管 cibuildwheel 在某些构建中使用 OCI 容器和 Pyodide,但这些不提供任何安全保证 - 您正在构建和测试的代码对调用 cibuildwheel 的环境具有完全访问权限。
如果您无法信任所有引入的代码,请保持良好的安全卫生习惯:将构建分发包的任务与将它们上传到 PyPI 的任务分开,谨慎处理密钥和凭证并定期轮换,并在授予权限时遵循最小权限原则。不要在 CI 运行器上存储敏感数据。
| 选项 | 描述 | |
|---|---|---|
| 构建选择 | platform | 覆盖自动检测的目标平台 |
buildskip | 选择要构建的 Python 版本 | |
archs | 更改机器上默认构建的架构。 | |
project-requires-python | 手动设置项目的 Python 兼容性 | |
enable | 启用构建时存在额外类别的选择器。 | |
allow-empty | 如果没有 wheel 匹配指定的构建标识符,则抑制错误代码 | |
| 构建自定义 | build-frontend | 设置用于构建的工具,可以是 "build"(默认)、"build[uv]" 或 "pip" |
config-settings | 为构建后端指定 config-settings。 | |
environment | 设置环境变量 | |
environment-pass | 在主机上设置环境变量以传递给容器。 | |
before-all | 在构建任何 wheel 之前,在构建系统上执行 shell 命令。 | |
before-build | 执行 shell 命令以准备每个 wheel 的构建 | |
xbuild-tools | 路径上应包含在隔离的交叉构建环境中的二进制文件。 | |
xbuild-files | 构建环境中的平台特定文件 | |
repair-wheel-command | 执行 shell 命令以修复每个已构建的 wheel | |
manylinux-*-imagemusllinux-*-image | 指定 manylinux / musllinux 容器镜像 | |
container-engine | 指定构建 Linux wheel 时使用的容器引擎 | |
dependency-versions | 控制 cibuildwheel 使用的工具版本 | |
pyodide-version | 指定用于 pyodide 平台构建的 Pyodide 版本 | |
| Auditing | audit-requires | 为审计步骤安装 Python 依赖项 |
audit-command | 在运行结束前使用工具检查 wheels | |
| Testing | test-command | 测试每个构建的 wheel 的命令 |
before-test | 在测试每个 wheel 之前执行 shell 命令 | |
test-sources | 复制到测试工作目录的路径 | |
test-requires | 在运行测试之前安装 Python 依赖项 | |
test-extras | 使用 extras_require 安装您的 wheel 以进行测试 | |
test-groups | 从您的项目的 dependency-groups 中指定测试依赖项 | |
test-skip | 跳过在某些构建上运行测试 | |
test-environment | 为测试环境设置环境变量 | |
test-runtime | 控制测试的执行方式。 | |
| Debugging | debug-keep-container | 运行后保留容器以进行调试。 |
debug-traceback | 发生错误时打印完整的 traceback。 | |
build-verbosity | 增加/减少构建的输出 |
这些选项可以在 pyproject.toml 文件中指定,或作为环境变量,参见 配置文档。
工作示例
以下是一些使用 cibuildwheel 的仓库。
| Name | CI | OS | Notes |
|---|---|---|---|
| scikit-learn | 机器学习库。一个复杂但干净的配置,使用 cibuildwheel 的许多功能来构建一个包含 Cython 和 C++ 扩展的大型项目。 | ||
| duckdb | DuckDB 是一个分析型进程内 SQL 数据库管理系统 | ||
| NumPy | Python 科学计算的基础包。 | ||
| pytorch-fairseq | 用 Python 编写的 Facebook AI Research 序列到序列工具包。 | ||
| NCNN | ncnn 是一个针对移动平台优化的高性能神经网络推理框架 | ||
| Matplotlib | 久负盛名的 Matplotlib,一个包含 C++ 部分的 Python 库 | ||
| Tornado | Tornado 是一个 Python Web 框架和异步网络库。使用稳定的 ABI 用于小型 C 扩展。 | ||
| MyPy | 使用 MyPyC 编译的 MyPy 版本。 | ||
| Prophet | 用于生成具有线性或非线性增长的多季节性时间序列数据的高质量预测的工具。 | ||
| Triton | 自托管运行器 |
ℹ️ 这只是其中一小部分,还有更多!请查看文档中的 Working Examples 页面。
Legal note
由于 cibuildwheel 使用 delocate、auditwheel 或 delvewheel 修复 wheel,它可能会自动打包来自构建机器的动态链接库。
这有助于确保该库可以在不依赖 pip 工具链之外任何依赖项的情况下运行。
这与静态链接类似,因此可能会带来一些许可证影响。请检查您引入的任何代码的许可证,以确保这是被允许的。
Changelog
v4.2.0
2026 年 8 月 4 日
- 🌟 CPython 3.15 wheels 现在默认构建 - 不带
"cpython-prerelease"enable集合。是时候将这些 wheels 构建并上传到 PyPI 了!此版本包含 CPython 3.15.0rc1,保证与最终版本 ABI 兼容。 (#2944) - ✨ 添加了对 Pyodide 3.15 的支持,使用
cp315-pyodide_wasm32构建标识符,采用 Pyodide 315.0.0a2。这些相对于最终版本也是稳定的。 (#2958) - 🐛 对失败的下载重试六次,采用指数退避策略,因此短暂的网络中断不再阻止构建。
4xx响应仍会立即报告。 (#2953) - 🐛 在 Pyodide 上接受
default作为build-frontend值,并在顶层表和 overrides 中接受pyodide-build(#2951) - 🛠 在 GraalPy 上保留 pip,因为较新的 pip 会破坏构建 (#2955)
- 🛠 将 Pyodide 更新到 314.0.4 (#2949, #2952)
- 🛠 更新依赖项和容器固定版本 (#2952, #2960)
- 💼 更新 CI action 固定版本 (#2948, #2954)
- 🧪 对 abi3 测试使用 pp311,并删除
test_overridden_pip_constraint,自 #2583 以来这已不再必要 (#2956, #2957)
v4.1.1
2026年7月24日
- ✨ 将
pyodide-build作为独立的build-frontend添加,现为 Pyodide 的默认前端,并支持详细程度标志处理。在 Pyodide 上,任何其他前端都会被忽略并发出警告。 (#2609, #2945) - 🔐 使用摘要而非标签来固定容器镜像,以增强供应链安全性。人类可读的标签仍作为注释保留在
pinned_docker_images.cfg中。 (#2915) - 🐛 修复了平台特定的
test-runtime环境变量(例如CIBW_TEST_RUNTIME_ANDROID)未被尊重的问题 (#2941) - 🐛 修复了
test-requires和audit-requires的引号处理,使包含空格的 PEP 508 说明符能够正常工作 (#2913) - 🐛 使
archs解析不区分大小写并感知平台,例如arm64在 Windows 上可以工作 (#2920) - 🐛 在
config-settings中为{project}占位符使用绝对路径 (#2934) - 🐛 针对构建标识符验证
pyodide-version选项,并提供清晰的错误信息 (#2925) - 🐛 修复了 PyPy 在 macOS 上的安装问题,此前 PyPy 已将其下载源从
.tar.bz2切换为.tar.gz(#2939) - 🐛 在 macOS 的构建和测试虚拟环境中提供匹配的
python3-config(#2922) - 🛠 更新依赖项和容器固定版本 (#2917, #2935, #2939)
- 🛠 更新 Android 测试以适配当前 Python 版本和新的测试仓库 URL (#2933)
- 🛠 移除
orjson依赖项,mypy 2+ 不再使用它 (#2923) - 📚 使用 properdocs(MkDocs 的一个分支)构建文档 (#2946)
- 📚 在构建标识符表中添加缺失的
cp314-pyodide_wasm32条目 (#2947) - 📚 移除关于
pip wheel构建前端和 ClearLinux 的过时说明 (#2926) - 💼 添加 "CI: PyPy EoL" PR 标签,以便在 PR 上运行 PyPy EoL 测试 (#2930)
- 💼 更新 CI 操作固定版本和 pre-commit 钩子 (#2914, #2932, #2938, #2940, #2942, #2943)
v4.1.0
2026 年 6 月 12 日
- ✨ 将 Pyodide 更新至 314.0.0 最终版本,因此 Pyodide 3.14 的 wheels 现在默认构建时不再需要
pyodide-prereleaseenable标志。 (#2906) - 🐛 当构建未生成 wheel 时,抛出清晰的错误,而不是在后续阶段以令人困惑的消息失败 (#2909)
- 🛠 通过 Python 3.15 上的延迟导入加速 CLI 启动 (#2797)
- 📚 新增关于使用
CIBW_CACHE_PATH缓存 cibuildwheel 下载工具的 FAQ 部分 (#2842) - 📚 文档改进:澄清了命令选项所使用的 shell,澄清了环境变量优先级,并修复了一个失效的 Pyodide 环境信息链接 (#2904, #2905, #2911)
v4.0.0
2026 年 6 月 7 日
有关新功能的更多信息,请参阅 @henryiii 的 发布帖!
-
🌟 在修复步骤之后,默认添加使用
abi3audit进行的 wheel 审计,并新增audit-requires和audit-command选项 (#2805) -
🌟 添加
pyemscripten平台标签支持 (PEP 783),将 Pyodide 更新至 314.0.0a2,并添加pyodide-eolenable标志以构建已停止支持的 Pyodide 版本 (#2812, #2848) -
🌟 将
delvewheel设置为 Windows 的默认repair-wheel-command,因此扩展模块 DLL 现在会自动打包。如果不需要,可通过将其设置为空来跳过。 (#2831) -
✨ 在
enable选项cpython-prerelease下添加 CPython 3.15 支持。此版本的 cibuildwheel 使用 3.15.0b2。 (#2833, #2850)在 CPython 处于 beta 阶段时,ABI 可能会发生变化,因此您的 wheel 可能与最终版本不兼容。因此,我们不建议在 RC1 之前分发 wheel,届时 3.15 将在 cibuildwheel 中可用,且无需该标志。
-
✨ 为 iOS 和 Android 添加 CPython 3.15 支持 (#2857, #2858)
-
✨ 添加构建 NumPy 及相关包的 Android 改进,包括 auditwheel 支持、pkg-config 和 Fortran 配置,以及
xbuild-files选项 (#2695) -
✨ 在每次构建步骤期间添加设置为当前构建标识符的
CIBUILDWHEEL_BUILD_IDENTIFIER环境变量(例如cp311-manylinux_x86_64) (#2872) -
✨ 为
config-settings添加{project}和{package}占位符 (#2827) -
⚠️ 移除对 Python 3.8 的支持 (#2686)
-
⚠️ 移除实验性的 CPython 3.13 自由线程构建和
cpython-freethreadingenable选项。CPython 3.14+ 的自由线程支持仍可用,无需启用标志。 (#2684) -
⚠️ 移除对 Cirrus CI 的支持,该服务将于 2026 年 6 月 1 日关闭 (#2817)
-
⚠️ 移除对 GraalPy 3.11 (gp311) 的支持,如 #2741 中所述,并移除仅适用于 GraalPy 24 的变通方案 (#2895)
-
🔐 为直接下载 Python 解释器、virtualenv 和 python-build-standalone 资源添加 SHA256 验证 (#2873)
-
🔐 为安全归档提取添加 tarfile 提取过滤器 (#2856)
-
🐛 修复在 Linux 上使用
uv作为build-frontend时,before-build的UV_PYTHON未设置的问题 (#2830) -
🐛 修复下载 python-build-standalone 时对 musl libc 的检测,此前在 Alpine 等 musl 主机上始终选择 gnu 资源 (#2889)
-
🐛 修复当
{project}或{package}包含空格或反斜杠时config-settings的展开问题 (#2886) -
🐛 防止
linux32失败时发生死锁,并将平台参数转发给健全性检查 (#2880, #2888) -
🐛 修复容器在启动失败和拆除过程中的资源泄漏问题 (#2879, #2887)
-
🐛 移除错误情况下潜在的缓存部分填充问题 (#2892)
-
🐛 当
ANDROID_API_LEVEL不是整数时抛出明确的错误 (#2891) -
🐛 在 python-build-standalone 中用适当的异常替换 assert (#2859)
-
🐛 当
package_dir位于 cwd 之外时,使用 ConfigurationError 而非通用的 Exception (#2898) -
🛠 更新依赖项和容器固定版本 (#2893, #2882, #2874, #2868, #2862, #2884, #2845, #2837, #2818, #2810, #2838, #2813)
-
🛠 将 Android 更新至 Python 3.13.13 和 3.14.4 (#2821)
-
🛠 对 Emscripten 工具链安装应用 Pyodide 特定的补丁 (#2800)
-
🛠 使用
python -V -V进行 Windows 构建诊断 (#2832) -
🛠 简化固定容器镜像查找 (#2897)
-
🛠 对错误消息、OCI 容器和选项进行小幅修复 (#2860)
-
💼 为
bin/脚本添加 PEP 723 元数据,并移除bin依赖组 (#2819) -
💼 通过重试和缓存提高 Azure 测试的可靠性 (#2890)
-
💼 修复 Windows GitLab CI 测试运行问题 (#2870)
-
💼 更新 CI 操作固定版本和开发依赖项 (#2902, #2867, #2851, #2843, #2826, #2823, #2820, #2807)
-
💼 添加 agent 和 copilot 配置文件 (#2861)
-
💼 使用
if TYPE_CHECKING:块 (#2866, #2864) -
🧪 修复使用
uv前端的 Android 测试 (#2809) -
🧪 修复 update-dependencies 工作流,使用
uv运行nox(#2808) -
🧪 为
OCIContainer._get_platform_args添加单元测试 (#2878) -
📚 更新了 delvewheel 作为默认 Windows
repair-wheel-command的文档,包括构建图、模式默认值和法律声明 (#2877, #2853, #2891) -
📚 记录了平台特定的
before-build配置 (#2834) -
📚 更新了“工作原理”图,包含 Android、iOS 和 Pyodide 构建的详细信息 (#2816)
-
📚 添加了 Pyodide 图标,并重新生成了 Android、iOS 和 Pyodide 的工作示例数据 (#2815, #2811)
-
📚 添加了 intersphinx 支持,用于外部文档链接 (#2871)
-
📚 添加了构建 CUDA wheels 的说明,并修复了 FAQ 中的 manylinux 容器引用 (#2896, #2900)
-
📚 在文档中链接回源代码 (#2806)
-
📚 移除了过时的 numpy 信息 (#2855)
v3.4.1
2026 年 4 月 2 日
- ⚠️ 针对实验性 CPython 3.13 无锁线程变体的构建现已弃用。该功能将在下一个次要版本中移除。因此,
enable选项cpython-freethreading也已弃用。指定enable = "all"的构建不再选择cpython-freethreading。CPython 3.14 的无锁线程支持仍可用,无需enable标志。(#2787) - 🐛 如果
repair-wheel-command在配置中已定义,iOS 构建将不再跳过它(#2761) - 🐛 修复了一个导致
uv在环境定义了 PYTHON_VERSION 或 UV_PYTHON 时失败的 bug,这些变量与我们的 venvs 冲突(#2795) - ✨ cibuildwheel 现在会在构建开始时打印所选的构建标识符。(#2785)
- 🔐 GitHub Action 现在使用完整的 SHA 引用其他 actions(#2744)
这是最后几个版本。
ℹ️ 想要更多更新日志?请前往文档中的更新日志页面。
贡献
有关如何为 cibuildwheel 贡献的更多信息,请参阅文档。
所有通过代码库、问题跟踪器、聊天室或其他方式与 cibuildwheel 项目互动的人员,均须遵守PSF 行为准则。
维护者
核心:
- Joe Rickerby @joerick
- Yannick Jadoul @YannickJadoul
- Matthieu Darbois @mayeut
- Henry Schreiner @henryiii
- Grzegorz Bokota @Czaki
- Agriya Khetarpal @agriyakhetarpal(同时也是 Pyodide)
平台维护者:
- Russell Keith-Magee @freakboy3742(iOS)
- Hood Chatham @hoodmane(Pyodide)
- Gyeongjae Choi @ryanking13(Pyodide)
- Tim Felgentreff @timfel(GraalPy)
- Malcolm Smith @mhsmith(Android)
致谢
cibuildwheel 站在巨人的肩膀上。
- ⭐️ 感谢 @matthew-brett 的 multibuild 和 matthew-brett/delocate
- 感谢 @PyPA 的 manylinux Docker 镜像 pypa/manylinux
- 感谢 @ogrisel 的 wheelhouse-uploader 和
run_with_env.cmd
特别感谢——
- @zfrenchee 帮助调试了许多问题](https://github.com/pypa/cibuildwheel/issues/2)
- @lelit 提供了出色的 bug 报告和贡献
- @mayeut 提交了一个出色的 PR,修补了 Python 本身以提供更好的兼容性!
- @czaki 在众多 PR 中作为超级贡献者,并协助解决了无数问题!
- @mattip 帮助为 cibuildwheel 添加 PyPy 支持
另请参阅
另一个非常相似的工具是 matthew-brett/multibuild。multibuild 是一个用于在多个平台上构建 wheel 的 shell 脚本工具箱。它被用作构建一些大型数据科学工具(如 SciPy)的基础。
如果你正在构建 Rust wheel,你可以避免使用许多使 GLIBC 通过 manylinux 正常工作所需的技巧;这对于交叉编译尤其相关,因为使用 Rust 进行交叉编译很容易。参见 maturin-action 以获取一个针对构建 Rust wheel 和交叉编译进行优化的工具。