Skip to content

Commit b23cd69

Browse files
committed
Fix cargo test with extension-module feature.
1 parent d3f993a commit b23cd69

File tree

3 files changed

+30
-21
lines changed

3 files changed

+30
-21
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
3333
- Remove unused `python3` feature. [#1235](https://github.com/PyO3/pyo3/pull/1235)
3434

3535
### Fixed
36+
- Fix `cargo test` with `extension-module` feature. (Requires `cargo +nightly -Zextra-link-arg test` for now.) #[1123](https://github.com/PyO3/pyo3/pull/1123)
3637
- Fix missing field in `PyCodeObject` struct (`co_posonlyargcount`) - caused invalid access to other fields in Python >3.7. [#1260](https://github.com/PyO3/pyo3/pull/1260)
3738
- Fix building for `x86_64-unknown-linux-musl` target from `x86_65-unknown-linux-gnu` host. [#1267](https://github.com/PyO3/pyo3/pull/1267)
3839

build.rs

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -594,8 +594,8 @@ fn get_library_link_name(version: &PythonVersion, ld_version: &str) -> String {
594594
}
595595
}
596596

597-
fn get_rustc_link_lib(config: &InterpreterConfig) -> Result<String> {
598-
match env::var("CARGO_CFG_TARGET_OS").unwrap().as_str() {
597+
fn get_rustc_link_lib(config: &InterpreterConfig, target_os: &str) -> Result<String> {
598+
match target_os {
599599
"windows" => get_rustc_link_lib_windows(config),
600600
"macos" => get_rustc_link_lib_macos(config),
601601
_ => get_rustc_link_lib_unix(config),
@@ -762,19 +762,26 @@ fn configure(interpreter_config: &InterpreterConfig) -> Result<String> {
762762
}
763763

764764
check_target_architecture(interpreter_config)?;
765-
let target_os = env::var_os("CARGO_CFG_TARGET_OS").unwrap();
765+
let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
766+
767+
if let Some(libdir) = &interpreter_config.libdir {
768+
println!("cargo:rustc-link-search=native={}", libdir);
769+
} else if target_os == "windows" {
770+
println!(
771+
"cargo:rustc-link-search=native={}\\libs",
772+
interpreter_config.base_prefix
773+
);
774+
}
766775

767776
let is_extension_module = env::var_os("CARGO_FEATURE_EXTENSION_MODULE").is_some();
768-
if !is_extension_module || target_os == "windows" || target_os == "android" {
769-
println!("{}", get_rustc_link_lib(&interpreter_config)?);
770-
if let Some(libdir) = &interpreter_config.libdir {
771-
println!("cargo:rustc-link-search=native={}", libdir);
772-
} else if target_os == "windows" {
773-
println!(
774-
"cargo:rustc-link-search=native={}\\libs",
775-
interpreter_config.base_prefix
776-
);
777-
}
777+
if is_extension_module && !(target_os == "windows" || target_os == "android") {
778+
// Extension module on unix - only link non-lib targets
779+
let lib_name =
780+
get_library_link_name(&interpreter_config.version, &interpreter_config.ld_version);
781+
println!("cargo:rustc-link-arg-bins=-l{}", lib_name);
782+
} else {
783+
// Not extension module, or is windows or android - always link to libpython.
784+
println!("{}", get_rustc_link_lib(&interpreter_config, &target_os)?);
778785
}
779786

780787
let mut flags = String::new();

guide/src/faq.md

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

1616
[`GILOnceCell`]: https://docs.rs/pyo3/latest/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, [#341](https://github.com/PyO3/pyo3/issues/341) 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-
version = "*"
22+
PyO3 is able to re-enable linking for binaries and tests in the project, but it requires a nightly cargo feature. To use this feature, you must opt into it, e.g.:
2523

26-
[features]
27-
extension-module = ["pyo3/extension-module"]
28-
default = ["extension-module"]
24+
```
25+
# For cargo test
26+
cargo +nightly -Zextra-link-arg test
27+
28+
# For cargo run
29+
cargo +nightly -Zextra-link-arg run
2930
```

0 commit comments

Comments
 (0)