10分钟上手Setuptools-rust:从安装到构建第一个Rust-Python扩展
想让你的 Python 项目跑得飞快?setuptools-rust 就是连接 Python 与 Rust 的桥梁——它作为 setuptools 的插件,让你能用 Rust 编写 Python 扩展模块,并用标准的 pip 命令完成构建与安装。本教程将带你 10 分钟从零开始,构建并运行你的第一个 Rust-Python 扩展,全程不需要写一行 C 代码。🚀
为什么你需要 setuptools-rust?
Python 的优点是开发效率高,但遇到 CPU 密集型的计算任务时性能往往不尽如人意。Rust 则兼具 C 语言的性能与内存安全。借助 setuptools-rust 与 PyO3 绑定库,你可以:
- 用 Rust 编写扩展函数,在 Python 中直接
import调用,性能接近原生 C 扩展; - 复用 setuptools 成熟的打包、发布、wheel 构建流程,无需学习新的构建工具;
- 天然支持 Linux、macOS、Windows,还能做交叉编译。
官方推荐使用 pyproject.toml 声明式配置,简单直观;如果你需要更复杂的构建逻辑,也支持在 setup.py 中通过 RustExtension 类进行编程式配置(参考 setuppy_tutorial.md)。
第一步:安装前置工具
在开始前,请确认你的电脑上已安装:
- Python 3.9 及以上版本,并确保
pip可用; - Rust 工具链(含
cargo),未安装的话执行以下命令:curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
检查版本:
python --version
cargo --version
第二步:创建项目目录结构
我们参照官方示例 hello-world 来搭建项目。为了不让 Python 和 Rust 争抢 src 目录,官方约定将 Python 代码放在 python/,Rust 代码放在 rust/:
hello-world
├── python
│ └── hello_world
│ └── __init__.py
├── rust
│ └── lib.rs
├── Cargo.toml
├── MANIFEST.in
└── pyproject.toml
也可以直接克隆官方仓库获取完整示例:
git clone https://gitcode.com/gh_mirrors/se/setuptools-rust
示例代码位于 examples/hello-world 目录下。
第三步:用 PyO3 编写 Rust 扩展代码
在 rust/lib.rs 中编写一个将两个整数相加并返回字符串的函数:
use pyo3::prelude::*;
#[pymodule]
mod _lib {
use pyo3::prelude::*;
/// 将两数之和格式化为字符串
#[pyfunction]
fn sum_as_string(a: usize, b: usize) -> PyResult<String> {
Ok((a + b).to_string())
}
}
注意:#[pymodule] 下的模块名 _lib 必须与 Cargo.toml 中 [lib] 的 name 保持一致,否则 Python 无法导入。
第四步:配置 Cargo.toml 编译目标
在 Cargo.toml 中声明依赖与动态库类型:
[package]
name = "hello-world"
version = "0.1.0"
edition = "2021"
[dependencies]
pyo3 = "0.28"
[lib]
name = "_lib" # 必须与 #[pymodule] 模块名一致
crate-type = ["cdylib"] # 生成 Python 可导入的动态链接库
path = "rust/lib.rs"
第五步:在 pyproject.toml 中挂载 Rust 扩展
这是 setuptools-rust 最核心的一步。在 pyproject.toml 中声明构建依赖,并通过 [[tool.setuptools-rust.ext-modules]] 指定 Rust 扩展模块:
[build-system]
requires = ["setuptools", "setuptools-rust"]
build-backend = "setuptools.build_meta"
[project]
name = "hello-world"
version = "1.0"
[tool.setuptools.packages]
find = { where = ["python"] }
[[tool.setuptools-rust.ext-modules]]
target = "hello_world._lib" # 扩展被嵌套进 hello_world 包
binding = "PyO3" # 默认值,可省略
💡 提示:
binding支持PyO3、RustCPython等取值;如果你只想分发 Rust 编写的命令行工具,改用[[tool.setuptools-rust.bins]]即可,底层对应 extension.py 中的RustBin类。
第六步:通过 MANIFEST.in 保留 Rust 源文件
为了让源码分发包(sdist)包含 Rust 源码,需要在 MANIFEST.in 中添加:
include Cargo.toml
recursive-include rust *.rs
第七步:一键安装并测试
在虚拟环境中执行标准 pip 命令,setuptools-rust 会自动调用 cargo build 完成编译:
python -m venv .venv
source .venv/bin/activate # Windows 使用 .venv\Scripts\activate
python -m pip install -e .
然后在 Python 中测试你的第一个 Rust-Python 扩展:
>>> import hello_world
>>> hello_world.sum_as_string(5, 7)
'12'
成功输出 '12',说明 Rust 代码已经跑起来了!🎉
进阶技巧:让构建更顺手
用环境变量控制编译模式
SETUPTOOLS_RUST_CARGO_PROFILE=dev:默认是release,调试时设为dev可加快编译;RUSTFLAGS=-Ctarget-cpu=native:针对当前 CPU 优化。
发布 wheel 到 PyPI
setuptools-rust 完全兼容标准打包流程,直接用 python -m build 就能产出 wheel,参考 building_wheels.md。跨平台发布可用 cibuildwheel;交叉编译可借助 crossenv、cross 或 cargo-zigbuild。
两种配置方式灵活切换
- 声明式:
pyproject.toml(本教程所用,适合绝大多数场景); - 编程式:在 setup.py 中使用
RustExtension,适合需要动态生成配置的项目,示例见examples/hello-world-setuppy。
总结
10 分钟,你已经完成了从环境准备到构建首个 Rust-Python 扩展的全流程。setuptools-rust 的优雅之处在于:你不需要改变任何打包习惯,只需在 pyproject.toml 里加上几行配置,就能享受到 Rust 的高性能。进阶玩法还包括在 extension.py 中探索更多参数,以及结合 html-py-ever 等官方示例学习大型项目实践。快去动手试试吧!⚡
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



