Setuptools-rust权威指南:Cargo.toml配置与项目结构最佳实践
Setuptools-rust权威指南:Cargo.toml配置与项目结构最佳实践
【免费下载链接】setuptools-rustSetuptools plugin for Rust support项目地址: https://gitcode.com/gh_mirrors/se/setuptools-rust
setuptools-rust是 setuptools 的官方级插件,让你能用 PyO3 或 rust-cpython 编写 Rust 扩展,然后像发布普通 C 扩展一样轻松打包、分发 Python 模块。本文是一份完整的Cargo.toml 配置与项目结构实战教程,无论你是刚接触 Rust+Python 混编的新手,还是想优化现有打包流程的开发者,都能从中找到可直接照抄的配置模板与避坑要点。全文不堆砌代码,只讲"怎么配、为什么这么配"。
一、为什么需要 setuptools-rust:快速理解它的作用
纯 Python 包用pip一条命令就能安装,但当你把性能敏感的代码用 Rust 重写后,就需要在安装时先编译 Rust 代码,再把它链接成 Python 能 import 的扩展模块。setuptools-rust 正是承担这个"桥梁"角色:
- 自动调用 Cargo 完成 Rust 编译;
- 把编译产物正确安装到 Python 包目录中;
- 支持扩展模块(extension module)与 Rust 可执行文件(binary)两种安装形态;
- 与虚拟环境、wheel 构建、sdist 源码包全流程无缝衔接。
它的核心价值可以用一句话概括:写扩展如写 C,打包如打包 C,但性能与内存安全由 Rust 保障。
二、最佳项目结构:python 与 rust 目录分离
项目结构是打包顺利的第一前提。官方推荐的目录布局刻意避开了src目录——因为 Python 生态和 Rust/Cargo 生态都默认把src当成自己的地盘,共用容易引发混乱。更稳妥的做法是显式分区,参考官方 hello-world 示例:
hello-world ├── Cargo.lock ├── Cargo.toml ├── MANIFEST.in ├── pyproject.toml ├── python │ └── hello_world │ └── __init__.py └── rust └── lib.rspython/:存放纯 Python 代码,通过[tool.setuptools.packages]的find指定查找位置;rust/:存放 Rust 源码,通过 Cargo.toml 的[lib].path指向具体文件。
这种分离让 Python 工具链与 Cargo 各管各的目录,互不干扰,也便于后续扩展。你可以参考examples/hello-world/、examples/hello-world-script/等官方示例目录查看完整实现。
三、pyproject.toml 核心配置:两处关键声明
3.1 声明构建依赖
在pyproject.toml的[build-system]中声明setuptools-rust,这是构建环境的"安装清单":
[build-system] requires = ["setuptools", "setuptools-rust"] build-backend = "setuptools.build_meta"requires列表会告诉 pip:构建本项目前,请先安装这两个依赖。
3.2 声明 Rust 扩展模块
[[tool.setuptools-rust.ext-modules]]是声明 Rust 扩展的入口,每个条目对应一个 Rust 扩展模块:
[[tool.setuptools-rust.ext-modules]] target = "hello_world._lib" # Python 侧导入路径 path = "Cargo.toml" # Cargo 清单文件,默认值可省略 binding = "PyO3" # 绑定类型,默认 PyO3target的写法有讲究:最后一段必须与 Cargo.toml 中[lib].name一致,前面的前缀用于把模块嵌套进 Python 包。例如target = "hello_world._lib"意味着最终生成hello_world/_lib,用户用import hello_world._lib即可导入。
如果希望同时安装 Rust 编写的命令行工具,则使用[[tool.setuptools-rust.bins]],并在 Cargo.toml 中用[[bin]]声明可执行目标,参考examples/hello-world-script/pyproject.toml的写法。
四、Cargo.toml 配置:与 pyproject.toml 一一对应
Cargo.toml 是 Rust 侧的配置中心,其中[lib]表必须与 pyproject.toml 中的扩展模块声明严格对齐:
[lib] name = "_lib" # 与 target 最后一段一致 path = "rust/lib.rs" # 指向 rust 目录下的源文件 crate-type = ["cdylib"] # 必须!生成 Python 可加载的动态库[dependencies] pyo3 = "0.28"三个最容易踩坑的点:
crate-type = ["cdylib"]不能漏,否则编译产物不是共享库,Python 无法加载;[lib].name与target末尾必须匹配,且通常建议加下划线前缀(如_lib),表示这是"私有实现模块",避免与 Python 包名冲突;[lib].path要正确指向rust/目录下的文件,这是目录分离结构的关键衔接。
Rust 侧依赖 PyO3 时,建议锁定大版本(如pyo3 = "0.28"),以获得稳定的 API 与工具链兼容性。
五、MANIFEST.in:别让源码包漏掉 Rust 文件
当你发布 sdist 源码包时,默认清单并不包含 Cargo.toml 与 Rust 源文件。必须通过MANIFEST.in显式声明,否则用户从源码包安装时会直接构建失败:
include Cargo.toml recursive-include rust *.rs这个文件虽小,却是"发布到 PyPI 后别人能否装成功"的关键。官方仓库中的MANIFEST.in与examples/各示例的对应文件都可以作为参考。
六、安装与验证:三分钟跑通全流程
配置完成后,在项目根目录执行标准流程即可验证:
python -m venv .venv source .venv/bin/activate # Windows 使用 .venv\Scripts\activate python -m pip install -e . python -c "import hello_world; print(hello_world.__doc__)"安装成功后还能用pip wheel .构建 wheel 包,用python -m build一键产出可分发的发行包。在本地inplace开发模式下,setuptools-rust 默认走 debug 构建;而install与wheel构建时自动切换为 release,无需手工干预。
七、进阶技巧:五个值得收藏的配置细节
- 切换构建 profile:通过环境变量
SETUPTOOLS_RUST_CARGO_PROFILE覆盖默认的release,例如设为dev可强制 debug 构建,方便调试崩溃与符号信息; - 为 Cargo 传额外参数:在
ext-modules中配置args(如args = ["--no-default-features"])或features,实现特性开关控制; - Rust 可执行文件安装:使用
[[tool.setuptools-rust.bins]]声明target与args,参考examples/hello-world/pyproject.toml中release-ltoprofile 的用法,可显著减小二进制体积; - 旧式 setup.py 方案:若需要复杂构建逻辑,可用
RustExtension类在setup.py中命令式配置,参考examples/hello-world-setuppy/setup.py与源码中的setuptools_rust/extension.py; - 跨平台 wheel 构建:配合
cibuildwheel或 manylinux Docker 容器可产出多平台二进制 wheel,构建细节参考官方docs/building_wheels.md文档。
八、写在最后:一套模板走天下
总结一套可复用的最小模板:目录分离(python/ 与 rust/)+ pyproject.toml 双声明 + Cargo.toml 的 cdylib 对齐 + MANIFEST.in 补全文件。把这四步做好,你的 Rust 扩展项目就具备了专业的打包基础,无论后续发布到 PyPI、接入 CI 还是支持多平台,都能平稳运行。现在,就用这份指南为你的项目添上 Rust 的翅膀吧!🚀
【免费下载链接】setuptools-rustSetuptools plugin for Rust support项目地址: https://gitcode.com/gh_mirrors/se/setuptools-rust
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考