From 00274f11725db9f54df1f084944a6f2491e951ca Mon Sep 17 00:00:00 2001 From: David Hewitt <1939362+davidhewitt@users.noreply.github.com> Date: Sun, 30 Aug 2020 15:30:56 +0100 Subject: [PATCH] Fix `cargo test` with `extension-module` feature. --- CHANGELOG.md | 1 + build.rs | 33 ++++++++++++++++++++------------- guide/src/faq.md | 17 +++++++++-------- 3 files changed, 30 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e8e2dd1aa2f..45d5631fbe1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Link against libpython on android with `extension-module` set. [#1095](https://github.com/PyO3/pyo3/pull/1095) - Fix support for both `__add__` and `__radd__` in the `+` operator when both are defined in `PyNumberProtocol` (and similar for all other reversible operators). [#1107](https://github.com/PyO3/pyo3/pull/1107) +- Fix `cargo test` with `extension-module` feature. (Requires `cargo +nightly -Zextra-link-arg test` for now.) #[1123](https://github.com/PyO3/pyo3/pull/1123) ## [0.11.1] - 2020-06-30 ### Added diff --git a/build.rs b/build.rs index 04ea5a477e3..c1bbe1fb240 100644 --- a/build.rs +++ b/build.rs @@ -568,8 +568,8 @@ fn get_library_link_name(version: &PythonVersion, ld_version: &str) -> String { } } -fn get_rustc_link_lib(config: &InterpreterConfig) -> Result { - match env::var("CARGO_CFG_TARGET_OS").unwrap().as_str() { +fn get_rustc_link_lib(config: &InterpreterConfig, target_os: &str) -> Result { + match target_os { "windows" => get_rustc_link_lib_windows(config), "macos" => get_rustc_link_lib_macos(config), _ => get_rustc_link_lib_unix(config), @@ -730,19 +730,26 @@ fn configure(interpreter_config: &InterpreterConfig) -> Result { } check_target_architecture(interpreter_config)?; - let target_os = env::var_os("CARGO_CFG_TARGET_OS").unwrap(); + let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap(); + + if let Some(libdir) = &interpreter_config.libdir { + println!("cargo:rustc-link-search=native={}", libdir); + } else if target_os == "windows" { + println!( + "cargo:rustc-link-search=native={}\\libs", + interpreter_config.base_prefix + ); + } let is_extension_module = env::var_os("CARGO_FEATURE_EXTENSION_MODULE").is_some(); - if !is_extension_module || target_os == "windows" || target_os == "android" { - println!("{}", get_rustc_link_lib(&interpreter_config)?); - if let Some(libdir) = &interpreter_config.libdir { - println!("cargo:rustc-link-search=native={}", libdir); - } else if target_os == "windows" { - println!( - "cargo:rustc-link-search=native={}\\libs", - interpreter_config.base_prefix - ); - } + if is_extension_module && !(target_os == "windows" || target_os == "android") { + // Extension module on unix - only link non-lib targets + let lib_name = + get_library_link_name(&interpreter_config.version, &interpreter_config.ld_version); + println!("cargo:rustc-link-arg-bins=-l{}", lib_name); + } else { + // Not extension module, or is windows or android - always link to libpython. + println!("{}", get_rustc_link_lib(&interpreter_config, &target_os)?); } let mut flags = String::new(); diff --git a/guide/src/faq.md b/guide/src/faq.md index 96e7c0740de..c09820c2f01 100644 --- a/guide/src/faq.md +++ b/guide/src/faq.md @@ -15,15 +15,16 @@ PyO3 provides a struct [`GILOnceCell`] which works equivalently to `OnceCell` bu [`GILOnceCell`]: https://docs.rs/pyo3/latest/pyo3/once_cell/struct.GILOnceCell.html -## I can't run `cargo test`: I'm having linker issues like "Symbol not found" or "Undefined reference to _PyExc_SystemError"! +## I can't run `cargo test` or `cargo run`: I'm having linker issues like "Symbol not found" or "Undefined reference to _PyExc_SystemError"! -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`: +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. -```toml -[dependencies.pyo3] -version = "*" +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.: -[features] -extension-module = ["pyo3/extension-module"] -default = ["extension-module"] +``` +# For cargo test +cargo +nightly -Zextra-link-arg test + +# For cargo run +cargo +nightly -Zextra-link-arg run ```