From 3e7bba1be9bd2d8f7ca81c66a31e6380412627cc Mon Sep 17 00:00:00 2001 From: messense Date: Sat, 16 Apr 2022 16:22:37 +0800 Subject: [PATCH] Don't require a working Python interpreter when `generate-abi3-import-lib` feature is enabled on Windows --- src/build_options.rs | 52 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 3 deletions(-) diff --git a/src/build_options.rs b/src/build_options.rs index 9d035bca8..0bd6adb74 100644 --- a/src/build_options.rs +++ b/src/build_options.rs @@ -272,12 +272,25 @@ impl BuildOptions { None => PathBuf::from(&cargo_metadata.target_directory).join("wheels"), }; + let generate_abi3_import_lib = has_generate_abi3_import_lib(&cargo_metadata)?; let interpreter = if self.interpreter.is_empty() { // Auto-detect interpreters - find_interpreter(&bridge, &[], &target, get_min_python_minor(&metadata21))? + find_interpreter( + &bridge, + &[], + &target, + get_min_python_minor(&metadata21), + generate_abi3_import_lib, + )? } else { // User given list of interpreters - find_interpreter(&bridge, &self.interpreter, &target, None)? + find_interpreter( + &bridge, + &self.interpreter, + &target, + None, + generate_abi3_import_lib, + )? }; let mut rustc_extra_args = self.rustc_extra_args.clone(); @@ -450,6 +463,33 @@ fn has_abi3(cargo_metadata: &Metadata) -> Result> { Ok(None) } +/// pyo3 0.16.4+ supports building abi3 wheels without a working Python interpreter on Windows +/// when `generate-abi3-import-lib` feature is enabled +fn has_generate_abi3_import_lib(cargo_metadata: &Metadata) -> Result { + let resolve = cargo_metadata + .resolve + .as_ref() + .context("Expected cargo to return metadata with resolve")?; + for &lib in PYO3_BINDING_CRATES.iter() { + let pyo3_packages = resolve + .nodes + .iter() + .filter(|package| cargo_metadata[&package.id].name.as_str() == lib) + .collect::>(); + match pyo3_packages.as_slice() { + [pyo3_crate] => { + let generate_import_lib = pyo3_crate + .features + .iter() + .any(|x| x == "generate-abi3-import-lib"); + return Ok(generate_import_lib); + } + _ => continue, + } + } + Ok(false) +} + /// Tries to determine the [BridgeModel] for the target crate pub fn find_bridge(cargo_metadata: &Metadata, bridge: Option<&str>) -> Result { let resolve = cargo_metadata @@ -505,7 +545,9 @@ pub fn find_bridge(cargo_metadata: &Metadata, bridge: Option<&str>) -> Result
= package .targets .iter() @@ -585,6 +627,7 @@ pub fn find_interpreter( interpreter: &[PathBuf], target: &Target, min_python_minor: Option, + generate_abi3_import_lib: bool, ) -> Result> { match bridge { BridgeModel::Bindings(binding_name, _) => { @@ -718,6 +761,9 @@ pub fn find_interpreter( platform: None, runnable: false, }]) + } else if generate_abi3_import_lib { + println!("🐍 Not using a specific python interpreter (Automatically generating windows import library)"); + Ok(Vec::new()) } else { let interp = interpreter .get(0)