为Python >= 3.9使用Maturin构建无架构包
当前版本
我之前在PyPi和Conda上发布过一个包。这个包是用纯Python写的,使用了以下一些设置在pyproject.toml
文件中,并且是通过本地的python -m build
命令构建的:
[build-system]
requires = ["setuptools>=61.0.0", "wheel"]
build-backend = "setuptools.build_meta"
这样会生成两个分发文件:一个源文件和一个轮子文件,这些文件会被上传:
myproject-1.0.0.tar.gz
myproject-1.0.0-py3-none-any.whl
新版本
为了提高性能,我现在用Rust写了一些扩展,并使用了pyo3绑定,构建系统是maturin。所有东西在本地都能正常工作。
我想生成这些通用的分发文件,但显然我对Python包的分发系统还不是很了解。
如果我把pyproject.toml
文件改成这样:
[build-system]
requires = ["maturin>=1.0,<2.0"]
build-backend = "maturin"
然后运行maturin build --release --sdist --bindings pyo3
(在Windows上,使用Python 3.11)会生成以下文件:
myproject-1.1.0.tar.gz
myproject-1.1.0-cp311-none-win_amd64.whl
问题
我想了解如何全面覆盖分发的各个方面,以及可能存在的风险。例如,
如果我把这些文件上传到PyPi,会不会给用户带来问题?
没有安装Rust的用户能否从源分发中安装我的包?
源分发是否也需要依赖于架构?
maturin如何为所有Python版本(>= 3.9)生成轮子文件?
1 个回答
如果我把这些文件上传到PyPi,会对用户造成问题吗?
如果用户使用了这个 --only-binary
选项,那肯定会有问题。
没有安装Rust的用户能从源代码包安装我的软件包吗?
我觉得不行:源代码包应该包含构建轮子所需的文件,但轮子还是需要被构建。如果没有纯轮子的选项,那用户就没办法了。
可惜的是,按照我所知,maturin不支持纯Python的备用方案,我也在为我个人的项目寻找/希望这个功能。
我不是很清楚所有的情况,但我认为目前最好的办法是把加速器编译成一个不同的crate,并把它作为可选依赖。我不知道有没有办法告诉pip如果可以就安装一个依赖,否则就忽略,但需求说明符可以做到这一点,尽管维护起来有点麻烦。
源代码分发也需要依赖于架构吗?
不需要,源代码就是源代码。
maturin如何为所有Python版本 >= 3.9生成轮子?
我猜如果你使用有限的ABI或cffi,可能可以生成一个跨版本的轮子,否则你可能需要为每个目标解释器生成一个轮子,以创建匹配的二进制文件。像cibuildwheel这样的项目旨在帮助处理这些事情。
根据https://github.com/PyO3/maturin-action/issues/15#issuecomment-969833776,可能还有一个 -i
选项,可以让你明确指定目标解释器。