Skip to content

Commit

Permalink
Merge pull request #1755 from davidhewitt/macos-link-args
Browse files Browse the repository at this point in the history
build: revert usage of cargo:rustc-cdylib-link-arg
  • Loading branch information
davidhewitt authored Aug 3, 2021
2 parents 7be6bdd + c2d6a50 commit fcd35c1
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 24 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
### Added

- Add `indexmap` feature to add `ToPyObject`, `IntoPy` and `FromPyObject` implementations for `indexmap::IndexMap`. [#1728](https://github.com/PyO3/pyo3/pull/1728)
- Add `pyo3_build_config::add_extension_module_link_args()` to use in build scripts to set linker arguments (for macOS). [#1755](https://github.com/PyO3/pyo3/pull/1755)

### Changed

- `PyErr::new` no longer acquires the Python GIL internally. [#1724](https://github.com/PyO3/pyo3/pull/1724)
- Reverted PyO3 0.14.0's use of `cargo:rustc-cdylib-link-arg` in its build script, as Cargo unintentionally allowed crates to pass linker args to downstream crates in this way. Projects supporting macOS may need to restore `.cargo/config.toml` files. [#1755](https://github.com/PyO3/pyo3/pull/1755)

### Fixed

Expand Down
5 changes: 0 additions & 5 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,6 @@ fn emit_cargo_configuration(interpreter_config: &InterpreterConfig) -> Result<()
println!("cargo:rustc-link-search=native={}\\libs", 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.
Expand Down
30 changes: 30 additions & 0 deletions guide/src/building_and_distribution.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,36 @@ You can then open a Python shell in the output directory and you'll be able to r

See, as an example, Bazel rules to build PyO3 on Linux at https://github.com/TheButlah/rules_pyo3.

#### macOS

On macOS, because the `extension-module` feature disables linking to `libpython` ([see the next section](#the-extension-module-feature)), some additional linker arguments need to be set. `maturin` and `setuptools-rust` both pass these arguments for PyO3 automatically, but projects using manual builds will need to set these directly in order to support macOS.

The easiest way to set the correct linker arguments is to add a [`build.rs`](https://doc.rust-lang.org/cargo/reference/build-scripts.html) with the following content:

```rust,ignore
fn main() {
pyo3_build_config::add_extension_module_link_args();
}
```

Remember to also add `pyo3-build-config` to the `build-dependencies` section in `Cargo.toml`.

An alternative to using `pyo3-build-config` is add the following to a cargo configuration file (e.g. `.cargo/config.toml`):

```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",
]
```

### The `extension-module` feature

PyO3's `extension-module` feature is used to disable [linking](https://en.wikipedia.org/wiki/Linker_(computing)) to `libpython` on unix targets.
Expand Down
51 changes: 32 additions & 19 deletions pyo3-build-config/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,33 +1,20 @@
//! Configuration used by PyO3 for conditional support of varying Python versions.
//!
//! The only public API currently exposed is [`use_pyo3_cfgs`], which is intended to be used in
//! build scripts to add a standard set of `#[cfg]` attributes for handling multiple Python
//! versions.
//!
//! The full list of attributes added are the following:
//!
//! | Flag | Description |
//! | ---- | ----------- |
//! | `#[cfg(Py_3_6)]`, `#[cfg(Py_3_7)]`, `#[cfg(Py_3_8)]`, `#[cfg(Py_3_9)]`, `#[cfg(Py_3_10)]` | These attributes mark code only for a given Python version and up. For example, `#[cfg(Py_3_6)]` marks code which can run on Python 3.6 **and newer**. |
//! | `#[cfg(Py_LIMITED_API)]` | This marks code which is run when compiling with PyO3's `abi3` feature enabled. |
//! | `#[cfg(PyPy)]` | This marks code which is run when compiling for PyPy. |
//!
//! For examples of how to use these attributes, [see PyO3's guide](https://pyo3.rs/latest/building_and_distribution/multiple_python_versions.html).
//! The public APIs exposed, [`use_pyo3_cfgs`] and [`add_extension_module_link_args`] are intended
//! to be called from build scripts to simplify building crates which depend on PyO3.
#[doc(hidden)]
pub mod errors;
mod impl_;

use once_cell::sync::OnceCell;

pub use impl_::{
find_interpreter, get_config_from_interpreter, InterpreterConfig, PythonImplementation,
PythonVersion,
};

// Used in PyO3's build.rs
#[doc(hidden)]
pub use impl_::{cargo_env_var, env_var, make_interpreter_config};
pub use impl_::{
cargo_env_var, env_var, find_interpreter, get_config_from_interpreter, make_interpreter_config,
InterpreterConfig, PythonImplementation, PythonVersion,
};

/// Reads the configuration written by PyO3's build.rs
///
Expand All @@ -46,6 +33,32 @@ pub fn get() -> &'static InterpreterConfig {
#[doc(hidden)]
pub const PATH: &str = concat!(env!("OUT_DIR"), "/pyo3-build-config.txt");

/// Adds all the [`#[cfg]` flags](index.html) to the current compilation.
///
/// This should be called from a build script.
///
/// The full list of attributes added are the following:
///
/// | Flag | Description |
/// | ---- | ----------- |
/// | `#[cfg(Py_3_6)]`, `#[cfg(Py_3_7)]`, `#[cfg(Py_3_8)]`, `#[cfg(Py_3_9)]`, `#[cfg(Py_3_10)]` | These attributes mark code only for a given Python version and up. For example, `#[cfg(Py_3_6)]` marks code which can run on Python 3.6 **and newer**. |
/// | `#[cfg(Py_LIMITED_API)]` | This marks code which is run when compiling with PyO3's `abi3` feature enabled. |
/// | `#[cfg(PyPy)]` | This marks code which is run when compiling for PyPy. |
///
/// For examples of how to use these attributes, [see PyO3's guide](https://pyo3.rs/latest/building_and_distribution/multiple_python_versions.html).
pub fn use_pyo3_cfgs() {
get().emit_pyo3_cfgs();
}

/// Adds linker arguments (for macOS) suitable for PyO3's `extension-module` feature.
///
/// This should be called from a build script.
///
/// This is currently a no-op on non-macOS platforms, however may emit additional linker arguments
/// in future if deemed necessarys.
pub fn add_extension_module_link_args() {
if cargo_env_var("CARGO_CFG_TARGET_OS").unwrap() == "macos" {
println!("cargo:rustc-cdylib-link-arg=-undefined");
println!("cargo:rustc-cdylib-link-arg=dynamic_lookup");
}
}

0 comments on commit fcd35c1

Please sign in to comment.