Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

macos: automatically provide required linker arguments #1539

Merged
merged 1 commit into from Apr 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -26,6 +26,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- The `auto-initialize` feature is no longer enabled by default. [#1443](https://github.com/PyO3/pyo3/pull/1443)
- Change `PyCFunction::new()` and `PyCFunction::new_with_keywords()` to take `&'static str` arguments rather than implicitly copying (and leaking) them. [#1450](https://github.com/PyO3/pyo3/pull/1450)
- Deprecate `PyModule` methods `call`, `call0`, `call1` and `get`. [#1492](https://github.com/PyO3/pyo3/pull/1492)
- Automatically provide `-undefined` and `dynamic_lookup` linker arguments on macOS with `extension-module` feature. [#1539](https://github.com/PyO3/pyo3/pull/1539)

### Removed
- Remove deprecated exception names `BaseException` etc. [#1426](https://github.com/PyO3/pyo3/pull/1426)
Expand Down
16 changes: 0 additions & 16 deletions README.md
Expand Up @@ -80,22 +80,6 @@ fn string_sum(py: Python, m: &PyModule) -> PyResult<()> {
}
```

On Windows and Linux, you can build normally with `cargo build --release`. On macOS, you need to set additional linker arguments. One option is to compile with `cargo rustc --release -- -C link-arg=-undefined -C link-arg=dynamic_lookup`, the other is to create a `.cargo/config` with the following content:

```toml
[target.x86_64-apple-darwin]
rustflags = [
"-C", "link-arg=-undefined",
"-C", "link-arg=dynamic_lookup",
]

[target.aarch64-apple-darwin]
rustflags = [
"-C", "link-arg=-undefined",
"-C", "link-arg=dynamic_lookup",
]
```

While developing, you can symlink (or copy) and rename the shared library from the target folder: On MacOS, rename `libstring_sum.dylib` to `string_sum.so`, on Windows `libstring_sum.dll` to `string_sum.pyd`, and on Linux `libstring_sum.so` to `string_sum.so`. Then open a Python shell in the same folder and you'll be able to `import string_sum`.

To build, test and publish your crate as a Python module, you can use [maturin](https://github.com/PyO3/maturin) or [setuptools-rust](https://github.com/PyO3/setuptools-rust). You can find an example for setuptools-rust in [examples/word-count](https://github.com/PyO3/pyo3/tree/main/examples/word-count), while maturin should work on your crate without any configuration.
Expand Down
29 changes: 19 additions & 10 deletions build.rs
Expand Up @@ -729,19 +729,32 @@ 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();
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" {
match (is_extension_module, target_os.as_str()) {
(_, "windows") => {
// always link on windows, even with extension module
println!("{}", get_rustc_link_lib(&interpreter_config));
println!(
"cargo:rustc-link-search=native={}\\libs",
interpreter_config.base_prefix
);
}
(true, "macos") => {
// with extension module on macos some extra linker arguments are needed
println!("cargo:rustc-cdylib-link-arg=-undefined");
println!("cargo:rustc-cdylib-link-arg=dynamic_lookup");
}
(false, _) | (_, "android") => {
// other systems, only link libs if not extension module
// android always link.
println!("{}", get_rustc_link_lib(&interpreter_config));
if let Some(libdir) = &interpreter_config.libdir {
println!("cargo:rustc-link-search=native={}", libdir);
}
}
_ => {}
}

if interpreter_config.shared {
Expand Down Expand Up @@ -885,10 +898,6 @@ fn main_impl() -> Result<()> {
println!("cargo:rustc-cfg={}=\"{}\"", CFG_KEY, flag)
}

if env::var_os("TARGET") == Some("x86_64-apple-darwin".into()) {
// TODO: Find out how we can set -undefined dynamic_lookup here (if this is possible)
}

for var in &[
"LIB",
"LD_LIBRARY_PATH",
Expand Down
20 changes: 0 additions & 20 deletions src/lib.rs
Expand Up @@ -82,26 +82,6 @@
//! }
//! ```
//!
//! On Windows and linux, you can build normally with `cargo build
//! --release`. On macOS, you need to set additional linker arguments. One
//! option is to compile with `cargo rustc --release -- -C link-arg=-undefined
//! -C link-arg=dynamic_lookup`, the other is to create a `.cargo/config` with
//! the following content:
//!
//! ```toml
//! [target.x86_64-apple-darwin]
//! rustflags = [
//! "-C", "link-arg=-undefined",
//! "-C", "link-arg=dynamic_lookup",
//! ]
//!
//! [target.aarch64-apple-darwin]
//! rustflags = [
//! "-C", "link-arg=-undefined",
//! "-C", "link-arg=dynamic_lookup",
//! ]
//! ```
//!
//! While developing, you symlink (or copy) and rename the shared library from
//! the target folder: On macOS, rename `libstring_sum.dylib` to
//! `string_sum.so`, on Windows `libstring_sum.dll` to `string_sum.pyd` and on
Expand Down