Setuptools Rust 扩展插件
项目描述
Setuptools 插件用于构建 Rust Python 扩展
setuptools-rust
是一个 Setuptools 插件,用于构建使用 PyO3 或 rust-cpython 实现的 Rust Python 扩展。
将用Rust编写的Python扩展编译和分发得像用C编写一样简单。
快速入门
以下是一个非常基础的教程,展示了如何在pyproject.toml
中使用setuptools-rust
。它假设您已经有一系列要分发的Python和Rust文件。您可以在github仓库的examples/hello-world
目录中查看这些文件的示例。有关如何在Rust中编写Python模块的详细信息,请参阅PyO3文档。
hello-world
├── python
│ └── hello_world
│ └── __init__.py
└── rust
└── lib.rs
一旦实现文件就位,我们需要添加一个pyproject.toml
文件,该文件告诉任何想要使用您项目的人如何构建它。在这个文件中,我们使用一个表格数组(TOML术语与Python字典列表等价),用于指定用Rust编写的不同扩展模块
# pyproject.toml
[build-system]
requires = ["setuptools", "setuptools-rust"]
build-backend = "setuptools.build_meta"
[project]
name = "hello-world"
version = "1.0"
[tool.setuptools.packages]
# Pure Python packages/modules
find = { where = ["python"] }
[[tool.setuptools-rust.ext-modules]]
# Private Rust extension module to be nested into the Python package
target = "hello_world._lib" # The last part of the name (e.g. "_lib") has to match lib.name in Cargo.toml,
# but you can add a prefix to nest it inside of a Python package.
path = "Cargo.toml" # Default value, can be omitted
binding = "PyO3" # Default value, can be omitted
每个扩展模块应直接映射到Cargo清单文件上的相应[lib]
表
# Cargo.toml
[package]
name = "hello-world"
version = "0.1.0"
edition = "2021"
[dependencies]
pyo3 = "0.22.0"
[lib]
name = "_lib" # private module to be nested into Python package,
# needs to match the name of the function with the `[#pymodule]` attribute
path = "rust/lib.rs"
crate-type = ["cdylib"] # required for shared library for Python to import from.
# See more keys and their definitions at https://doc.rust-lang.net.cn/cargo/reference/manifest.html
# See also PyO3 docs on writing Cargo.toml files at https://pyo3.rs
您还需要告诉Setuptools,Rust文件是构建您的项目所需的,这可以通过源分发完成。这可以通过MANIFEST.in
(见以下示例)或通过如setuptools-scm
之类的插件来完成。
# MANIFEST.in
include Cargo.toml
recursive-include rust *.rs
有了这些文件,您就可以在虚拟环境中安装项目以进行测试并确保一切正常工作
# cd hello-world
python3 -m venv .venv
source .venv/bin/activate # on Linux or macOS
.venv\Scripts\activate # on Windows
python -m pip install -e .
python
>>> import hello_world
# ... try running something from your new extension module ...
# ... better write some tests with pytest ...
下一步和总结
-
当您准备好分发项目时,请查看文档中有关构建轮的说明。
-
支持交叉编译,使用
crossenv
、cross
或cargo-zigbuild
之一。有关示例,请参阅ci.yml
中的test-crossenv
、test-cross
和test-zigbuild
Github操作作业。 -
如果您想分发用Rust编写的二进制可执行文件(而不是Python运行时可以导入的库),也可以使用
[[tool.setuptools-rust.bins]]
(而不是[[tool.setuptools-rust.ext-modules]]
)。请注意,同时分发库和可执行文件(或多个可执行文件)可能会显着增加由wheel文件分发的包索引的大小,从而增加构建、下载和安装时间。另一种方法是使用Python入口点调用Rust实现(通过PyO3绑定公开)。有关更多见解,请参阅hello-world示例。 -
有关配置选项的完整参考,请参阅API参考。您可以使用定义在
RustExtension
类中的任何参数与[[tool.setuptools-rust.ext-modules]]
一起使用,以及使用定义在RustBin
类中的任何参数与[[tool.setuptools-rust.bins]]
一起使用;只需记住在您的pyproject.toml
文件中将下划线字符_
替换为破折号-
即可。 -
Cargo.toml
允许每个文件只有一个[lib]
表。如果您需要多个扩展模块,您将需要编写多个Cargo.toml
文件。或者,您也可以创建一个单独的私有Rust顶层模块,它公开多个子模块(使用PyO3的子模块),这可能会减少构建工件的大小。您始终可以将扩展模块保持为私有,并用纯Python包装它们,以精细控制公共API。 -
如果想在同一个macOS wheel中包含
[[tool.setuptools-rust.bins]]
和[[tool.setuptools-rust.ext-modules]]
,可能需要手动添加一个额外的build.rs
文件。有关此问题的解决方案,请参阅 PyO3/setuptools-rust#351。 -
更多示例请参见
hello-world
:本教程中使用的代码的更完整版本,它将[[tool.setuptools-rust.ext-modules]]
和[[tool.setuptools-rust.bins]]
混合在一个单一的分发中。html-py-ever
:一个更高级的示例,使用 Rust 包作为依赖项。rust_with_cffi
:使用 Rust 和 CFFI。namespace_package
:将 Rust 编写的模块集成到 PEP 420 命名空间包中。hello-world-script
:仅使用 Rust 创建二进制可执行文件,而不是库模块。
项目详情
下载文件
下载适用于您平台的文件。如果您不确定选择哪个,请了解更多关于 安装包 的信息。