使用 pyo3、rust-cpython 和 cffi 绑定以及 rust 二进制文件作为 python 包构建和发布 crates
项目描述
成熟
以前是 pyo3-pack
使用 pyo3、rust-cpython 和 cffi 绑定以及 rust 二进制文件作为 python 包构建和发布 crates。
该项目旨在作为setuptools-rust和milksnake的零配置替代。它支持在 windows、linux、mac 和 freebsd 上为 python 3.5+ 构建轮子,可以将它们上传到pypi并具有基本的 pypy 支持。
查看用户指南!
用法
您可以从最新版本下载二进制文件或使用 pip 安装它:
pip install maturin
有四个主要命令:
maturin new
创建一个配置了 maturin 的新货物项目。maturin publish
将 crate 构建到 python 包中并将它们发布到 pypi。maturin build
构建轮子并将它们存储在一个文件夹中(target/wheels
默认情况下),但不上传它们。可以使用twine或maturin upload
.maturin develop
构建 crate 并将其作为 python 模块直接安装在当前的 virtualenv 中。请注意,虽然maturin develop
速度更快,但它并不支持运行pip install
后maturin build
支持的所有功能。
pyo3
并且rust-cpython
绑定会被自动检测,对于 cffi 或您需要传递的二进制文件-b cffi
或-b bin
. maturin 不需要额外的配置文件,并且不会与现有的 setuptools-rust 或 milksnake 配置冲突。您甚至可以将它与诸如tox之类的测试工具集成。test-crates
文件夹中有不同绑定的示例。
包的名称将是货物项目的名称,即.[package]
部分中的名称字段Cargo.toml
。您在导入时使用的模块的名称将是name
该部分中的值[lib]
(默认为包的名称)。对于二进制文件,它只是 cargo 生成的二进制文件的名称。
Python打包基础
Python 包有两种格式:一种称为 wheel 和源分发 (sdist) 的构建形式,两者都是存档。轮子可以与任何 python 版本、解释器(主要是 cpython 和 pypy)、操作系统和硬件架构(对于纯 python 轮子)兼容,可以限制为特定的平台和架构(例如,使用 ctypes 或 cffi 时)或特定架构和操作系统上的特定 python 解释器和版本(例如,使用 pyo3 和 rust-cpython)。
在包上使用pip install
时,pip 会尝试找到匹配的轮子并安装它。如果找不到,它会下载源代码分发并为当前平台构建一个轮子,这需要安装正确的编译器。安装轮子比安装源分发要快得多,因为构建轮子通常很慢。
当你发布一个可以安装的包时pip install
,你将它上传到官方包存储库pypi。对于测试,您可以改用test pypi,您可以使用pip install --index-url https://test.pypi.org/simple/
. 请注意,对于 linux 发布,您需要使用 manylinux docker 容器,而对于从存储库发布,您可以使用messense/maturin-action github 操作。
pyo3 和 rust-cpython
对于 pyo3 和 rust-cpython,maturin 只能为已安装的 python 版本构建包。在 linux 和 mac 上,PATH
使用中的所有 python 版本。如果您不使用 设置自己的解释器-i
,则会使用启发式方法来搜索 python 安装。在 Windows 上,所有来自 python 启动器的版本(默认情况下由 python.org 安装程序安装)和除 base 之外的所有 conda 环境都被使用。您可以使用子命令检查选择了哪些版本list-python
。
pyo3 将在环境变量中设置使用的 python 解释器PYTHON_SYS_EXECUTABLE
,可以从自定义构建脚本中使用。Maturin 可以使用 pyo3 为 pypy 构建和上传轮子,即使只测试了 linux 上的 pypy3.7-7.3。
菲
Cffi 轮子与所有 python 版本兼容,包括 pypy。如果cffi
没有安装并且 python 在 virtualenv 中运行,maturin 将安装它,否则你必须自己安装它(pip install cffi
)。
maturin 使用 cbindgen 生成头文件,可以通过cbindgen.toml
项目根目录中的文件配置 cbindgen 来自定义头文件。或者,您可以使用将头文件写入$PROJECT_ROOT/target/header.h
.
基于头文件 maturin 生成一个模块,该模块导出一个ffi
和一个lib
对象。
自定义构建脚本示例
use cbindgen;
use std::env;
use std::path::Path;
fn main() {
let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
let bindings = cbindgen::Builder::new()
.with_no_includes()
.with_language(cbindgen::Language::C)
.with_crate(crate_dir)
.generate()
.unwrap();
bindings.write_to_file(Path::new("target").join("header.h"));
}
混合 rust/python 项目
要创建混合 rust/python 项目,请lib.name
在 Cargo.toml 旁边创建一个带有模块名称(即在 Cargo.toml 中)的文件夹,并在其中添加 python 源:
my-project
├── Cargo.toml
├── my_project
│ ├── __init__.py
│ └── bar.py
├── pyproject.toml
├── Readme.md
└── src
└── lib.rs
pyproject.toml
您可以通过设置tool.maturin.python-source
或Cargo.toml
通过设置指定不同的python源目录package.metadata.maturin.python-source
,例如
pyproject.toml
[tool.maturin]
python-source = "python"
货运.toml
[package.metadata.maturin]
python-source = "python"
那么项目结构将如下所示:
my-project
├── Cargo.toml
├── python
│ └── my_project
│ ├── __init__.py
│ └── bar.py
├── pyproject.toml
├── Readme.md
└── src
└── lib.rs
注意 建议使用此结构以避免常见的
ImportError
陷阱
maturin 会将本机扩展作为模块添加到您的 python 文件夹中。使用开发时,maturin 会将本地库和 cffi 的胶水代码复制到您的 python 文件夹。您应该将这些文件添加到您的 gitignore。
使用 cffi 你可以做from .my_project import lib
然后使用lib.my_native_function
,使用 pyo3/rust-cpython 你可以直接使用from .my_project import my_native_function
。
pyo3 后的示例布局maturin develop
:
my-project
├── Cargo.toml
├── my_project
│ ├── __init__.py
│ ├── bar.py
│ └── my_project.cpython-36m-x86_64-linux-gnu.so
├── Readme.md
└── src
└── lib.rs
Python 元数据
maturin 支持PEP 621,你可以在pyproject.toml
. maturin 合并来自Cargo.toml
and的元数据pyproject.toml
,pyproject.toml
优先于Cargo.toml
.
要指定 python 依赖项,请dependencies
在. 此列表等效于 setuptools:[project]
pyproject.toml
install_requires
[project]
name = "my-project"
dependencies = ["flask~=1.1.0", "toml==0.10.0"]
Pip 允许添加所谓的控制台脚本,它们是在您的程序中执行某些功能的 shell 命令。您可以在部分中添加控制台脚本[project.scripts]
。键是脚本名称,而值是格式为函数的路径some.module.path:class.function
,其中class
部分是可选的。该函数在没有参数的情况下被调用。例子:
[project.scripts]
get_42 = "my_project:DummyClass.get_42"
您还可以在 Cargo.toml 中指定 trove分类器project.classifiers
:
[project]
name = "my-project"
classifiers = ["Programming Language :: Python"]
源分布
maturin 支持通过pyproject.toml
. 要使用它,请使用以下内容pyproject.toml
在您的旁边创建一个:Cargo.toml
[build-system]
requires = ["maturin>=0.13,<0.14"]
build-backend = "maturin"
如果存在pyproject.toml
带有条目的 a,则当指定[build-system]
时,maturin 可以构建包的源代码分发。--sdist
源代码分发将包含与cargo package
. 要仅构建源分发,请--interpreter
不带任何值传递。
然后,您可以使用pip install .
. 与pip install . -v
您可以看到货物和成熟素的输出。
您可以使用 options compatibility
、skip-auditwheel
、和 common Cargo 构建选项bindings
,strip
例如直接运行 maturin 时的相同方式features
。[tool.maturin]
cffibindings
和 bin 项目需要密钥,因为这些项目无法自动检测到。目前,所有构建都处于发布模式(有关详细信息,请参阅此线程)。
对于带有 cffi 绑定的非 manylinux 构建,您可以使用以下内容:
[build-system]
requires = ["maturin>=0.13,<0.14"]
build-backend = "maturin"
[工具.maturin]
绑定= “cffi”
兼容性= “Linux”
manylinux
选项也被接受为compatibility
与旧版本的 maturin 向后兼容的别名。
要在 sdist 中包含任意文件以在编译期间使用,请指定sdist-include
为 glob 数组:
[tool.maturin]
sdist-include = ["path/**/*"]
有一个maturin sdist
命令仅用于构建源分发作为pypa/pip#6041的解决方法。
Manylinux和auditwheel
出于可移植性的原因,Linux 上的原生 python 模块必须只动态链接一组非常少的库,这些库基本上安装在任何地方,因此得名 manylinux。pypa 提供了特殊的 docker 映像和一个名为auditwheel的工具,以确保符合manylinux 规则。如果你想为 linux pypi 发布广泛使用的轮子,你需要使用 manylinux docker 镜像。
从 1.64 版本开始的 Rust 编译器至少需要 glibc 2.17,因此您至少需要使用 manylinux2014。对于发布,我们建议强制执行与带有 manylinux 标志的映像相同的 manylinux 版本,例如,--manylinux 2014
如果您正在构建quay.io/pypa/manylinux2014_x86_64
. 如果您设置 eg , messense/maturin-action github 操作已经解决了这个问题manylinux: 2014
。
maturin 包含 auditwheel 的重新实现,自动检查生成的库并提供正确的轮子。如果你系统的 glibc 太新或者你链接了其他共享库,它会分配linux
标签。您还可以手动禁用这些检查并直接使用原生 linux 目标--manylinux off
。
为了完全符合 manylinux,您需要在 CentOS docker 容器中编译。pyo3 /maturin映像基于 manylinux2014 映像,并将参数传递给maturin
二进制文件。你可以像这样使用它:
docker run --rm -v $(pwd):/io ghcr.io/pyo3/maturin build --release # or other maturin arguments
请注意,此图像非常基础,仅包含 python、maturin 和 stable rust。如果您需要其他工具,可以在 manylinux 容器中运行命令。有关小型教育示例,请参阅konstin/complex-manylinux-maturin-docker或有关真实世界设置的 nanoporetech/fast-ctc-decode。
当为 musl 目标编译时,maturin 本身与 manylinux 兼容。
贡献
欢迎大家为 maturin 做出贡献!支持项目的方式有很多,例如:
- 帮助成熟用户解决 GitHub 和 Gitter 上的问题
- 改进文档
- 编写功能和错误修正
- 发布博客和如何使用 maturin 的示例
如果您希望自愿为 maturin 提供时间并正在寻找从哪里开始,我们的贡献笔记有更多资源。
如果你没有时间贡献自己,但仍希望支持项目未来的成功,我们的一些维护者有 GitHub 赞助页面:
执照
获得以下任一许可:
- Apache 许可证,版本 2.0,(LICENSE-APACHE或http://www.apache.org/licenses/LICENSE-2.0)
- MIT 许可证(LICENSE-MIT或http://opensource.org/licenses/MIT)
由您选择。