Skip to content

Commit

Permalink
Fix cargo test with extension-module feature.
Browse files Browse the repository at this point in the history
  • Loading branch information
davidhewitt committed Mar 4, 2021
1 parent 67b1a61 commit bc794b2
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 21 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- `PyObject_Check`, `PySuper_Check`, and `FreeFunc` [#1438](https://github.com/PyO3/pyo3/pull/1438)

### Fixed
- Fix `cargo test` with `extension-module` feature. (Requires `cargo +nightly -Zextra-link-arg test` for now.) #[1123](https://github.com/PyO3/pyo3/pull/1123)
- Remove FFI definition `PyCFunction_ClearFreeList` for Python 3.9 and later. [#1425](https://github.com/PyO3/pyo3/pull/1425)
- `PYO3_CROSS_LIB_DIR` enviroment variable no long required when compiling for x86-64 Python from macOS arm64 and reverse. [#1428](https://github.com/PyO3/pyo3/pull/1428)
- Fix FFI definition `_PyEval_RequestCodeExtraIndex` which took an argument of the wrong type. [#1429](https://github.com/PyO3/pyo3/pull/1429)
Expand Down
45 changes: 32 additions & 13 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,13 @@ fn run_python_script(interpreter: &Path, script: &str) -> Result<String> {
}
}

fn get_library_link_name_unix(config: &InterpreterConfig) -> String {
match config.version.implementation {
PythonInterpreterKind::CPython => format!("python{}", config.ld_version),
PythonInterpreterKind::PyPy => format!("pypy{}-c", config.version.major),
}
}

fn get_rustc_link_lib(config: &InterpreterConfig) -> String {
let link_name = if env::var("CARGO_CFG_TARGET_OS").unwrap().as_str() == "windows" {
if env::var("CARGO_CFG_TARGET_ENV").unwrap().as_str() == "gnu" {
Expand All @@ -628,10 +635,7 @@ fn get_rustc_link_lib(config: &InterpreterConfig) -> String {
}
}
} else {
match config.version.implementation {
PythonInterpreterKind::CPython => format!("python{}", config.ld_version),
PythonInterpreterKind::PyPy => format!("pypy{}-c", config.version.major),
}
get_library_link_name_unix(config)
};

format!(
Expand Down Expand Up @@ -764,17 +768,32 @@ fn configure(interpreter_config: &InterpreterConfig) -> Result<()> {
check_target_architecture(interpreter_config)?;
let target_os = env::var_os("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
);
}

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" {
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_unix(&interpreter_config);
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));
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 interpreter_config.shared {
Expand Down
17 changes: 9 additions & 8 deletions guide/src/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,18 @@ 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
```

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

0 comments on commit bc794b2

Please sign in to comment.