我正在 Rust 中使用 maturin 构建一个自定义 Python 模块。
我正在使用 PyEnv,Python 3.12.2,安装有
env PYTHON_CONFIGURE_OPTS="--enable-shared"
和 --keep
,因此 Python 源可用。我有一个 venv,我正在使用 maturin develop
来构建我的库并根据需要更新 venv。
我的
lib.rs
文件中有一些单元测试,通常我只需运行 cargo test
来运行它们。
但是在 Maturin 管理的环境中,我收到链接器错误:
error: linking with `cc` failed: exit status: 1
...
= note: /usr/bin/ld: .../target/debug/deps/libpyo3-c286c2d4bbe22ea2.rlib(pyo3-c286c2d4bbe22ea2.pyo3.7555584b645de9e8-cgu.01.rcgu.o): in function `pyo3_ffi::object::Py_DECREF':
$HOME/.cargo/git/checkouts/pyo3-a22e69bc62b9f0fd/da24f0c/pyo3-ffi/src/object.rs:597: undefined reference to `_Py_Dealloc'
我可以通过以下两种方法解决这个问题:
RUSTFLAGS
和 LD_LIBRARY_PATH
/ rpath:$ export RUSTFLAGS="-C link-arg=-Wl,-rpath,.../pyenv.git/versions/3.12.2/lib -C link-arg=-L.../pyenv.git/versions/3.12.2/lib -C link-arg=-lpython3.12"
.cargo/config.toml
:[target.'cfg(all())']
rustflags = [
"-C", "link-arg=-Wl,-rpath,.../pyenv.git/versions/3.12.2/lib",
"-C", "link-arg=-L.../pyenv.git/versions/3.12.2/lib",
"-C", "link-arg=-lpython3.12",
]
为了简洁/隐私,我剪掉了路径。
这两种方法都在做同样的事情 - 提供显式链接器路径、要链接的库以及运行时库路径。这可行,但感觉不对。
我无法找到
maturin test
或等效项,而且当我有成熟的东西为我做这件事时,我必须手动指定 cargo
/ rustc
的链接器参数似乎是不对的.
有没有用maturin做到这一点的好方法?
编辑:在 PyO3 文档中,我找到了 Testing 部分,建议转换
Cargo.toml
的这一部分:
[dependencies]
pyo3 = { git = "https://github.com/pyo3/pyo3", features = ["extension-module"] }
进入此:
[dependencies.pyo3]
git = "https://github.com/pyo3/pyo3"
[features]
extension-module = ["pyo3/extension-module"]
default = ["extension-module"]
然后运行
cargo test --no-default-features
。这实际上解决了链接器错误,但在运行时定位库仍然存在问题:
Running unittests src/lib.rs (target/debug/deps/pyo3_example-cc3941bd091dc64e)
.../target/debug/deps/pyo3_example-cc3941bd091dc64e: error while loading shared libraries: libpython3.12.so.1.0: cannot open shared object file: No such file or directory
通过将
LD_LIBRARY_PATH
设置为 .../pyenv.git/versions/3.12.2/lib
可以解决此问题,因此它会在一定程度上提供帮助,但还不够。
我有几乎相同的设置:带有 PyO3 和 maturin 的 Python 模块。我运行
cargo test
没问题。也许是因为在我的cargo.toml
我有这个部分:
[lib]
name = "module_name_whatever"
crate-type = ["cdylib", "lib"]