Skip to content

Commit 9d1ffb1

Browse files
committed
Fix cargo test with extension-module feature.
1 parent bb0ae49 commit 9d1ffb1

File tree

4 files changed

+48
-16
lines changed

4 files changed

+48
-16
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,8 @@ jobs:
208208
run: |
209209
python -m pip install -U pip nox
210210
cargo xtask test-py
211+
cargo run
212+
cargo test
211213
env:
212214
CARGO_TARGET_DIR: ${{ github.workspace }}/target
213215

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
5757

5858
### Fixed
5959

60+
- Fix `cargo test` with `extension-module` feature. (Requires `cargo +nightly` for now.) #[2135](https://github.com/PyO3/pyo3/pull/2135)
6061
- Fix undefined symbol for `PyObject_HasAttr` on PyPy. [#2025](https://github.com/PyO3/pyo3/pull/2025)
6162
- Fix memory leak in `PyErr::into_value`. [#2026](https://github.com/PyO3/pyo3/pull/2026)
6263
- Fix clippy warning `needless-option-as-deref` in code generated by `#[pyfunction]` and `#[pymethods]`. [#2040](https://github.com/PyO3/pyo3/pull/2040)

guide/src/faq.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,17 @@ PyO3 provides a struct [`GILOnceCell`] which works equivalently to `OnceCell` bu
1515

1616
[`GILOnceCell`]: {{#PYO3_DOCS_URL}}/pyo3/once_cell/struct.GILOnceCell.html
1717

18-
## I can't run `cargo test`: I'm having linker issues like "Symbol not found" or "Undefined reference to _PyExc_SystemError"!
18+
## I can't run `cargo test` or `cargo run`: I'm having linker issues like "Symbol not found" or "Undefined reference to _PyExc_SystemError"!
1919

20-
Currently, [#340](https://github.com/PyO3/pyo3/issues/340) causes `cargo test` to fail with linking errors when the `extension-module` feature is activated. For now you can work around this by making the `extension-module` feature optional and running the tests with `cargo test --no-default-features`:
20+
On unix operating systems the `extension-module` feature is required to disable linking against libpython to meet criteria of how Python extension modules should be built.
2121

22-
```toml
23-
[dependencies.pyo3]
24-
{{#PYO3_CRATE_VERSION}}
22+
PyO3 is able to re-enable linking for binaries and tests in the project, but this requires a `cargo` version capable of understanding extra linker arguments. This is only supported on nightly cargoes from February of 2022 or newer.
2523

26-
[features]
27-
extension-module = ["pyo3/extension-module"]
28-
default = ["extension-module"]
24+
```text
25+
# For cargo test
26+
cargo +nightly test
27+
# For cargo run
28+
cargo +nightly run
2929
```
3030

3131
## I can't run `cargo test`: my crate cannot be found for tests in `tests/` directory!

pyo3-build-config/src/lib.rs

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,24 +37,36 @@ pub fn use_pyo3_cfgs() {
3737
get().emit_pyo3_cfgs();
3838
}
3939

40-
/// Adds linker arguments (for macOS) suitable for PyO3's `extension-module` feature.
40+
/// Adds linker arguments suitable for PyO3's `extension-module` feature.
4141
///
4242
/// This should be called from a build script.
43-
///
44-
/// This is currently a no-op on non-macOS platforms, however may emit additional linker arguments
45-
/// in future if deemed necessarys.
43+
#[cfg(feature = "resolve-config")]
4644
pub fn add_extension_module_link_args() {
45+
let interpreter_config = get();
46+
4747
_add_extension_module_link_args(
48+
interpreter_config,
4849
&impl_::cargo_env_var("CARGO_CFG_TARGET_OS").unwrap(),
4950
std::io::stdout(),
5051
)
5152
}
5253

53-
fn _add_extension_module_link_args(target_os: &str, mut writer: impl std::io::Write) {
54+
fn _add_extension_module_link_args(
55+
interpreter_config: &InterpreterConfig,
56+
target_os: &str,
57+
mut writer: impl std::io::Write,
58+
) {
5459
if target_os == "macos" {
5560
writeln!(writer, "cargo:rustc-cdylib-link-arg=-undefined").unwrap();
5661
writeln!(writer, "cargo:rustc-cdylib-link-arg=dynamic_lookup").unwrap();
5762
}
63+
if target_os != "windows" && target_os != "android" {
64+
let lib_name = interpreter_config.lib_name.as_ref().unwrap();
65+
writeln!(writer, "cargo:rustc-link-arg-bins=-l{}", lib_name).unwrap();
66+
writeln!(writer, "cargo:rustc-link-arg-tests=-l{}", lib_name).unwrap();
67+
writeln!(writer, "cargo:rustc-link-arg-benches=-l{}", lib_name).unwrap();
68+
writeln!(writer, "cargo:rustc-link-arg-examples=-l{}", lib_name).unwrap();
69+
}
5870
}
5971

6072
/// Loads the configuration determined from the build environment.
@@ -179,15 +191,32 @@ mod tests {
179191
fn extension_module_link_args() {
180192
let mut buf = Vec::new();
181193

194+
let interpreter_cfg = InterpreterConfig {
195+
version: PythonVersion { major: 3, minor: 7 },
196+
implementation: PythonImplementation::CPython,
197+
shared: true,
198+
abi3: false,
199+
lib_name: Some("test".to_owned()),
200+
lib_dir: None,
201+
executable: None,
202+
pointer_width: None,
203+
build_flags: BuildFlags::default(),
204+
suppress_build_script_link_lines: false,
205+
extra_build_script_lines: vec![],
206+
};
182207
// Does nothing on non-mac
183-
_add_extension_module_link_args("windows", &mut buf);
208+
_add_extension_module_link_args(&interpreter_cfg, "windows", &mut buf);
184209
assert_eq!(buf, Vec::new());
185210

186-
_add_extension_module_link_args("macos", &mut buf);
211+
_add_extension_module_link_args(&interpreter_cfg, "macos", &mut buf);
187212
assert_eq!(
188213
std::str::from_utf8(&buf).unwrap(),
189214
"cargo:rustc-cdylib-link-arg=-undefined\n\
190-
cargo:rustc-cdylib-link-arg=dynamic_lookup\n"
215+
cargo:rustc-cdylib-link-arg=dynamic_lookup\n\
216+
cargo:rustc-link-arg-bins=-ltest\n\
217+
cargo:rustc-link-arg-tests=-ltest\n\
218+
cargo:rustc-link-arg-benches=-ltest\n\
219+
cargo:rustc-link-arg-examples=-ltest\n"
191220
);
192221
}
193222
}

0 commit comments

Comments
 (0)