使用 "extension-module" 功能时 PyO3 链接器错误

PyO3 linker error when using "extension-module" feature

当我尝试构建一个非常简单的 PyO3 模块时,编译在 link 阶段停止并且 returns 一条很长的错误消息。我在 Linux.

上编译这段代码

Rust 项目如下所示:

├ Cargo.toml
└ src/
  └ lib.rs

Cargo.toml:

[package]
name = "dytest"
version = "0.1.0"
edition = "2021"

[lib]
name = "dytest"
crate-type = ["cdylib"]

[dependencies]
pyo3 = { version = "0.16", features = ["extension-module"] }

lib.rs:

use pyo3::prelude::*;

#[test]
fn test_print() {
    pyo3::prepare_freethreaded_python();
    Python::with_gil(|py| py.run( "print('Hello World')", None, None ) );
}

当我现在 运行 cargo test 时,我得到一个 linker 错误:

error: linking with `cc` failed: exit status: 1
  |
  = note: "cc" "-m64" [...many, many paths...]
  = note: /usr/bin/ld: /home/user/dytest/target/debug/deps/libpyo3-c98e45c2daa36b66.rlib(pyo3-c98e45c2daa36b66.pyo3.b04632a8-cgu.2.rcgu.o): in function `pyo3_ffi::object::Py_DECREF':
          /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/pyo3-ffi-0.16.2/src/object.rs:407: undefined reference to `_Py_Dealloc'
          /usr/bin/ld: /home/user/dytest/target/debug/deps/libpyo3-c98e45c2daa36b66.rlib(pyo3-c98e45c2daa36b66.pyo3.b04632a8-cgu.2.rcgu.o): in function `pyo3_ffi::object::Py_None':
          /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/pyo3-ffi-0.16.2/src/object.rs:472: undefined reference to `_Py_NoneStruct'
          /usr/bin/ld: /home/user/dytest/target/debug/deps/libpyo3-c98e45c2daa36b66.rlib(pyo3-c98e45c2daa36b66.pyo3.b04632a8-cgu.2.rcgu.o): in function `pyo3::err::PyErr::take':
          /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/pyo3-0.16.2/src/err/mod.rs:264: undefined reference to `PyErr_Fetch'
          
          [...many, many error messages...]

          /usr/bin/ld: /home/user/dytest/target/debug/deps/libpyo3-c98e45c2daa36b66.rlib(pyo3-c98e45c2daa36b66.pyo3.b04632a8-cgu.15.rcgu.o): in function `pyo3::types::string::PyString::to_string_lossy':
          /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/pyo3-0.16.2/src/types/string.rs:199: undefined reference to `PyUnicode_AsEncodedString'
          collect2: error: ld returned 1 exit status
          
  = help: some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified
  = note: use the `-l` flag to specify native libraries to link
  = note: use the `cargo:rustc-link-lib` directive to specify the native libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#cargorustc-link-libkindname)

error: could not compile `dytest` due to previous error

如果我替换
pyo3 = { version = "0.16", features = ["extension-module"] }

pyo3 = { version = "0.16" }
一切正常,但 PyO3 User Guide 明确说明了此功能。

在 Windows 机器上尝试此代码,有效。

我假设我缺少某种依赖性,但我不知道缺少什么。

这似乎是一个已知的 PyO3 问题。在他们的 FAQ:

中提到

Cargo.toml:

[dependencies.pyo3]
version = "0.16.3"

[features]
extension-module = ["pyo3/extension-module"]
default = ["extension-module"]
当 extension-module 功能被激活时,

cargo test 失败并出现链接错误。解决方法是使 extension-module 功能可选,并 运行 使用
进行测试 cargo test --no-default-features.