Project Icon

maturin

Rust与Python集成的高效构建与发布工具

Maturin是一款专门用于构建和发布Rust与Python集成项目的工具。它支持pyo3、cffi和uniffi绑定,能够将Rust crate和二进制文件打包为Python包。Maturin可在Windows、Linux、Mac和FreeBSD上为Python 3.8+构建wheels,支持上传至PyPI,并兼容PyPy和GraalPy。该工具简化了Rust和Python的集成过程,无需额外配置,与setuptools-rust和milksnake兼容。通过支持pyproject.toml构建,Maturin为开发者提供了灵活高效的跨语言开发解决方案。

Maturin

前身为 pyo3-pack

Maturin 用户指南 Crates.io PyPI Actions 状态 FreeBSD Discord 服务器

使用最小配置构建并发布带有 pyo3、cffi 和 uniffi 绑定的 crate,以及作为 Python 包的 Rust 二进制文件。 它支持为 Windows、Linux、Mac 和 FreeBSD 上的 Python 3.8+ 构建 wheel,可以将它们上传到 PyPI,并提供基本的 PyPy 和 GraalPy 支持。

查看用户指南

使用方法

你可以从最新发布版本下载二进制文件,或者使用 pipx 安装:

pipx install maturin

[!注意]

如果你不想使用 pipx,pip install maturin 也应该可以正常工作。

有四个主要命令:

  • maturin new 创建一个配置了 maturin 的新 Cargo 项目。
  • maturin publish 将 crate 构建成 Python 包并发布到 PyPI。
  • maturin build 构建 wheel 并将它们存储在一个文件夹中(默认为 target/wheels),但不上传它们。可以使用 twinematurin upload 上传这些 wheel。
  • maturin develop 构建 crate 并直接将其作为 Python 模块安装到当前虚拟环境中。请注意,虽然 maturin develop 速度更快,但它不支持在 maturin build 之后运行 pip install 所支持的所有功能。

系统会自动检测 pyo3 绑定。对于 cffi 或二进制文件,你需要传递 -b cffi-b bin。 maturin 不需要额外的配置文件,也不会与现有的 setuptools-rust 或 milksnake 配置冲突。 你甚至可以将其与测试工具(如 tox)集成。 test-crates 文件夹中有不同绑定的示例。

包的名称将是 Cargo 项目的名称,即 Cargo.toml[package] 部分的 name 字段。 模块的名称(即你在导入时使用的名称)将是 [lib] 部分的 name 值(默认为包的名称)。对于二进制文件,它就是 Cargo 生成的二进制文件的名称。

Python 打包基础

Python 包有两种格式: 一种是称为 wheel 的构建形式,另一种是源代码分发(sdist),两者都是归档文件。 wheel 可以与任何 Python 版本、解释器(主要是 CPython 和 PyPy)、操作系统和硬件架构兼容(对于纯 Python wheel), 也可以限制于特定平台和架构(例如使用 ctypes 或 cffi 时),或限制于特定操作系统和架构上的特定 Python 解释器和版本(例如使用 pyo3)。

当使用 pip install 安装包时,pip 会尝试找到匹配的 wheel 并安装它。如果找不到,它会下载源代码分发并为当前平台构建 wheel, 这需要安装正确的编译器。安装 wheel 比安装源代码分发要快得多,因为构建 wheel 通常很慢。

当你发布可以用 pip install 安装的包时,你会将其上传到官方包存储库 PyPI。 对于测试,你可以使用 Test PyPI,可以通过 pip install --index-url https://test.pypi.org/simple/ 使用。 注意,要为 Linux 发布,你需要使用 manylinux Docker 容器,而要从你的仓库发布,你可以使用 PyO3/maturin-action GitHub Action

pyo3

对于 pyo3,maturin 只能为已安装的 Python 版本构建包。在 Linux 和 Mac 上,会使用 PATH 中的所有 Python 版本。 如果你没有用 -i 设置自己的解释器,会使用一种启发式方法来搜索 Python 安装。 在 Windows 上,会使用 Python 启动器(Python.org 安装程序默认安装)中的所有版本和除 base 之外的所有 Conda 环境。你可以使用 list-python 子命令检查哪些版本被选中。

pyo3 会在环境变量 PYTHON_SYS_EXECUTABLE 中设置使用的 Python 解释器,可以从自定义构建脚本中使用。Maturin 可以为 PyPy 构建和上传带有 pyo3 的 wheel,尽管只在 Linux 上测试了 pypy3.7-7.3。

Cffi

Cffi wheel 与所有 Python 版本(包括 PyPy)兼容。如果没有安装 cffi 并且 Python 在虚拟环境中运行,maturin 会安装它,否则你必须自己安装(pip install cffi)。

maturin 使用 cbindgen 生成头文件,可以通过在项目根目录中的 cbindgen.toml 文件配置 cbindgen 来自定义。或者,你可以使用将头文件写入 $PROJECT_ROOT/target/header.h 的构建脚本。

基于头文件,maturin 生成一个导出 ffilib 对象的模块。

自定义构建脚本示例
use cbindgen;
use std::env;
use std::path::Path;

fn main() {
    let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
让我们创建一个 cbindgen::Builder 实例,并设置以下属性:

不包含任何头文件
使用 C 语言
使用指定的 crate 目录
生成绑定
将生成的绑定写入 target/header.h 文件

```rust
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 绑定使用 uniffi-rs 从接口定义文件生成 Python ctypes 绑定。uniffi wheels 兼容所有 Python 版本,包括 pypy。

混合 Rust/Python 项目

要创建混合 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

你可以在 pyproject.toml 中通过设置 tool.maturin.python-source 来指定不同的 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 会将原生库复制到 Python 文件夹中,对于 cffi 还会复制粘合代码。你应该将这些文件添加到 .gitignore 中。

使用 cffi 时,你可以执行 from .my_project import lib,然后使用 lib.my_native_function。使用 pyo3 时,你可以直接 from .my_project import my_native_function

使用 pyo3 后 maturin develop 的示例布局:

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(())
}

Python 元数据

maturin 支持 PEP 621,你可以在 pyproject.toml 中指定 Python 包元数据。 maturin 合并 Cargo.tomlpyproject.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.tomlproject.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 的输出。

你可以在 [tool.maturin] 下使用 compatibilityskip-auditwheelbindingsstrip 和常见的 Cargo 构建选项(如 features),就像直接运行 maturin 一样。 对于 cffi 和 bin 项目,bindings 键是必需的,因为这些无法自动检测。目前,所有构建都是在发布模式下进行的(详见此讨论)。

对于使用 cffi 绑定的非 manylinux 构建,你可以使用以下配置:

[build-system]
requires = ["maturin>=1.0,<2.0"]
build-backend = "maturin"

[tool.maturin]
bindings = "cffi"
compatibility = "linux"

为了向后兼容旧版本的 maturin,manylinux 选项也被接受作为 compatibility 的别名。

要在 sdist 中包含任意文件以供编译使用,请将 include 指定为 path glob 数组,并将 format 设置为 sdist:

[tool.maturin]
include = [{ path = "path/**/*", format = "sdist" }]

maturin sdist 命令用于仅构建源代码分发,作为 pypa/pip#6041 的解决方法。

Manylinux 和 auditwheel

出于可移植性考虑,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: 2014PyO3/maturin-action GitHub Action 已经会处理这个问题。

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  # 或其他 maturin 参数

请注意,这个镜像非常基础,只包含 Python、maturin 和稳定版 Rust。如果你需要其他工具,可以在 manylinux 容器内运行命令。 参见 konstin/complex-manylinux-maturin-docker 了解一个小型教育示例,或 nanoporetech/fast-ctc-decode 了解实际应用设置。

当为 musl 目标编译时,maturin 本身符合 manylinux 标准。

示例

  • ballista-python - 一个绑定到 Apache Arrow 分布式查询引擎 Ballista 的 Python 库
  • bleuscore - 一个纯 Rust 编写的 BLEU 评分计算库
  • chardetng-py - chardetng 字符编码检测器的 Python 绑定
  • connector-x - ConnectorX 使你能以最快和最内存高效的方式将数据从数据库加载到 Python 中
  • datafusion-python - 一个绑定到 Apache Arrow 内存查询引擎 DataFusion 的 Python 库
  • deltalake-python - 基于 delta-rs 的原生 Delta Lake Python 绑定,集成了 Pandas
  • opendal - OpenDAL Python 绑定,用于自由访问数据
  • orjson - 一个快速、正确的 Python JSON 库
  • polars - 用 Rust 编写的快速多线程 DataFrame 库 | Python | Node.js
  • pydantic-core - 用 Rust 编写的 pydantic 核心验证逻辑
  • pyrus-cramjam - Rust 压缩/解压缩算法的轻量级 Python 封装
  • pyxel - 一个 Python 复古游戏引擎
  • roapi - ROAPI 自动为静态数据集创建只读 API,无需编写任何代码
  • robyn - 一个快速且可扩展的异步 Python Web 服务器,具有 Rust 运行时
  • ruff - 一个用 Rust 编写的极快的 Python linter
  • tantivy-py - Tantivy 的 Python 绑定
  • watchfiles - Python 中简单、现代且高性能的文件监视和代码重载
  • wonnx - Wonnx 是一个 100% 用 Rust 编写的 GPU 加速 ONNX 推理运行时

贡献

欢迎所有人为 maturin 做出贡献!有很多方式可以支持这个项目,比如:

  • 在 GitHub 和 Gitter 上帮助 maturin 用户解决问题
  • 改进文档
  • 编写新功能和修复 bug
  • 发布有关如何使用 maturin 的博客和示例

如果你想贡献时间给 maturin 并在寻找从哪里开始,我们的贡献说明有更多资源。

如果你没有时间亲自贡献但仍希望支持项目的未来发展,我们的一些维护者有 GitHub 赞助页面:

许可证

根据以下两种许可之一授权:

由你选择。

项目侧边栏1项目侧边栏2
推荐项目
Project Cover

豆包MarsCode

豆包 MarsCode 是一款革命性的编程助手,通过AI技术提供代码补全、单测生成、代码解释和智能问答等功能,支持100+编程语言,与主流编辑器无缝集成,显著提升开发效率和代码质量。

Project Cover

AI写歌

Suno AI是一个革命性的AI音乐创作平台,能在短短30秒内帮助用户创作出一首完整的歌曲。无论是寻找创作灵感还是需要快速制作音乐,Suno AI都是音乐爱好者和专业人士的理想选择。

Project Cover

有言AI

有言平台提供一站式AIGC视频创作解决方案,通过智能技术简化视频制作流程。无论是企业宣传还是个人分享,有言都能帮助用户快速、轻松地制作出专业级别的视频内容。

Project Cover

Kimi

Kimi AI助手提供多语言对话支持,能够阅读和理解用户上传的文件内容,解析网页信息,并结合搜索结果为用户提供详尽的答案。无论是日常咨询还是专业问题,Kimi都能以友好、专业的方式提供帮助。

Project Cover

阿里绘蛙

绘蛙是阿里巴巴集团推出的革命性AI电商营销平台。利用尖端人工智能技术,为商家提供一键生成商品图和营销文案的服务,显著提升内容创作效率和营销效果。适用于淘宝、天猫等电商平台,让商品第一时间被种草。

Project Cover

吐司

探索Tensor.Art平台的独特AI模型,免费访问各种图像生成与AI训练工具,从Stable Diffusion等基础模型开始,轻松实现创新图像生成。体验前沿的AI技术,推动个人和企业的创新发展。

Project Cover

SubCat字幕猫

SubCat字幕猫APP是一款创新的视频播放器,它将改变您观看视频的方式!SubCat结合了先进的人工智能技术,为您提供即时视频字幕翻译,无论是本地视频还是网络流媒体,让您轻松享受各种语言的内容。

Project Cover

美间AI

美间AI创意设计平台,利用前沿AI技术,为设计师和营销人员提供一站式设计解决方案。从智能海报到3D效果图,再到文案生成,美间让创意设计更简单、更高效。

Project Cover

AIWritePaper论文写作

AIWritePaper论文写作是一站式AI论文写作辅助工具,简化了选题、文献检索至论文撰写的整个过程。通过简单设定,平台可快速生成高质量论文大纲和全文,配合图表、参考文献等一应俱全,同时提供开题报告和答辩PPT等增值服务,保障数据安全,有效提升写作效率和论文质量。

投诉举报邮箱: service@vectorlightyear.com
@2024 懂AI·鲁ICP备2024100362号-6·鲁公网安备37021002001498号