From 2926a565f496a350d4fc9ca8f753b86b7215d0e8 Mon Sep 17 00:00:00 2001 From: David Hewitt <1939362+davidhewitt@users.noreply.github.com> Date: Fri, 2 Apr 2021 14:04:44 +0100 Subject: [PATCH] macos: automatically provide required linker arguments --- CHANGELOG.md | 1 + README.md | 16 ---------------- build.rs | 31 ++++++++++++++++++++----------- src/lib.rs | 20 -------------------- 4 files changed, 21 insertions(+), 47 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c3bffd2089..7e041d2f95c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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) diff --git a/README.md b/README.md index 12c69d0574e..3216968ed0a 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/build.rs b/build.rs index 141c4f3e7dd..2e8596bb601 100644 --- a/build.rs +++ b/build.rs @@ -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 { @@ -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", diff --git a/src/lib.rs b/src/lib.rs index 5b17fa3e566..4764011b8be 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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