diff --git a/src/bridge.rs b/src/bridge.rs new file mode 100644 index 000000000..f91ef4fbf --- /dev/null +++ b/src/bridge.rs @@ -0,0 +1,115 @@ +use std::fmt::{Display, Formatter}; + +/// The name and version of the bindings crate +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Bindings { + /// The name of the bindings crate, `pyo3`, `rust-cpython` or `uniffi` + pub name: String, + /// bindings crate version + pub version: semver::Version, +} + +impl Bindings { + /// Returns the minimum python minor version supported + pub fn minimal_python_minor_version(&self) -> usize { + use crate::python_interpreter::MINIMUM_PYTHON_MINOR; + + match self.name.as_str() { + "pyo3" | "pyo3-ffi" => { + let major_version = self.version.major; + let minor_version = self.version.minor; + // N.B. must check large minor versions first + if (major_version, minor_version) >= (0, 16) { + 7 + } else { + MINIMUM_PYTHON_MINOR + } + } + _ => MINIMUM_PYTHON_MINOR, + } + } + + /// Returns the minimum PyPy minor version supported + pub fn minimal_pypy_minor_version(&self) -> usize { + use crate::python_interpreter::MINIMUM_PYPY_MINOR; + + match self.name.as_str() { + "pyo3" | "pyo3-ffi" => { + let major_version = self.version.major; + let minor_version = self.version.minor; + // N.B. must check large minor versions first + if (major_version, minor_version) >= (0, 23) { + 9 + } else if (major_version, minor_version) >= (0, 14) { + 7 + } else { + MINIMUM_PYPY_MINOR + } + } + _ => MINIMUM_PYPY_MINOR, + } + } +} + +/// The way the rust code is used in the wheel +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum BridgeModel { + /// A rust binary to be shipped a python package + Bin(Option), + /// A native module with pyo3 or rust-cpython bindings. + Bindings(Bindings), + /// `Bindings`, but specifically for pyo3 with feature flags that allow building a single wheel + /// for all cpython versions (pypy & graalpy still need multiple versions). + /// The numbers are the minimum major and minor version + BindingsAbi3(u8, u8), + /// A native module with c bindings, i.e. `#[no_mangle] extern "C" ` + Cffi, + /// A native module generated from uniffi + UniFfi, +} + +impl BridgeModel { + /// Returns the bindings + pub fn bindings(&self) -> Option<&Bindings> { + match self { + BridgeModel::Bin(Some(bindings)) => Some(bindings), + BridgeModel::Bindings(bindings) => Some(bindings), + _ => None, + } + } + + /// Returns the name of the bindings crate + pub fn unwrap_bindings_name(&self) -> &str { + match self { + BridgeModel::Bindings(bindings) => &bindings.name, + _ => panic!("Expected Bindings"), + } + } + + /// Test whether this is using a specific bindings crate + pub fn is_bindings(&self, name: &str) -> bool { + match self { + BridgeModel::Bin(Some(bindings)) => bindings.name == name, + BridgeModel::Bindings(bindings) => bindings.name == name, + _ => false, + } + } + + /// Test whether this is bin bindings + pub fn is_bin(&self) -> bool { + matches!(self, BridgeModel::Bin(_)) + } +} + +impl Display for BridgeModel { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + BridgeModel::Bin(Some(bindings)) => write!(f, "{} bin", bindings.name), + BridgeModel::Bin(None) => write!(f, "bin"), + BridgeModel::Bindings(bindings) => write!(f, "{}", bindings.name), + BridgeModel::BindingsAbi3(..) => write!(f, "pyo3"), + BridgeModel::Cffi => write!(f, "cffi"), + BridgeModel::UniFfi => write!(f, "uniffi"), + } + } +} diff --git a/src/build_context.rs b/src/build_context.rs index 2f9aabec5..1fef48024 100644 --- a/src/build_context.rs +++ b/src/build_context.rs @@ -10,8 +10,8 @@ use crate::project_layout::ProjectLayout; use crate::source_distribution::source_distribution; use crate::target::{Arch, Os}; use crate::{ - compile, pyproject_toml::Format, BuildArtifact, Metadata23, ModuleWriter, PyProjectToml, - PythonInterpreter, Target, + compile, pyproject_toml::Format, BridgeModel, BuildArtifact, Metadata23, ModuleWriter, + PyProjectToml, PythonInterpreter, Target, }; use anyhow::{anyhow, bail, Context, Result}; use cargo_metadata::CrateType; @@ -26,126 +26,11 @@ use platform_info::*; use sha2::{Digest, Sha256}; use std::collections::{BTreeMap, HashSet}; use std::env; -use std::fmt::{Display, Formatter}; use std::io; use std::path::{Path, PathBuf}; use std::str::FromStr; use tracing::instrument; -/// The name and version of the bindings crate -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct Bindings { - /// The name of the bindings crate, `pyo3`, `rust-cpython` or `uniffi` - pub name: String, - /// bindings crate version - pub version: semver::Version, -} - -impl Bindings { - /// Returns the minimum python minor version supported - pub fn minimal_python_minor_version(&self) -> usize { - use crate::python_interpreter::MINIMUM_PYTHON_MINOR; - - match self.name.as_str() { - "pyo3" | "pyo3-ffi" => { - let major_version = self.version.major; - let minor_version = self.version.minor; - // N.B. must check large minor versions first - if (major_version, minor_version) >= (0, 16) { - 7 - } else { - MINIMUM_PYTHON_MINOR - } - } - _ => MINIMUM_PYTHON_MINOR, - } - } - - /// Returns the minimum PyPy minor version supported - pub fn minimal_pypy_minor_version(&self) -> usize { - use crate::python_interpreter::MINIMUM_PYPY_MINOR; - - match self.name.as_str() { - "pyo3" | "pyo3-ffi" => { - let major_version = self.version.major; - let minor_version = self.version.minor; - // N.B. must check large minor versions first - if (major_version, minor_version) >= (0, 23) { - 9 - } else if (major_version, minor_version) >= (0, 14) { - 7 - } else { - MINIMUM_PYPY_MINOR - } - } - _ => MINIMUM_PYPY_MINOR, - } - } -} - -/// The way the rust code is used in the wheel -#[derive(Clone, Debug, PartialEq, Eq)] -pub enum BridgeModel { - /// A rust binary to be shipped a python package - Bin(Option), - /// A native module with pyo3 or rust-cpython bindings. - Bindings(Bindings), - /// `Bindings`, but specifically for pyo3 with feature flags that allow building a single wheel - /// for all cpython versions (pypy & graalpy still need multiple versions). - /// The numbers are the minimum major and minor version - BindingsAbi3(u8, u8), - /// A native module with c bindings, i.e. `#[no_mangle] extern "C" ` - Cffi, - /// A native module generated from uniffi - UniFfi, -} - -impl BridgeModel { - /// Returns the bindings - pub fn bindings(&self) -> Option<&Bindings> { - match self { - BridgeModel::Bin(Some(bindings)) => Some(bindings), - BridgeModel::Bindings(bindings) => Some(bindings), - _ => None, - } - } - - /// Returns the name of the bindings crate - pub fn unwrap_bindings_name(&self) -> &str { - match self { - BridgeModel::Bindings(bindings) => &bindings.name, - _ => panic!("Expected Bindings"), - } - } - - /// Test whether this is using a specific bindings crate - pub fn is_bindings(&self, name: &str) -> bool { - match self { - BridgeModel::Bin(Some(bindings)) => bindings.name == name, - BridgeModel::Bindings(bindings) => bindings.name == name, - _ => false, - } - } - - /// Test whether this is bin bindings - pub fn is_bin(&self) -> bool { - matches!(self, BridgeModel::Bin(_)) - } -} - -impl Display for BridgeModel { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - match self { - BridgeModel::Bin(Some(bindings)) => write!(f, "{} bin", bindings.name), - BridgeModel::Bin(None) => write!(f, "bin"), - BridgeModel::Bindings(bindings) => write!(f, "{}", bindings.name), - BridgeModel::BindingsAbi3(..) => write!(f, "pyo3"), - BridgeModel::Cffi => write!(f, "cffi"), - BridgeModel::UniFfi => write!(f, "uniffi"), - } - } -} - /// Insert wasm launcher scripts as entrypoints and the wasmtime dependency fn bin_wasi_helper( artifacts_and_files: &[(&BuildArtifact, String)], diff --git a/src/build_options.rs b/src/build_options.rs index 9bdcb0c54..674b66fe2 100644 --- a/src/build_options.rs +++ b/src/build_options.rs @@ -1,11 +1,10 @@ use crate::auditwheel::{AuditWheelMode, PlatformTag}; -use crate::build_context::BridgeModel; use crate::compile::{CompileTarget, LIB_CRATE_TYPES}; use crate::cross_compile::{find_sysconfigdata, parse_sysconfigdata}; use crate::project_layout::ProjectResolver; use crate::pyproject_toml::ToolMaturin; use crate::python_interpreter::{InterpreterConfig, InterpreterKind}; -use crate::{Bindings, BuildContext, PythonInterpreter, Target}; +use crate::{Bindings, BridgeModel, BuildContext, PythonInterpreter, Target}; use anyhow::{bail, format_err, Context, Result}; use cargo_metadata::{CrateType, TargetKind}; use cargo_metadata::{Metadata, Node}; diff --git a/src/compile.rs b/src/compile.rs index ba85e6a85..452de08ba 100644 --- a/src/compile.rs +++ b/src/compile.rs @@ -1,8 +1,7 @@ -use crate::build_context::BridgeModel; use crate::target::RUST_1_64_0; #[cfg(feature = "zig")] use crate::PlatformTag; -use crate::{BuildContext, PythonInterpreter, Target}; +use crate::{BridgeModel, BuildContext, PythonInterpreter, Target}; use anyhow::{anyhow, bail, Context, Result}; use cargo_metadata::CrateType; use fat_macho::FatWriter; diff --git a/src/lib.rs b/src/lib.rs index 04cd33280..d2e8420fc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -23,7 +23,8 @@ #![deny(missing_docs)] -pub use crate::build_context::{Bindings, BridgeModel, BuildContext, BuiltWheelMetadata}; +pub use crate::bridge::{Bindings, BridgeModel}; +pub use crate::build_context::{BuildContext, BuiltWheelMetadata}; pub use crate::build_options::{BuildOptions, CargoOptions}; pub use crate::cargo_toml::CargoToml; pub use crate::compile::{compile, BuildArtifact}; @@ -44,6 +45,7 @@ pub use crate::upload::{upload, upload_ui, PublishOpt, Registry, UploadError}; pub use auditwheel::PlatformTag; mod auditwheel; +mod bridge; mod build_context; mod build_options; mod cargo_toml;