Skip to content

Commit

Permalink
Don't require a working Python interpreter when `generate-abi3-import…
Browse files Browse the repository at this point in the history
…-lib` feature is enabled for Windows
  • Loading branch information
messense committed Apr 17, 2022
1 parent 4c08dbb commit 7d1b63b
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 12 deletions.
6 changes: 6 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,12 @@ jobs:
cargo run -- build --no-sdist -i python -m test-crates/pyo3-pure/Cargo.toml --target aarch64-apple-darwin --zig
# Check wheels with twine
twine check --strict test-crates/pyo3-pure/target/wheels/*.whl
- name: test cross compiling windows abi3 wheel
if: matrix.os == 'ubuntu-latest'
run: |
sudo apt-get install -y mingw-w64
rustup target add x86_64-pc-windows-gnu
cargo run -- build --no-sdist -m test-crates/pyo3-pure/Cargo.toml --target x86_64-pc-windows-gnu
test-alpine:
name: Test Alpine Linux
Expand Down
1 change: 1 addition & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]

* Stop setting `PYO3_NO_PYTHON` environment variable for pyo3 0.16.4 and later in [#875](https://github.com/PyO3/maturin/pull/875)
* Build Windows abi3 wheels with `pyo3` 0.16.4 and later versions no longer require a Python interpreter in [#879](https://github.com/PyO3/maturin/pull/879)

## [0.12.12] - 2022-04-07

Expand Down
4 changes: 1 addition & 3 deletions src/build_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,9 +211,7 @@ impl BuildContext {
.cloned()
.collect();
let mut built_wheels = Vec::new();
if !cpythons.is_empty() {
built_wheels.extend(self.build_binding_wheel_abi3(&cpythons, *major, *minor)?);
}
built_wheels.extend(self.build_binding_wheel_abi3(&cpythons, *major, *minor)?);
if !pypys.is_empty() {
println!(
"⚠️ Warning: PyPy does not yet support abi3 so the build artifacts will be version-specific. \
Expand Down
61 changes: 53 additions & 8 deletions src/build_options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,12 +272,25 @@ impl BuildOptions {
None => PathBuf::from(&cargo_metadata.target_directory).join("wheels"),
};

let generate_abi3_import_lib = is_generating_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();
Expand Down Expand Up @@ -450,6 +463,33 @@ fn has_abi3(cargo_metadata: &Metadata) -> Result<Option<(u8, u8)>> {
Ok(None)
}

/// pyo3 0.16.4+ supports building abi3 wheels without a working Python interpreter for Windows
/// when `generate-abi3-import-lib` feature is enabled
fn is_generating_abi3_import_lib(cargo_metadata: &Metadata) -> Result<bool> {
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::<Vec<_>>();
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<BridgeModel> {
let resolve = cargo_metadata
Expand Down Expand Up @@ -505,7 +545,9 @@ pub fn find_bridge(cargo_metadata: &Metadata, bridge: Option<&str>) -> Result<Br
println!("🔗 Found rust-cpython bindings");
BridgeModel::Bindings("rust_cpython".to_string(), MINIMUM_PYTHON_MINOR)
} else {
let package = &cargo_metadata[resolve.root.as_ref().unwrap()];
let package = cargo_metadata
.root_package()
.context("Expected cargo to return metadata with root_package")?;
let targets: Vec<_> = package
.targets
.iter()
Expand Down Expand Up @@ -585,6 +627,7 @@ pub fn find_interpreter(
interpreter: &[PathBuf],
target: &Target,
min_python_minor: Option<usize>,
generate_abi3_import_lib: bool,
) -> Result<Vec<PythonInterpreter>> {
match bridge {
BridgeModel::Bindings(binding_name, _) => {
Expand Down Expand Up @@ -718,15 +761,17 @@ pub fn find_interpreter(
platform: None,
runnable: false,
}])
} else {
let interp = interpreter
.get(0)
.context("Failed to find a python interpreter")?;
} else if let Some(interp) = interpreter.get(0) {
println!("🐍 Using {} to generate to link bindings (With abi3, an interpreter is only required on windows)", interp);
Ok(interpreter)
} else if generate_abi3_import_lib {
println!("🐍 Not using a specific python interpreter (Automatically generating windows import library)");
Ok(Vec::new())
} else {
bail!("Failed to find a python interpreter");
}
} else {
println!("🐍 Not using a specific python interpreter (With abi3, an interpreter is only required on windows)");
println!("🐍 Not using a specific python interpreter");
Ok(interpreter)
}
}
Expand Down
2 changes: 1 addition & 1 deletion test-crates/pyo3-pure/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ description = "Implements a dummy function (get_fortytwo.DummyClass.get_42()) in
license = "MIT"

[dependencies]
pyo3 = { version = "0.16.4", features = ["abi3-py37", "extension-module"] }
pyo3 = { version = "0.16.4", features = ["abi3-py37", "extension-module", "generate-abi3-import-lib"] }

[lib]
name = "pyo3_pure"
Expand Down

0 comments on commit 7d1b63b

Please sign in to comment.