From 1e951d5d8b1b521031352438ff5b9ef167beae6a Mon Sep 17 00:00:00 2001 From: Gregory Szorc Date: Wed, 1 Sep 2021 19:40:47 -0700 Subject: [PATCH] pyo3-build-config: add a crate feature to control build script I have a use case in PyOxidizer where I want to use the pyo3-build-config crate as a library crate so I can access the `InterpreterConfig` struct so I can read/write config files without reinventing the wheel. This is doable before this commit. But it requires that the build environment have a Python interpreter. This is undesirable for library usage. This commit introduces a cargo feature flag to control whether the build script does anything. The feature flag must be present for the build script to resolve a config. The feature flag is enabled by default for backwards compatibility. The pyo3 and pyo3-macros-backend crates use this feature by default, for backwards compatibility and because it is the reasonable default. This is probably room to conditionalize some APIs and other behavior based on this feature flag. But we stop short of doing that for the time being. --- CHANGELOG.md | 1 + Cargo.toml | 2 +- guide/src/features.md | 8 ++++++++ pyo3-build-config/Cargo.toml | 6 +++++- pyo3-build-config/build.rs | 10 +++++++--- pyo3-macros-backend/Cargo.toml | 2 +- 6 files changed, 23 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bc060ed2..5e26065d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Add implementation of `std::ops::Index` for `PyList`, `PyTuple` and `PySequence`. [#1825](https://github.com/PyO3/pyo3/pull/1825) - Add range indexing implementations of `std::ops::Index` for `PyList`, `PyTuple` and `PySequence`. [#1829](https://github.com/PyO3/pyo3/pull/1829) - Add commonly-used sequence methods to `PyList` and `PyTuple`. [#1849](https://github.com/PyO3/pyo3/pull/1849) +- The `pyo3-build-config` crate now has a `resolve-config` feature to control whether its build script does anything. [#1856](https://github.com/PyO3/pyo3/pull/1856) ### Changed diff --git a/Cargo.toml b/Cargo.toml index a7370897..61dd34dd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,7 +43,7 @@ pyo3 = { path = ".", default-features = false, features = ["macros", "auto-initi serde_json = "1.0.61" [build-dependencies] -pyo3-build-config = { path = "pyo3-build-config", version = "0.14.4" } +pyo3-build-config = { path = "pyo3-build-config", version = "0.14.4", features = ["resolve-config"] } [features] default = ["macros"] diff --git a/guide/src/features.md b/guide/src/features.md index bde158ab..0a485eb4 100644 --- a/guide/src/features.md +++ b/guide/src/features.md @@ -69,6 +69,14 @@ The `nightly` feature needs the nightly Rust compiler. This allows PyO3 to use R - `FromPyObject` for `Vec` and `[T;N]` can perform a `memcpy` when the object supports the Python buffer protocol. - `ToBorrowedObject` can skip a reference count increase when the provided object is a Python native type. +### `resolve-config` + +The `resolve-config` feature of the `pyo3-build-config` crate controls whether that crate's +build script automatically resolves a Python interpreter / build configuration. Disabling +this feature enables this crate to be used in *library mode*. This may be desirable for +use cases where you want to read or write PyO3 build configuration files or resolve +metadata about a Python interpreter. + ## Optional Dependencies These features enable conversions between Python types and types from other Rust crates, enabling easy access to the rest of the Rust ecosystem. diff --git a/pyo3-build-config/Cargo.toml b/pyo3-build-config/Cargo.toml index 5dbbe638..82172277 100644 --- a/pyo3-build-config/Cargo.toml +++ b/pyo3-build-config/Cargo.toml @@ -14,7 +14,11 @@ edition = "2018" once_cell = "1" [features] -default = [] +default = ["resolve-config"] + +# Attempt to resolve a Python interpreter config for building in the build +# script. If this feature isn't enabled, the build script no-ops. +resolve-config = [] abi3 = [] abi3-py36 = ["abi3-py37"] diff --git a/pyo3-build-config/build.rs b/pyo3-build-config/build.rs index 0ffd170b..7e2cae9b 100644 --- a/pyo3-build-config/build.rs +++ b/pyo3-build-config/build.rs @@ -91,8 +91,12 @@ fn generate_build_configs() -> Result<()> { } fn main() { - if let Err(e) = generate_build_configs() { - eprintln!("error: {}", e.report()); - std::process::exit(1) + if std::env::var("CARGO_FEATURE_RESOLVE_CONFIG").is_ok() { + if let Err(e) = generate_build_configs() { + eprintln!("error: {}", e.report()); + std::process::exit(1) + } + } else { + eprintln!("resolve-config feature not enabled; build script in no-op mode"); } } diff --git a/pyo3-macros-backend/Cargo.toml b/pyo3-macros-backend/Cargo.toml index 0d3fc54f..65b90923 100644 --- a/pyo3-macros-backend/Cargo.toml +++ b/pyo3-macros-backend/Cargo.toml @@ -16,7 +16,7 @@ edition = "2018" [dependencies] quote = { version = "1", default-features = false } proc-macro2 = { version = "1", default-features = false } -pyo3-build-config = { path = "../pyo3-build-config", version = "0.14.4" } +pyo3-build-config = { path = "../pyo3-build-config", version = "0.14.4", features = ["resolve-config"] } [dependencies.syn] version = "1"