cibuildwheel
Python轮子很棒。但在Mac、Linux、Windows上,针对多个Python版本构建它们并不容易。
cibuildwheel
来帮忙了。cibuildwheel
在你的CI服务器上运行 - 目前支持GitHub Actions、Azure Pipelines、Travis CI、AppVeyor、CircleCI和GitLab CI - 它可以在所有平台上构建和测试你的轮子。
它能做什么?
macOS Intel | macOS Apple Silicon | Windows 64位 | Windows 32位 | Windows Arm64 | manylinux musllinux x86_64 | manylinux musllinux i686 | manylinux musllinux aarch64 | manylinux musllinux ppc64le | manylinux musllinux s390x | Pyodide | |
---|---|---|---|---|---|---|---|---|---|---|---|
CPython 3.6 | ✅ | 不适用 | ✅ | ✅ | 不适用 | ✅ | ✅ | ✅ | ✅ | ✅ | 不适用 |
CPython 3.7 | ✅ | 不适用 | ✅ | ✅ | 不适用 | ✅ | ✅ | ✅ | ✅ | ✅ | 不适用 |
CPython 3.8 | ✅ | ✅ | ✅ | ✅ | 不适用 | ✅ | ✅ | ✅ | ✅ | ✅ | 不适用 |
CPython 3.9 | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ | 不适用 |
CPython 3.10 | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ | 不适用 |
CPython 3.11 | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ | 不适用 |
CPython 3.12 | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ | ✅⁴ |
CPython 3.13³ | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ | 不适用 |
PyPy 3.7 v7.3 | ✅ | 不适用 | ✅ | 不适用 | 不适用 | ✅¹ | ✅¹ | ✅¹ | 不适用 | 不适用 | 不适用 |
PyPy 3.8 v7.3 | ✅ | ✅ | ✅ | 不适用 | 不适用 | ✅¹ | ✅¹ | ✅¹ | 不适用 | 不适用 | 不适用 |
PyPy 3.9 v7.3 | ✅ | ✅ | ✅ | 不适用 | 不适用 | ✅¹ | ✅¹ | ✅¹ | 不适用 | 不适用 | 不适用 |
PyPy 3.10 v7.3 | ✅ | ✅ | ✅ | 不适用 | 不适用 | ✅¹ | ✅¹ | ✅¹ | 不适用 | 不适用 | 不适用 |
¹ PyPy仅支持manylinux轮子。
² Windows arm64支持是实验性的。
³ 从cibuildwheel 2.20开始,CPython 3.13默认使用Python RC版本构建。自由线程模式仍需使用CIBW_FREE_THREADED_SUPPORT
选择加入。
⁴ 实验性功能,PyPI尚不支持,但可直接用于Web部署。使用--platform pyodide
进行构建。
- 为CPython和PyPy构建manylinux、musllinux、macOS 10.9+和Windows轮子
- 适用于GitHub Actions、Azure Pipelines、Travis CI、AppVeyor、CircleCI、GitLab CI和Cirrus CI
- 通过auditwheel和delocate在Linux和macOS上打包共享库依赖
- 针对wheel安装版本的库运行你的库的测试
如果你需要构建不受支持的Python版本(如Python 2),请参阅cibuildwheel 1文档。
使用方法
cibuildwheel
在CI服务内部运行。支持的平台取决于你使用的服务:
Linux | macOS | Windows | Linux ARM | macOS ARM | Windows ARM | |
---|---|---|---|---|---|---|
GitHub Actions | ✅ | ✅ | ✅ | ✅¹ | ✅ | ✅² |
Azure Pipelines | ✅ | ✅ | ✅ | ✅ | ✅² | |
Travis CI | ✅ | ✅ | ✅ | |||
AppVeyor | ✅ | ✅ | ✅ | ✅ | ✅² | |
CircleCI | ✅ | ✅ | ✅ | ✅ | ||
Gitlab CI | ✅ | ✅ | ✅ | ✅¹ | ✅ | |
Cirrus CI | ✅ | ✅ | ✅ | ✅ | ✅ |
¹ 需要模拟,单独分发。其他服务可能也通过模拟或第三方构建主机支持Linux ARM,但这些在我们的CI中未经测试。
² 使用交叉编译。在此CI平台上无法测试arm64
。
示例设置
要在GitHub Actions上构建manylinux、musllinux、macOS和Windows轮子,你可以使用以下.github/workflows/wheels.yml
:
name: 构建
on: [push, pull_request]
jobs:
build_wheels:
name: 在${{ matrix.os }}上构建轮子
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-13, macos-14]
steps:
- uses: actions/checkout@v4
# 用于托管cibuildwheel
- uses: actions/setup-python@v5
- name: 安装cibuildwheel
run: python -m pip install cibuildwheel==2.20.0
- name: 构建轮子
run: python -m cibuildwheel --output-dir wheelhouse
# 要提供选项,将它们放在'env'中,如:
# env:
# CIBW_SOME_OPTION: 值
- uses: actions/upload-artifact@v4
with:
name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}
path: ./wheelhouse/*.whl
有关更多信息,包括PyPI部署以及其他CI服务或专用GitHub Action的使用,请查看文档和示例。
工作原理
下图总结了cibuildwheel在每个平台上采取的步骤。
在文档中探索此图的交互版本。
选项
选项 | 描述 | |
---|---|---|
构建选择 | CIBW_PLATFORM | 覆盖自动检测的目标平台 |
CIBW_BUILD CIBW_SKIP | 选择要构建的Python版本 | |
CIBW_ARCHS | 更改默认在您的机器上构建的架构 | |
CIBW_PROJECT_REQUIRES_PYTHON | 手动设置项目的Python兼容性 | |
CIBW_PRERELEASE_PYTHONS | 启用使用可用的Python预发布版本进行构建 | |
构建定制 | CIBW_BUILD_FRONTEND | 设置用于构建的工具,可以是"pip"(目前默认)或"build" |
CIBW_ENVIRONMENT | 设置构建过程中需要的环境变量 | |
CIBW_ENVIRONMENT_PASS_LINUX | 在主机上设置环境变量以在构建期间传递到容器 | |
CIBW_BEFORE_ALL | 在构建任何轮子之前在构建系统上执行shell命令 | |
CIBW_BEFORE_BUILD | 执行shell命令准备每个轮子的构建 | |
CIBW_REPAIR_WHEEL_COMMAND | 执行shell命令修复每个构建的轮子 | |
CIBW_MANYLINUX_*_IMAGE CIBW_MUSLLINUX_*_IMAGE | 指定替代的manylinux / musllinux Docker镜像 | |
CIBW_CONTAINER_ENGINE | 指定构建Linux轮子时使用的容器引擎 | |
CIBW_DEPENDENCY_VERSIONS | 指定cibuildwheel如何控制其使用的工具版本 | |
测试 | CIBW_TEST_COMMAND | 执行shell命令测试每个构建的轮子 |
CIBW_BEFORE_TEST | 在测试每个轮子之前执行shell命令 | |
CIBW_TEST_REQUIRES | 在运行测试之前安装Python依赖项 | |
CIBW_TEST_EXTRAS | 使用extras_require安装轮子进行测试 | |
CIBW_TEST_SKIP | 跳过对某些构建运行测试 | |
其他 | CIBW_BUILD_VERBOSITY | 增加/减少pip wheel的输出 |
这些选项也可以在pyproject.toml文件中指定;请参阅配置。
工作示例
以下是一些使用cibuildwheel的仓库。
名称 | CI | 操作系统 | 注释 |
---|---|---|---|
scikit-learn | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | 机器学习库。使用cibuildwheel的许多功能构建一个具有Cython和C++扩展的大型项目的复杂但干净的配置。 |
pytorch-fairseq | ![github icon][] | ![apple icon][] ![linux icon][] | Facebook AI Research用Python编写的序列到序列工具包。 |
NumPy | ![github icon][] ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Python科学计算的基础包。 |
Tornado | ![github icon][] | ![linux icon][] ![apple icon][] ![windows icon][] | Tornado是一个Python web框架和异步网络库。使用稳定ABI构建小型C扩展。 |
duckdb | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | DuckDB是一个分析型内存SQL数据库管理系统 |
NCNN | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | ncnn是一个为移动平台优化的高性能神经网络推理框架 |
Matplotlib | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | 著名的Matplotlib,一个带有C++部分的Python库 |
Prophet | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | 用于生成具有多重季节性的时间序列数据的高质量预测的工具,可以是线性或非线性增长。 |
MyPy | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | 使用MyPyC编译的MyPy版本。 |
Kivy | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | 用Python编写的开源UI框架,可在Windows、Linux、macOS、Android和iOS上运行 |
ℹ️ 这只是一小部分,还有更多!查看文档中的工作示例页面。
法律说明
由于cibuildwheel
使用delocate
或auditwheel
修复轮子,它可能会自动捆绑构建机器上的动态链接库。
这有助于确保库可以在没有pip工具链之外的任何依赖项的情况下运行。
这类似于静态链接,因此可能有一些许可证影响。请检查您引入的任何代码的许可证,以确保允许这样做。
更新日志
v2.20.0
- 🌟 现在默认构建CPython 3.13轮子 - 无需
CIBW_PRERELEASE_PYTHONS
标志。是时候构建这些轮子并上传到PyPI了!此版本包括CPython 3.13.0rc1,保证与最终版本ABI兼容。自由线程仍然在标志/配置选项后面。(#1950) - ✨ 提供
CIBW_ALLOW_EMPTY
环境变量作为命令行标志的替代方案。(#1937) - 🐛 Windows上的PyPy3.8不使用uv,从0.2.25版本开始停止工作。请注意,PyPy 3.8已经结束生命周期。(#1868)
- 🛠 根据目标架构设置
VSCMD_ARG_TGT_ARCH
变量。(#1876) - 🛠 撤销pytest 8-8.2上的更清晰输出,现在8.3已经发布。(#1943)
- 📚 更新示例以在主机上使用Python 3.12(从2024年10月开始,cibuildwheel将要求主机机器上的Python 3.11+)(#1919)
v2.19.2
- 🐛 更新manylinux2014引脚以支持已结束生命周期的CentOS 7镜像。(#1917)
- 🐛 支持
build[uv]
构建前端的--no-isolation
。(#1889) - 🛠 在https://github.com/pypa/cibuildwheel/attestations提供版本认证。(#1916)
- 🛠 提供CPython 3.13.0b3。(#1913)
- 🛠 现在pip 21.1可用,删除一些变通方法。(#1891, #1892)
- 📚 从我们的文档中删除nosetest。(#1821)
- 📚 记录GHA上3.8的macOS ARM变通方法。(#1871)
- 📚 GitLab CI + macOS现在是一个受支持的平台,并有示例。(#1911)
v2.19.1
- 🐛 Pyodide在GHA上不需要setup-python (#1868)
- 🐛 为uv指定完整的python路径(修复0.2.10和0.2.11中的问题)(#1881)
- 🛠 更新CPython 3.13上的pip 24.1b2。(#1879)
- 🛠 修复我们的模式生成脚本中的警告。(#1866)
- 🛠 pytest 8-8.2上的更清晰输出。(#1865)
v2.19.0
有关新功能的更多信息,请参阅发布帖子!
- 🌟 添加Pyodide平台。在Linux上使用主机Python 3.12设置
--platform pyodide
或CIBW_PLATFORM: pyodide
来构建WebAssembly轮子。目前PyPI不接受,但可直接在使用Pyodide的网站中使用,如用于实时文档等。(#1456, #1859) - 🌟 添加
build[uv]
后端,它将使用预先存在的uv安装(或安装cibuildwheel[uv]
),并在Python 3.8+上使用uv
进行所有环境设置和安装。在大多数情况下,这显著提高了速度。(#1856) - ✨ 添加macOS自由线程构建并更新CPython至3.13.0b2。(#1854)
- 🐛 修复了将轮子复制到不存在的输出目录的问题。(#1851, #1862)
- 🐛 改进了测试环境种子的确定性。(#1835)
- 🛠 现在设置
VIRTUAL_ENV
变量。(#1842) - 🛠 移除pip<21.3的临时解决方案。(#1842)
- 🛠 重构错误处理以使用异常。(#1719)
- 🛠 避免测试中的硬编码路径。(#1834)
- 🛠 使单一Python测试更加通用。(#1835)
- 🛠 通过拆分仿真测试加快我们的CI速度。(#1839)
v2.18.1
- 🌟 为3.13添加Linux和Windows的自由线程构建。新标识符
cp313t-*
,需要选择使用新选项CIBW_FREE_THREADED_SUPPORT
/tool.cibuildwheel.free-threaded-support
。查看文档获取更多信息。(#1831) - ✨
container-engine
现在是一个构建(非全局)选项。(#1792) - 🛠 cibuildwheel的构建后端现在是hatchling。(#1297)
- 🛠 对我们的noxfile进行了重大改进和现代化。(#1823)
- 🛠 使用pylint的新GitHub Actions报告器替代自定义匹配器。(#1823)
- 🛠 为Python 3.7+取消固定virtualenv更新(#1830)
- 🐛 修复从Windows或macOS ARM运行linux测试的问题。(#1788)
- 📚 修复我们的文档构建。(#1821)
以上是最近几个版本的更新。
ℹ️ 想查看更多更新日志?请访问文档中的更新日志页面。
贡献
有关如何为cibuildwheel做出贡献的更多信息,请参阅文档。
所有与cibuildwheel项目通过代码库、问题跟踪器、聊天室或其他方式进行互动的人都应遵守PSF行为准则。
维护者
- Joe Rickerby @joerick
- Yannick Jadoul @YannickJadoul
- Matthieu Darbois @mayeut
- Henry Schreiner @henryiii
- Grzegorz Bokota @Czaki
致谢
cibuildwheel
站在巨人的肩膀上。
- ⭐️ @matthew-brett 的 multibuild 和 matthew-brett/delocate
- @PyPA 的 manylinux Docker 镜像 pypa/manylinux
- @ogrisel 的 wheelhouse-uploader 和
run_with_env.cmd
同时也要特别感谢-
- @zfrenchee 帮助调试许多问题
- @lelit 提供了一些很棒的错误报告和贡献
- @mayeut 提供了一个非凡的PR,修补Python本身以获得更好的兼容性!
- @czaki 在多个PR中成为超级贡献者,并帮助解决了无数问题!
- @mattip 帮助将PyPy支持添加到cibuildwheel
另请参阅
另一个非常相似的工具值得考虑的是 matthew-brett/multibuild。multibuild
是一个用于在各种平台上构建轮子的shell脚本工具箱。它被用作构建一些大型数据科学工具(如SciPy)的基础。
如果你正在构建Rust轮子,你可以不需要一些让GLIBC通过manylinux工作的技巧;这对于交叉编译尤其重要,而Rust很容易实现交叉编译。查看 maturin-action,这是一个为构建Rust轮子和交叉编译而优化的工具。