如何使用 Maturin 运行 Rust 库单元测试?

问题描述 投票:0回答:1

我正在 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'

我可以通过以下两种方法解决这个问题:

  1. 使用
    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"
  1. 或创建
    .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
可以解决此问题,因此它会在一定程度上提供帮助,但还不够。

python unit-testing rust maturin
1个回答
0
投票

我有几乎相同的设置:带有 PyO3 和 maturin 的 Python 模块。我运行

cargo test
没问题。也许是因为在我的
cargo.toml
我有这个部分:

[lib]
name = "module_name_whatever"
crate-type = ["cdylib", "lib"]
© www.soinside.com 2019 - 2024. All rights reserved.