Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't require a working Python interpreter when generate-abi3-import-lib feature is enabled for Windows #879

Merged
merged 2 commits into from
Apr 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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().rev() {
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