- 开发工具
- 构建工具
【免费下载链接】maturin
Build and publish crates with pyo3, cffi and uniffi bindings as well as rust binaries as python packages
导读:maturin 是一个用于构建并发布 Python 包的工具,它把 Rust crate(通过 pyo3、cffi、uniffi 绑定,以及纯 Rust 二进制)打包成标准的 wheel 与 sdist 发行物。本文以官方用户指南(
guide/src/index.md,其中内嵌 README)为主线,完整梳理安装方式、三大核心命令、Python 打包基础、混合项目布局、PEP 621 元数据、源码发行版与 manylinux 兼容策略,并结合仓库源码说明底层实现,帮助读者一次性建立起使用 maturin 构建可发布 Python 包的全流程能力。
一、maturin 是什么
maturin(前身名为 pyo3-pack)是一个构建与发布工具:它支持将带有 pyo3、cffi、uniffi 绑定 的 crate,以及纯 Rust 二进制程序,以最小化配置的方式构建成 Python 包。它可以在 Windows、Linux、macOS 和 FreeBSD 上为 Python 3.8+ 构建 wheel,支持上传到 PyPI,并提供基础的 PyPy 与 GraalPy 支持。
从 源码入口 可以看到,maturin 的 CLI 定义了完整的命令集:build、publish、list-python、develop、sdist、init、new、generate-ci、upload、generate-stubs、pep517等,其中build与develop是日常开发最常用的两个命令。
maturin 不需要额外的配置文件,也不会与已有的 setuptools-rust 配置冲突。官方在test-crates目录下提供了针对不同绑定类型(pyo3、cffi、uniffi、bin)的完整示例工程,可供对照学习。
二、安装 maturin
官方用户指南在 安装章节 中提供了多种安装途径:
2.1 通过 pipx / uv / pip 安装
maturin 以 Python 二进制 wheel 的形式发布到 PyPI,推荐使用 pipx 或 uv 安装:
# pipx pipx install maturin # uv uv tool install maturin如果不想使用 pipx,pip install maturin也可以正常工作。
针对特定场景还有两个可选的附加依赖:
zig:使用 zig 作为链接器,便于交叉编译和实现 manylinux 兼容;patchelf:修复链接了其他共享库的 wheel。
例如安装 patchelf 依赖:pipx install maturin[patchelf]。
2.2 系统包管理器
- Homebrew(macOS):
brew install maturin。注意:Homebrew 安装会顺带安装一份独立的 Rust,如果你已经通过 rustup 安装了 Rust,会形成两份安装并可能产生冲突,此时建议改用其他方式安装; - conda(conda-forge 频道):先执行
conda config --add channels conda-forge和conda config --set channel_priority strict,再执行conda install maturin; - Alpine Linux:启用 community 仓库后执行
apk add maturin。
2.3 从源码构建
使用 cargo 从 crates.io 安装(带--locked保证依赖锁定):
cargo install --locked maturin也可以直接从 Git 仓库安装。
提示:如果从源码自行构建 maturin,且需要 SBOM(软件物料清单)支持,可参考 SBOM 章节 启用
sbomfeature。
三、三大核心命令
maturin 有三条主要命令(定义于 src/main.rs):
maturin new:创建一个已配置好 maturin 的 Cargo 项目;maturin build:构建 wheel 并存放于指定目录(默认是target/wheels),但不执行上传,适合产出可分发产物;maturin develop:构建 crate 并直接安装为当前 virtualenv 中的 Python 模块。注意:maturin develop更快,但支持的功能不如maturin build之后再用pip install完整。
使用maturin build和maturin develop时,可以添加-r或--release标志编译出性能优化版本。
包的名称取自 Cargo 项目的name(即Cargo.toml中[package]段的name字段);你在import时使用的模块名则是[lib]段的name值(默认为包名)。对于二进制程序,模块名就是 cargo 生成的二进制名称。
3.1maturin new快速创建项目
maturin new -b pyo3 guessing_game可以一键生成 pyo3 工程骨架,命令支持的选项包括:
Usage: maturin new [OPTIONS] <PATH> Arguments: <PATH> 项目路径 Options: --name <NAME> 设置生成的包名,默认使用目录名 --mixed 使用混合 Rust/Python 项目布局 --src 对混合项目使用 Python-first 的 src 布局 -b, --bindings <BINDINGS> 绑定类型:[pyo3, cffi, uniffi, bin]四、Python 打包基础:wheel 与 sdist
Python 包有两种格式(这一背景在 README 与用户指南的 项目布局、发行 章节中均有阐述):
- wheel:已构建的二进制发行物。wheel 可能对任意 Python 版本、解释器(主要是 CPython 和 PyPy)、操作系统和硬件架构通用(纯 Python wheel),也可能被限定到特定平台与架构(如使用 ctypes 或 cffi 时),或限定到特定架构与操作系统上的特定 Python 解释器与版本(如使用 pyo3 时);
- sdist:源码发行物(source distribution)。
当执行pip install时,pip 会先尝试寻找匹配的 wheel 并直接安装;找不到时才下载 sdist 并在当前平台现场构建 wheel,这要求本机装有正确的编译器。安装 wheel 远比安装 sdist 快,因为构建 wheel 通常很慢。
发布到pip install可用的包时,需要上传到官方包仓库 PyPI;测试阶段可使用 test PyPI(通过pip install --index-url https://test.pypi.org/simple/安装)。注意:要在 Linux 上发布(详见后面的 manylinux 章节),需要使用 manylinux Docker 容器或 zig 进行构建。
五、混合 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.rs):
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 develop时,maturin 会复制原生库(cffi 场景下还有胶水代码)到 Python 目录——这些生成的文件应当加入.gitignore。
导入方式上,cffi 可以from .my_project import lib后调用lib.my_native_function;pyo3 可以直接from .my_project import my_native_function。
5.1 将 Rust 模块作为项目的子模块导入
如果 Rust 生成的 Python 模块与混合项目中的 Python 包同名,IDE 可能会混淆。可以通过module-name = <包名>.<rust 模块名>让 Rust 扩展以子模块形式安装:
[tool.maturin] module-name = "my_project._my_project"同时更新lib.rs中的模块名,pyo3 绑定下还可以用#[pyo3(name = "_my_project")]注解:
#[pymodule] + #[pyo3(name = "_my_project")] fn my_project(...)随后在 Python 源码中导入:from my_project import _my_project。这样 IDE 就能把_my_project识别为独立的模块,某些 IDE 下还能获得 Rust 模块内类型的代码补全。
5.2 Python 类型信息(type stubs)
- 纯 Rust 项目:在项目根目录放一个
<module_name>.pyi文件,maturin 会自动把它连同必需的py.typed标记文件一起打包; - 混合项目:在 Python 包根目录自行添加
py.typed空文件,并把.pyi桩文件放在对应位置。
六、Python 元数据(PEP 621)
maturin 支持 PEP 621)。maturin 会合并Cargo.toml与pyproject.toml的元数据,pyproject.toml优先级更高。
6.1 声明 Python 依赖
在[project]段添加dependencies列表,等价于 setuptools 的install_requires:
[project] name = "my-project" dependencies = ["flask~=1.1.0", "toml>=0.10.2,<0.11.0"]6.2 添加 console scripts
[project.scripts]段可以声明可执行命令,键为脚本名,值为some.module.path:class.function格式(class部分可选,函数以无参方式调用):
[project.scripts] get_42 = "my_project:DummyClass.get_42"6.3 添加 trove classifiers
[project] name = "my-project" classifiers = ["Programming Language :: Python"]6.4 动态元数据
当pyproject.toml中没有[project]段时,maturin 会从Cargo.toml填充name、version(SemVer 转 PEP 440)、summary、description(取自package.readme指定的 README)、keywords、home_page、author、author_email、license、project_url等字段。
当存在[project]段时,必须至少包含name字段;按照规范,maturin 只能填充出现在project.dynamic列表中的字段。例如想让 Python 包版本跟随 Rust crate 版本,需要把version加入dynamic列表:
[project] name = "my-awesome-project" dynamic = [ "version", "description", "readme", "urls", "authors", "license", "keywords", ]七、源码发行版(sdist)与 PEP 517/518 集成
maturin 支持通过pyproject.toml走 PEP 517 构建流程。在Cargo.toml旁创建pyproject.toml并写入:
[build-system] requires = ["maturin>=1.0,<2.0"] build-backend = "maturin"当存在带[build-system]的pyproject.toml时,指定--sdist即可构建源码发行版,其内容与cargo package相同;只构建 sdist 时可使用maturin sdist命令。之后便可通过pip install .安装,加-v可以看到 cargo 与 maturin 的输出。
PEP 517 的 Python 侧实现位于 maturin/init.py,它通过子进程调用maturin pep517 build-wheel/write-sdist/write-dist-info,并支持通过MATURIN_PEP517_ARGS环境变量或 pip 的--config-settings传递额外参数。
在[tool.maturin]下可以像直接运行 maturin 一样使用compatibility、skip-auditwheel、bindings、strip以及features等 Cargo 构建选项。bindings键对 cffi 和 bin 项目是必需的,因为这两类无法自动检测。当前 PEP 517 构建均采用 release 模式。例如一个非 manylinux 的 cffi 构建:
[build-system] requires = ["maturin>=1.0,<2.0"] build-backend = "maturin" [tool.maturin] bindings = "cffi" compatibility = "linux"manylinux选项作为compatibility的别名保留,用于向后兼容旧版本。
要在 sdist 中包含编译所需的任意文件,可用带format的 glob 配置:
[tool.maturin] include = [{ path = "path/**/*", format = "sdist" }]八、Manylinux 与 auditwheel
出于可移植性考虑,Linux 上的原生 Python 模块只能动态链接一组几乎处处安装的库,这就是 manylinux 名称的由来(对应 发行章节 的完整说明)。如果想在 PyPI 发布广泛可用的 Linux wheel,必须使用 manylinux Docker 镜像或使用 zig 构建。
关键事实与策略:
- Rust 编译器自 1.64 起要求至少 glibc 2.17,因此至少要使用 manylinux2014;
- 发布时建议用 manylinux 标志强制与镜像一致的版本,例如在
quay.io/pypa/manylinux2014_x86_64中构建时使用--manylinux 2014; - maturin 内置了 auditwheel 的重新实现:自动检查生成的库并给 wheel 打上正确的平台标签。若系统 glibc 过新,或链接了其他共享库,则会被标记为
linux标签; - 可以使用
--manylinux off手动关闭检查,直接使用原生 Linux 目标; - 发布到 PyPI 时,
--compatibility pypi只允许构建 PyPI 接受的标签,拒绝不支持的 OS 与架构。
maturin build相关的兼容性选项完整清单(定义于 build_options.rs):
--compatibility <tag>:控制平台标签与 PyPI 兼容性,可取值包括pypi、manylinux标签(如manylinux2014/manylinux_2_24)、musllinux标签(如musllinux_1_2)以及原生linux标签。注意manylinux1与manylinux2010不受 Rust 编译器支持;原生linux标签会被 PyPI 拒绝,除非另行通过 auditwheel 验证。默认取可兼容的最低 manylinux 标签,无匹配时退回linux;--auditwheel <MODE>:取值为repair(审计并修复)、check(只检查不修复)、warn(告警不失败不修复)、skip(跳过检查);--zig:对 manylinux 目标使用 zig 保证所选 manylinux 版本的兼容性(需先pip install maturin[zig]);-o, --out <OUT>:wheel 输出目录,默认是项目 target 目录下新建的wheels目录。
官方提供的pyo3/maturinDocker 镜像基于 manylinux2014,并把参数透传给maturin二进制:
docker run --rm -v $(pwd):/io ghcr.io/pyo3/maturin build --release # 或其他 maturin 参数该镜像非常精简,只包含 python、maturin 和 stable Rust;需要额外工具时可以在 manylinux 容器内自行执行命令。
九、bindings 绑定类型
maturin 支持多种绑定类型(详见 bindings.md),其中部分可以自动检测,也可用-b/--bindings手动指定。自动检测逻辑在 src/bridge/detection.rs:通过cargo metadata分析依赖图,若存在pyo3/pyo3-ffi依赖则判定为 pyo3 绑定,存在uniffi依赖判定为 uniffi,存在 cdylib 目标但无 pyo3 依赖时判定为 cffi,只有 bin 目标时判定为 bin。
pyo3:Rust 的 Python 绑定,支持 CPython、PyPy 与 GraalPy。加入Cargo.toml依赖后 maturin 会自动检测。pyo3 绑定支持稳定 ABI(Py_LIMITED_API/abi3/abi3t),例如同时启用abi3-py310与abi3t-py315时,一次构建只会选择一种稳定 ABI 家族,想同时发布两种 wheel 需要分别构建(如maturin build --interpreter python3.10与maturin build --interpreter python3.15t);cffi:wheel 兼容包括 PyPy 在内的所有 Python 版本。若 virtualenv 中未安装cffi,maturin 会自动安装;否则需自行pip install cffi。maturin 使用 cbindgen 生成头文件,可通过项目根目录的cbindgen.toml定制,也可用 build 脚本把头文件写到$PROJECT_ROOT/target/header.h。cffi 不会被自动检测,除非项目中没有 pyo3 依赖;bin:把 Rust 二进制程序作为 Python 包分发,二进制以 "scripts" 形式进入 wheel,安装后出现在用户PATH(如 virtualenv 的bin目录)中。只有当项目只有 bin 目标、且无 pyo3 依赖或 cdylib 目标时才会自动检测。若同时发布二进制与库会让 wheel 体积翻倍,官方建议在库中暴露 CLI 函数并用 Python 入口点包装;uniffi:使用 uniffi-rs 从接口定义文件生成 Pythonctypes绑定,wheel 兼容包括 PyPy 在内的所有 Python 版本。
十、配置:[tool.maturin]关键选项
maturin 的全部配置都在pyproject.toml的tool.maturin段(完整说明见 config.md),并与 CLI 参数一一对应(配置解析与合并逻辑见 cargo_options.rs)。常用键包括:
| 配置键 | 说明 |
|---|---|
module-name | 扩展模块的 Python 导入名,支持my_package._native这类点分名称,将 Rust 扩展安装为子模块 |
python-source | Python 源码目录,默认src |
python-packages | 需要打包的 Python 包列表 |
bindings | 绑定类型:pyo3、pyo3-ffi、cffi、uniffi、bin |
compatibility | 控制平台标签与 PyPI 兼容性 |
auditwheel | auditwheel 模式:repair、check、warn、skip |
include/exclude | 额外包含/排除的文件,支持 glob,可指定format(sdist/wheel),还支持从build.rs的OUT_DIR引入生成文件 |
strip | 是否剥离库以减小体积 |
features | 激活的 Cargo features,支持按 Python 版本条件化(如{ feature = "pyo3/abi3-py311", python-version = ">=3.11" }) |
profile/editable-profile | Cargo 构建 profile,editable 构建可用editable-profile覆盖(默认回退到profile) |
data | wheel data 目录路径,默认使用项目根目录的<module-name>.data |
targets | 过滤要构建的 Cargo 编译目标(注意区别于[tool.maturin.target.<triple>]) |
pgo-command | PGO 性能剖析阶段执行的命令(配合--pgo) |
use-base-python | PEP 517 构建时使用基础 Python 解释器而非 venv 解释器,避免不必要的重编译 |
[tool.maturin.sbom] | SBOM 生成配置(rust、auditwheel、include三键) |
[tool.maturin.target.<triple>] | 目标架构专属选项,目前仅 macOS 的macos-deployment-target |
[tool.maturin.generate-ci.github] | maturin generate-ci的默认值(pytest、zig、trusted-publishing 等) |
十一、本地开发与导入钩子
11.1maturin develop
maturin develop默认以 debug 模式快速构建并安装到 virtualenv(命令详解见 local_development.md)。调试信息文件(.pdb、.dSYM、.dwp)默认随产物包含,除非使用--strip。常用选项包括--release、--extras(安装可选依赖)、--skip-install(仅原地构建扩展)、--uv(用 uv 替代 pip 安装)等。
maturin 自 v0.12.0 起支持 PEP 660 editable 安装:pip install -e .或maturin develop均可。editable 模式下 Python 源码修改即时生效(解释器直接在项目源码树中查找模块),配合导入钩子后 Rust 源码修改也能自动触发重编译。
11.2 maturin_import_hook
maturin_import_hook 提供在 Python 脚本导入 maturin 项目时自动重建的机制:Rust 组件的修改像 Python 组件一样即时生效,且消除了 Python 代码使用过期 Rust 组件的可能。安装与激活:
pip install maturin_import_hook python -m maturin_import_hook site installsite install会把它写入当前环境的sitecustomize.py,每次解释器启动自动激活(每个 virtualenv 只需执行一次);site uninstall可移除。也可以在单个脚本顶部手动调用maturin_import_hook.install()。
它只处理以 editable 方式(maturin develop或pip install -e)安装的 maturin 包,还支持直接导入独立的.rs文件(#[pymodule]名称必须与文件名一致),并支持importlib.reload()、多项目并发构建、路径依赖变更检测等特性。生产环境可用MATURIN_IMPORT_HOOK_ENABLED=0禁用,构建缓存可用MATURIN_BUILD_DIR指定位置。
十二、分发:交叉编译、GitHub Actions 与 SBOM
12.1 交叉编译
maturin 对pyo3与bin绑定有较好的交叉编译支持(见 distribution.md):
- Linux/macOS:可使用 manylinux-cross Docker 镜像;或自 v0.12.7 起使用
zig cc链接,maturin build --release --target aarch64-unknown-linux-gnu --zig; - Windows:pyo3 0.16.5+ 的
generate-import-lib特性可在无 Windows Python 库的情况下交叉编译扩展(0.29.0+ 通过 raw-dylib 链接直接支持);maturin 集成 cargo-xwin 自动下载 MSVC CRT 与 Windows SDK 头文件/导入库。
12.2 GitHub Actions
maturin generate-ci github可生成 GitHub Actions 工作流:
mkdir -p .github/workflows maturin generate-ci github > .github/workflows/CI.yml发布到 PyPI 时默认使用 API token 认证;在pyproject.toml中设置[tool.maturin.generate-ci.github] trusted-publishing = true即可改用 PyPI 可信发布(OIDC),生成的工作流将执行uv publish --trusted-publishing always。
12.3 SBOM
maturin 可以自动生成 CycloneDX SBOM 并放入 wheel 的.dist-info/sboms/目录(遵循 PEP 770,详见 sbom.md):Rust 依赖树 SBOM(通过 cargo-cyclonedx)、auditwheel 修复时植入的共享库对应的系统包 SBOM、以及自定义 SBOM 文件。生成与禁用均通过[tool.maturin.sbom]配置,--sbom-include命令行参数可在 CI 等场景追加文件。
十三、Sphinx 文档集成与平台支持
13.1 Sphinx / Read The Docs / Netlify
为 Rust 扩展模块配置 Sphinx 文档会稍显复杂(详见 sphinx.md)。要点是确保pyproject.toml能构建 sdist(pip install .可用),并在.readthedocs.yaml中声明同时安装 Rust 工具链与 Python:
version: 2 sphinx: builder: html build: os: "ubuntu-20.04" tools: python: "3.9" rust: "1.55" python: install: - method: pip path: .混合项目切记不要在 Sphinx 的conf.py中把项目路径加入sys.path。Netlify 场景则需在.netlify.toml中配置构建命令,并配套rust-toolchain、runtime.txt、requirements.txt文件。
13.2 平台支持范围
- 自动化测试:GitHub Actions 上测试 Windows、macOS、Linux(均 64 位 x86),FreeBSD 通过 Cirrus CI 测试;
- 发布产物目标:Windows 的 32/64 位 x86 与 arm64,Linux 的 x86、x86_64、armv7、aarch64、ppc64le(musl)与 s390x(gnu),macOS 的 x86_64 与 aarch64;
- Python 支持:CPython 3.8 至 3.14 经过 CI 测试,PyPy 3.8+ 与 GraalPy 23.0+ 可用;
- manylinux/musllinux:
manylinux2014及更新版本、musllinux_1_1及更新版本均受支持。
十四、源码结构速览
如果希望深入 maturin 内部实现,可以从以下仓库路径入手:
- src/main.rs:CLI 入口与全部子命令定义;
- src/build_options.rs:
BuildOptions,按“Python/绑定选项 → 平台标签与 auditwheel → 输出产物 → Cargo 选项 → 压缩选项”分层组织构建配置; - src/cargo_options.rs:
CargoOptions及与pyproject.toml配置的合并逻辑; - src/bridge/detection.rs:绑定类型自动检测、abi3/abi3t 稳定 ABI 推断;
- src/pyproject_toml.rs:
[tool.maturin]配置的 TOML 模型; - maturin/init.py:PEP 517 后端实现;
- test-crates/:覆盖 pyo3、cffi、uniffi、bin 各类绑定与各种项目布局的测试示例工程。
用户指南中的 迁移指南 记录了各版本间的破坏性变更(如 0.13 起 sdist 不再默认构建、改用--sdist;[package.metadata.maturin]迁移到[tool.maturin]等),变更日志 提供完整变更明细,贡献指南 说明了本地开发与测试流程(运行cargo test需要virtualenv与wasm32-wasip1目标)。
结语
从创建工程、本地开发、交叉编译到 manylinux 合规发布,maturin 把 Rust/Python 混合项目的构建发布链路收敛到了极简配置之下。本文以用户指南为骨架梳理了全流程的关键操作与底层原理;后续针对具体场景,建议按需深入阅读 教程(完整的 pyo3 猜数字游戏实战)、配置、环境变量 与 发行 等专题章节。
- 开发工具
- 构建工具
【免费下载链接】maturin
Build and publish crates with pyo3, cffi and uniffi bindings as well as rust binaries as python packages
相关推荐
PyO3/maturin 项目安装指南:全方位构建Python与Rust混合开发环境
PyO3/maturin 项目安装指南:全方位构建Python与Rust混合开发环境 前言 PyO3/maturin 是一个强大的工具链,用于构建和发布包含Ru
开发工具构建工具使用 Rye 开发 Rust Python 扩展模块:maturin 构建流程与混合项目实战指南
使用 Rye 开发 Rust Python 扩展模块:maturin 构建流程与混合项目实战指南 Rye 官方推荐使用 maturin https://link
开发工具CLImaturin 完整指南:用 Rust 构建并发布 Python 包(pyo3/cffi/uniffi 与二进制分发)
maturin 完整指南:用 Rust 构建并发布 Python 包(pyo3/cffi/uniffi 与二进制分发) 导读 maturin(前身 pyo3 p
开发工具构建工具
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考