以前的 pyo3-pack
使用 pyo3、cffi 和 uniffi 绑定以及 rust 二进制文件以最少的配置构建和发布 crates 作为 python 包。它支持在 windows、linux、mac 和 freebsd 上为 python 3.8+ 构建轮子,可以将它们上传到 pypi,并具有基本的 pypy 和 graalpy 支持。
查看用户指南!
您可以从最新版本下载二进制文件或使用 pipx 安装它:
pipx install maturin
笔记
如果您不想使用 pipx, 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
速度更快,但它并不支持在maturin build
之后运行pip install
支持的所有功能。 pyo3
结合会自动检测。对于 cffi 或二进制文件,您需要传递-b cffi
或-b bin
。 maturin 不需要额外的配置文件,并且不会与现有的 setuptools-rust 或 milksnake 配置发生冲突。您甚至可以将其与 tox 等测试工具集成。 test-crates
文件夹中有不同绑定的示例。
包的名称将是货物项目的名称,即Cargo.toml
的[package]
部分中的名称字段。导入时使用的模块的名称将是[lib]
部分中的name
值(默认为包的名称)。对于二进制文件,它只是由 Cargo 生成的二进制文件的名称。
使用maturin build
和maturin develop
命令时,可以通过添加-r
或--release
标志来编译性能优化的程序。
Python 包有两种格式:称为wheel 的构建形式和源发行版(sdist),两者都是存档。轮子可以与任何Python版本、解释器(主要是cpython和pypy)、操作系统和硬件架构(对于纯Python轮子)兼容,可以限于特定的平台和架构(例如,当使用ctypes或cffi时)或特定架构和操作系统上的特定 python 解释器和版本(例如 pyo3)。
在软件包上使用pip install
时,pip 会尝试找到匹配的wheel并安装它。如果找不到,它会下载源代码发行版并为当前平台构建一个轮子,这需要安装正确的编译器。安装轮子比安装源发行版要快得多,因为构建轮子通常很慢。
当您发布可使用pip install
安装的包时,请将其上传到官方包存储库 pypi。对于测试,您可以使用 test pypi 代替,您可以将其与pip install --index-url https://test.pypi.org/simple/
一起使用。请注意,要针对 Linux 进行发布,您需要使用 Manylinux docker 容器,而要从存储库进行发布,您可以使用 PyO3/maturin-action github 操作。
对于 pyo3,maturin 只能为已安装的 python 版本构建包。在linux和mac上,使用PATH
中的所有python版本。如果您没有使用-i
设置自己的解释器,则会使用启发式搜索 python 安装。在 Windows 上,使用 python 启动器(默认情况下由 python.org 安装程序安装)的所有版本以及除 base 之外的所有 conda 环境。您可以使用list-python
子命令检查选择了哪些版本。
pyo3 将在环境变量PYTHON_SYS_EXECUTABLE
中设置使用的 python 解释器,可以从自定义构建脚本中使用它。 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" ) ) ;
}
uniffi 绑定使用 uniffi-rs 从接口定义文件生成 Python ctypes
绑定。 uniffi 轮子与所有 python 版本兼容,包括 pypy。
要创建混合 rust/python 项目,请在 Cargo.toml 旁边创建一个包含模块名称(即 Cargo.toml 中的lib.name
)的文件夹,并在其中添加 Python 源:
my-project
├── Cargo.toml
├── my_project
│ ├── __init__.py
│ └── bar.py
├── pyproject.toml
├── README.md
└── src
└── lib.rs
您可以通过设置tool.maturin.python-source
在pyproject.toml
中指定不同的 python 源目录,例如
pyproject.toml
[ tool . maturin ]
python-source = " python "
module-name = " my_project._lib_name "
那么项目结构将如下所示:
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 您可以直接from .my_project import my_native_function
。
maturin develop
后使用 pyo3 的示例布局:
my-project
├── Cargo.toml
├── my_project
│ ├── __init__.py
│ ├── bar.py
│ └── _lib_name.cpython-36m-x86_64-linux-gnu.so
├── README.md
└── src
└── lib.rs
执行此操作时,还要确保在代码中设置模块名称以匹配module-name
的最后部分(不包括包路径):
# [ pymodule ] # [ pyo3 ( name= "_lib_name" ) ] fn my_lib_name ( _py : Python < ' _ > , m : & PyModule ) -> PyResult < ( ) > { m . add_class :: < MyPythonRustClass > ( ) ? ; Ok ( ( ) ) }
maturin 支持 PEP 621,您可以在pyproject.toml
中指定 python 包元数据。 maturin 合并来自Cargo.toml
和pyproject.toml
的元数据, pyproject.toml
优先于Cargo.toml
。
要指定 python 依赖项,请在pyproject.toml
的[project]
部分中添加dependencies
列表。此列表相当于 setuptools 中的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 "
您还可以在pyproject.toml
中的project.classifiers
下指定 trove 分类器:
[ project ]
name = " my-project "
classifiers = [ " Programming Language :: Python " ]
maturin 支持通过pyproject.toml
进行构建。要使用它,请在Cargo.toml
旁边创建一个包含以下内容的pyproject.toml
:
[ build-system ]
requires = [ " maturin>=1.0,<2.0 " ]
build-backend = " maturin "
如果存在带有[build-system]
条目的pyproject.toml
,则在指定--sdist
时,maturin 可以构建包的源发行版。源发行版将包含与cargo package
相同的文件。要仅构建源发行版,请传递--interpreter
而不带任何值。
然后,您可以使用pip install .
。使用pip install . -v
可以看到cargo和maturin的输出。
您可以使用compatibility
、 skip-auditwheel
、 bindings
、 strip
和通用 Cargo 构建选项(例如[tool.maturin]
下的features
),就像直接运行 maturin 时一样。 cffi 和 bin 项目需要bindings
密钥,因为这些项目无法自动检测到。目前,所有版本都处于发布模式(有关详细信息,请参阅此线程)。
对于带有 cffi 绑定的 non-manylinux 构建,您可以使用以下命令:
[ build-system ]
requires = [ " maturin>=1.0,<2.0 " ]
build-backend = " maturin "
[ tool . maturin ]
bindings = " cffi "
compatibility = " linux "
manylinux
选项也被接受作为compatibility
的别名,以向后兼容旧版本的 maturin。
要在 sdist 中包含任意文件以供编译期间使用, include
为format
设置为sdist
的path
glob 数组:
[ tool . maturin ]
include = [{ path = " path/**/* " , format = " sdist " }]
有一个maturin sdist
命令仅用于构建源发行版作为 pypa/pip#6041 的解决方法。
出于可移植性的原因,Linux 上的本机 Python 模块只能动态链接一组非常少的库,这些库基本上安装在任何地方,因此被称为“manylinux”。 pypa 提供特殊的 docker 镜像和一个名为auditwheel 的工具,以确保遵守manylinux 规则。如果你想为 linux pypi 发布广泛可用的wheel,你需要使用 Manylinux docker 镜像。
从1.64版本开始的Rust编译器至少需要glibc 2.17,所以你至少需要使用manylinux2014。对于发布,我们建议使用与带有 Manylinux 标志的映像相同的 ManyLinux 版本,例如,如果您在quay.io/pypa/manylinux2014_x86_64
中构建,请使用--manylinux 2014
。如果您设置例如manylinux: 2014
PyO3/maturin-action github 操作已经处理了这个问题。
maturin 包含auditwheel 的重新实现,自动检查生成的库并为wheel 提供正确的平台标签。如果你的系统的glibc太新或者你链接了其他共享库,它会分配linux
标签。您还可以手动禁用这些检查并通过--manylinux off
直接使用本机 linux 目标。
为了完全符合 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做出贡献!支持该项目的方式有很多,例如:
如果您希望为 Maturin 提供志愿服务并正在寻找从哪里开始,我们的贡献笔记有更多资源。
如果您没有时间做出贡献,但仍希望支持项目未来的成功,我们的一些维护人员有 GitHub 赞助页面:
获得以下任一许可:
由您选择。