Skip to main content

使用 pyo3、rust-cpython 和 cffi 绑定以及 rust 二进制文件作为 python 包构建和发布 crates

项目描述

成熟

以前是 pyo3-pack

操作状态 自由BSD 板条箱.io 派皮 Maturin 用户指南 在 Gitter 上聊天

使用 pyo3、rust-cpython 和 cffi 绑定以及 rust 二进制文件作为 python 包构建和发布 crates。

该项目旨在作为setuptools-rustmilksnake的零配置替代。它支持在 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默认情况下),但不上传它们。可以使用twinematurin upload.
  • maturin develop构建 crate 并将其作为 python 模块直接安装在当前的 virtualenv 中。请注意,虽然maturin develop速度更快,但它并不支持运行pip installmaturin 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 在 vi​​rtualenv 中运行,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-sourceCargo.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.tomland的元数据pyproject.tomlpyproject.toml优先于Cargo.toml.

要指定 python 依赖项,请dependencies在. 此列表等效于 setuptools:[project]pyproject.tomlinstall_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 compatibilityskip-auditwheel、和 common Cargo 构建选项bindingsstrip例如直接运行 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 赞助页面:

执照

获得以下任一许可:

由您选择。

项目详情