PyO3 + maturin,從 Rust 編譯成 Python Extension 連同 .pyi 型別存根打包進 wheel 全流程

Posted by Young on 2025-10-17
Estimated Reading Time 2 Minutes
Words 515 In Total

建立 Rust 專案

建立 Rust 資料夾

1
2
mkdir my_rust_lib
cd my_rust_lib

建立 Cargo.toml(Rust 的設定檔

1
2
3
4
5
6
7
8
9
10
11
12
13
Cargo.toml 內容:
[package]
name = "my_rust_lib"
version = "0.1.0"
edition = "2021"

[lib]
name = "my_rust_lib"
crate-type = ["cdylib"] # ← 關鍵!編譯成動態庫供
Python 使用

[dependencies]
pyo3 = { version = "0.26", features =["extension-module"] } # ← PyO3 橋接

建立 pyproject.toml(Python 的設定檔)

1
2
3
4
5
6
7
8
9
10
11
12
13
[build-system]
requires = ["maturin>=1.8,<2.0"]
build-backend = "maturin"

[project]
name = "my_rust_lib"
version = "0.1.0"
description = "A Python extension module written in Rust using PyO3"
requires-python = ">=3.11,<3.15"

[tool.maturin]
features = ["pyo3/extension-module"]
include = ["my_rust_lib/**/*"]

features = ["pyo3/extension-module"] 就是告訴編譯器靶crate 打包成可被 python import 的模組

如果沒加,編譯後的 .so 會是「一般動態函式庫」而不是「Python extension module」。在 Python 直接 import your_module 時可能會失敗,因為缺少 PyO3 預期的初始化符號。

如果只是做一個純 Rust 套件,然後透過 FFI (cffi, ctypes) 去 call .so,那就不需要 pyo3/extension-module。

撰寫 Rust 程式碼

1
2
3
4
src/lib.rs 結構:
use pyo3::prelude::*; // ← 導入 PyO3

....

編譯指令

編譯並輸出 wheel 套件檔案,會在 target/wheels/ 產生 .whl 安裝包。

1
maturin build --release -m my_rust_lib/Cargo.toml

target

安裝模組

把你剛編譯出來的 Rust-Python 模組 wheel,強制安裝到當前 Python 環境。

1
uv pip install --force-reinstall my_rust_lib/target/wheels/my_rust_lib-*.whl

直接點 import 的類,或是直接去 .venv/lib/python3.13/site-packages/ 應就能看到編譯好的模組檔

lib

Python 調用 Rust 模組

就可以在 Python 中直接調用 Rust 編譯好的模組

1
import my_rust_lib # ← 直接導入,就像普通 Python 模組
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
┌─────────────────────────────────────────────────┐
│ Python 程式 │
│ import my_rust_lib │
│ my_rust_lib.correct_text(...) │
└──────────────────┬──────────────────────────────┘
│ (Python C API)

┌─────────────────────────────────────────────────┐
│ PyO3 橋接層 │
│ - 型別轉換 │
│ - 錯誤處理 │
│ - GIL 管理 │
└──────────────────┬──────────────────────────────┘

┌─────────────────────────────────────────────────┐
│ Rust 編譯的機器碼 │
│ my_rust_lib.so │
│ - correct_text() [native code] │
│ - pinyin 轉換 [native code] │
│ - edit_distance [native code] │
└─────────────────────────────────────────────────┘

所以走一次流程大概就是

  1. 編譯 Rust 程式碼 → 生成優化的機器碼,.so 動態庫
  2. 鏈接 Python C API → 透過 PyO3 橋接
  3. 生成 .so 檔案 → my_rust_lib.cpython-313-darwin.so
  4. 安裝到虛擬環境 → .venv/lib/python3.13/site-packages/my_rust_lib/

若您覺得這篇文章對您有幫助,歡迎分享出去讓更多人看到⊂◉‿◉つ~


留言版