PyO3/maturin

GitHub: PyO3/maturin

一款简化 Rust 到 Python 扩展构建与发布流程的工具,支持多种绑定方式和跨平台 wheel 打包。

Stars: 5434 | Forks: 383

# Maturin _原名 pyo3-Pack_ [![Maturin 用户指南](https://img.shields.io/badge/user-guide-brightgreen?logo=readthedocs&style=flat-square)](https://maturin.rs) [![Crates.io](https://img.shields.io/crates/v/maturin.svg?logo=rust&style=flat-square)](https://crates.io/crates/maturin) [![PyPI](https://img.shields.io/pypi/v/maturin.svg?logo=python&style=flat-square)](https://pypi.org/project/maturin) [![discord 服务器](https://img.shields.io/discord/1209263839632424990?logo=discord&style=flat-square)](https://discord.gg/33kcChzH7f) 构建并发布带有 [pyo3, cffi 和 uniffi bindings](https://maturin.rs/bindings) 的 crate,以及作为 Python 包的 Rust 二进制文件,只需极简的配置。 它支持为 Windows、Linux、macOS 和 FreeBSD 上的 Python 3.8+ 构建 wheel,可以将它们上传到 [pypi](https://pypi.org/),并具有基本的 PyPy 和 GraalPy 支持。 查看 [用户指南](https://maturin.rs/)! ## 用法 你可以从 [最新版本](https://github.com/PyO3/maturin/releases/latest) 下载二进制文件,或者使用 [pipx](https://pypa.github.io/pipx/) 或 [uv](https://github.com/astral-sh/uv) 安装: ``` # pipx pipx install maturin # uv uv tool install maturin ``` 主要有三个命令: - `maturin new` 创建一个配置了 maturin 的新 cargo 项目。 - `maturin build` 构建 wheel 并将其存储在一个文件夹中(默认为 `target/wheels`),但不会上传它们。建议使用 [uv](https://github.com/astral-sh/uv) 通过 `uv publish` 来发布包。 - `maturin develop` 构建 crate 并将其作为 python 模块直接安装在当前的 virtualenv 中。请注意,虽然 `maturin develop` 更快,但它不支持 `maturin build` 后运行 `pip install` 所支持的所有功能。 maturin 不需要额外的配置文件,也不会与现有的 setuptools-rust 配置冲突。 你甚至可以将其与 [tox](https://tox.readthedocs.io/en/latest/) 等测试工具集成。 `test-crates` 文件夹中有不同 bindings 的示例。 包的名称将是 cargo 项目的名称,即 `Cargo.toml` 中 `[package]` 部分的 name 字段。 你导入时使用的模块名称,将是 `[lib]` 部分中的 `name` 值(默认为包的名称)。对于二进制文件,它只是 cargo 生成的二进制文件的名称。 使用 `maturin build` 和 `maturin develop` 命令时,可以通过添加 `-r` 或 `--release` 标志来编译性能优化的程序。 ## Python 打包基础知识 Python 包有两种格式: 一种称为 wheel 的构建形式和源代码分发 (sdist),两者都是归档文件。 wheel 可以兼容任何 python 版本、解释器(主要是 cpython 和 pypy)、操作系统和硬件架构(对于纯 python wheel), 可以限于特定的平台和架构(例如使用 ctypes 或 cffi 时),或者限于特定架构和操作系统上的特定 python 解释器和版本(例如使用 pyo3 时)。 当对包使用 `pip install` 时,pip 会尝试找到匹配的 wheel 并安装它。如果没有找到,它会下载源代码分发并为当前平台构建 wheel, 这需要安装正确的编译器。安装 wheel 比安装源代码分发要快得多,因为构建 wheel 通常很慢。 当你发布一个可以通过 `pip install` 安装的包时,你需要将其上传到 [pypi](https://pypi.org/),即官方包仓库。 为了测试,你可以改用 [test pypi](https://test.pypi.org/),可以通过 `pip install --index-url https://test.pypi.org/simple/` 来使用它。 请注意,对于[为 linux 发布](#manylinux-and-auditwheel),你需要使用 manylinux docker 容器或 zig,而从你的仓库发布时,你可以使用 [PyO3/maturin-action](https://github.com/PyO3/maturin-action) github action。 ## 混合 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 ``` maturin 会将原生扩展作为模块添加到你的 python 文件夹中。使用 develop 时,maturin 会将原生库复制到你的 python 文件夹,对于 cffi 还会复制胶水代码。你应该将这些文件添加到你的 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(m: &Bound<'_, PyModule>) -> PyResult<()> { m.add_class::()?; Ok(()) } ``` ## Python 元数据 maturin 支持 [PEP 621](https://www.python.org/dev/peps/pep-0621/),你可以在 `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.2,<0.11.0"] ``` 你可以添加所谓的控制台脚本,它们是在 `[project.scripts]` 部分执行程序中某些功能的 shell 命令。 键是脚本名称,而值是函数的路径,格式为 `some.module.path:class.function`,其中 `class` 部分是可选的。该函数在无参数情况下被调用。示例: ``` [project.scripts] get_42 = "my_project:DummyClass.get_42" ``` 你也可以在 `pyproject.toml` 的 `project.classifiers` 下指定 [trove classifiers](https://pypi.org/classifiers/): ``` [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]` 下使用选项 `compatibility`、`skip-auditwheel`、`bindings`、`strip` 和常见的 Cargo 构建选项(如 `features`),方式与直接运行 maturin 时相同。 `bindings` 键对于 cffi 和 bin 项目是必需的,因为这些无法自动检测。目前,所有构建都在发布模式下进行(有关详细信息,请参阅[此主题](https://discuss.python.org/t/pep-517-debug-vs-release-builds/1924))。 对于带有 cffi bindings 的非 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](https://github.com/pypa/pip/issues/6041) 的变通方法。 ## Manylinux 和 auditwheel 出于可移植性原因,Linux 上的原生 python 模块必须仅动态链接极少数基本到处都安装的库集,因此得名 manylinux。 pypa 提供特殊的 docker 镜像和一个名为 [auditwheel](https://github.com/pypa/auditwheel/) 的工具来确保符合 [manylinux 规则](https://peps.python.org/pep-0599/#the-manylinux2014-policy)。 如果你想为 linux pypi 发布广泛可用的 wheel,**你需要使用 manylinux docker 镜像或使用 zig 构建**。 自 1.64 版本起,Rust 编译器[至少需要 glibc 2.17](https://blog.rust-lang.org/2022/08/01/Increasing-glibc-kernel-requirements.html),因此你需要至少使用 manylinux2014。 对于发布,我们建议使用 manylinux 标志强制执行与镜像相同的 manylinux 版本,例如,如果你在 `quay.io/pypa/manylinux2014_x86_64` 中构建,请使用 `--manylinux 2014`。 如果你设置例如 `manylinux: 2014`,[PyO3/maturin-action](https://github.com/PyO3/maturin-action) github action 已经处理了这个问题。 maturin 包含 auditwheel 的重新实现,会自动检查生成的库并为 wheel 提供适当的平台标签。 如果你系统的 glibc 太新或者你链接了其他共享库,它将分配 `linux` 标签。 你也可以手动禁用这些检查,并使用 `--manylinux off` 直接使用原生 linux 目标。 为了完全符合 manylinux,你需要在 CentOS docker 容器中编译。[pyo3/maturin](https://ghcr.io/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](https://github.com/konstin/complex-manylinux-maturin-docker);有关真实世界的设置,请参阅 [nanoporetech/fast-ctc-decode](https://github.com/nanoporetech/fast-ctc-decode/blob/b226ea0f2b2f4f474eff47349703d57d2ea4801b/.github/workflows/publish.yml)。 当为 musl 目标编译时,maturin 本身是符合 manylinux 的。 ## 示例 - [agg-python-bindings](https://pypi.org/project/agg-python-bindings) - 一个绑定到 Asciinema Agg 终端记录渲染器和 Avt 终端模拟器的 Python 库 - [ballista-python](https://github.com/apache/arrow-ballista-python) - 一个绑定到 Apache Arrow 分布式查询引擎 Ballista 的 Python 库 - [bleuscore](https://github.com/shenxiangzhuang/bleuscore) - 一个 BLEU 分数计算库,用纯 Rust 编写 - [chardetng-py](https://github.com/john-parton/chardetng-py) - chardetng 字符编码检测器的 Python 绑定。 - [connector-x](https://github.com/sfu-db/connector-x/tree/main/connectorx-python) - ConnectorX 使你能够以最快和最节省内存的方式将数据从数据库加载到 Python - [datafusion-python](https://github.com/apache/arrow-datafusion-python) - 一个绑定到 Apache Arrow 内存查询引擎 DataFusion 的 Python 库 - [deltalake-python](https://github.com/delta-io/delta-rs/tree/main/python) - 基于 delta-rs 的原生 Delta Lake Python 绑定,带有 Pandas 集成 - [opendal](https://github.com/apache/incubator-opendal/tree/main/bindings/python) - 自由访问数据的 OpenDAL Python 绑定 - [orjson](https://github.com/ijl/orjson) - 一个快速、正确的 Python JSON 库 - [polars](https://github.com/pola-rs/polars/tree/master/py-polars) - Rust | Python | Node.js 中快速的多线程 DataFrame 库 - [pydantic-core](https://github.com/pydantic/pydantic-core) - 用 Rust 编写的 pydantic 核心验证逻辑 - [pyrus-cramjam](https://github.com/milesgranger/pyrus-cramjam) - 用于 Rust 中解/压缩算法的轻量级 Python 封装 - [pyxel](https://github.com/kitao/pyxel) - 一个 Python 复古游戏引擎 - [roapi](https://github.com/roapi/roapi) - ROAPI 自动为静态数据集启动只读 API,无需你编写一行代码 - [robyn](https://github.com/sansyrox/robyn) - 具有 Rust 运行时的快速且可扩展的异步 python web 服务器 - [ruff](https://github.com/charliermarsh/ruff) - 一个极快的 Python linter,用 Rust 编写 - [rnet](https://github.com/0x676e67/rnet) - 具有 Black Magic 的异步 Python HTTP 客户端 - [rustpy-xlsxwriter](https://github.com/rahmadafandi/rustpy-xlsxwriter): 一个用于生成 Excel 文件的高性能 Python 库,利用 [rust_xlsxwriter](https://github.com/jmcnamara/rust_xlsxwriter) crate 进行高效数据处理。 - [tantivy-py](https://github.com/quickwit-oss/tantivy-py) - Tantivy 的 Python 绑定 - [tpchgen-cli](https://github.com/clflushopt/tpchgen-rs/tree/main/tpchgen-cli) - `tpchgen` 的 Python CLI 绑定,这是一个用纯 Rust 构建且零依赖的极快 TPC-H 基准数据生成器。 - [watchfiles](https://github.com/samuelcolvin/watchfiles) - python 中简单、现代和高性能的文件监视和代码重载 - [wonnx](https://github.com/webonnx/wonnx/tree/master/wonnx-py) - Wonnx 是一个用 100% Rust 编写的 GPU 加速 ONNX 推理运行时 ## 许可证 根据以下之一许可: - Apache License, Version 2.0, ([LICENSE-APACHE](https://github.com/PyO3/maturin/blob/main/license-apache) 或 http://www.apache.org/licenses/LICENSE-2.0) - MIT license ([LICENSE-MIT](https://github.com/PyO3/maturin/blob/main/license-mit) 或 http://opensource.org/licenses/MIT) 你选择。
标签:cffi, CLI, FFI, PyO3, PyPI, Python, Rust, SOC Prime, UniFFI, WiFi技术, 二进制, 可视化界面, 库, 应急响应, 开发工具, 性能优化, 打包工具, 无后门, 构建系统, 检测绕过, 混合编程, 绑定, 网络流量审计, 网络调试, 自动化, 请求拦截, 轮子, 逆向工具, 通知系统, 通知系统