diff --git a/Readme.md b/Readme.md index a4d109a9d..4e006cbca 100644 --- a/Readme.md +++ b/Readme.md @@ -211,7 +211,7 @@ To include arbitrary files in the sdist for use during compilation specify `sdis sdist-include = ["path/**/*"] ``` -There's a `cargo sdist` command for only building a source distribution as workaround for [pypa/pip#6041](https://github.com/pypa/pip/issues/6041). +There's a `maturin sdist` command for only building a source distribution as workaround for [pypa/pip#6041](https://github.com/pypa/pip/issues/6041). ## Manylinux and auditwheel diff --git a/src/build_options.rs b/src/build_options.rs index efe62863f..549a9087d 100644 --- a/src/build_options.rs +++ b/src/build_options.rs @@ -5,6 +5,7 @@ use crate::python_interpreter::InterpreterKind; use crate::BuildContext; use crate::CargoToml; use crate::Metadata21; +use crate::PyProjectToml; use crate::PythonInterpreter; use crate::Target; use anyhow::{bail, format_err, Context, Result}; @@ -130,6 +131,12 @@ impl BuildOptions { let cargo_toml = CargoToml::from_path(&manifest_file)?; let manifest_dir = manifest_file.parent().unwrap(); + let pyproject: Option = if manifest_dir.join("pyproject.toml").is_file() { + Some(PyProjectToml::new(manifest_dir).context("pyproject.toml is invalid")?) + } else { + None + }; + let pyproject = pyproject.as_ref(); let metadata21 = Metadata21::from_cargo_toml(&cargo_toml, &manifest_dir) .context("Failed to parse Cargo.toml into python metadata")?; let extra_metadata = cargo_toml.remaining_core_metadata(); @@ -158,7 +165,14 @@ impl BuildOptions { extra_metadata.python_source.as_deref(), )?; - let mut cargo_extra_args = split_extra_args(&self.cargo_extra_args)?; + let mut cargo_extra_args = self.cargo_extra_args.clone(); + if cargo_extra_args.is_empty() { + // if not supplied on command line, try pyproject.toml + if let Some(args) = pyproject.and_then(|x| x.cargo_extra_args()) { + cargo_extra_args.push(args.to_string()); + } + } + cargo_extra_args = split_extra_args(&cargo_extra_args)?; if let Some(ref target) = self.target { cargo_extra_args.extend(vec!["--target".to_string(), target.clone()]); } @@ -183,7 +197,12 @@ impl BuildOptions { } }; - let bridge = find_bridge(&cargo_metadata, self.bindings.as_deref())?; + let bridge = find_bridge( + &cargo_metadata, + self.bindings + .as_deref() + .or_else(|| pyproject.and_then(|x| x.bindings())), + )?; if bridge != BridgeModel::Bin && module_name.contains('-') { bail!( @@ -208,7 +227,14 @@ impl BuildOptions { None => find_interpreter(&bridge, &[], &target, get_min_python_minor(&metadata21))?, }; - let rustc_extra_args = split_extra_args(&self.rustc_extra_args)?; + let mut rustc_extra_args = self.rustc_extra_args.clone(); + if rustc_extra_args.is_empty() { + // if not supplied on command line, try pyproject.toml + if let Some(args) = pyproject.and_then(|x| x.rustc_extra_args()) { + rustc_extra_args.push(args.to_string()); + } + } + rustc_extra_args = split_extra_args(&rustc_extra_args)?; let mut universal2 = self.universal2; // Also try to determine universal2 from ARCHFLAGS environment variable @@ -228,6 +254,12 @@ impl BuildOptions { universal2 = true; } }; + let strip = pyproject.map(|x| x.strip()).unwrap_or_default() || strip; + let skip_auditwheel = + pyproject.map(|x| x.skip_auditwheel()).unwrap_or_default() || self.skip_auditwheel; + let platform_tag = self + .platform_tag + .or_else(|| pyproject.and_then(|x| x.compatibility())); Ok(BuildContext { target, @@ -240,8 +272,8 @@ impl BuildOptions { out: wheel_dir, release, strip, - skip_auditwheel: self.skip_auditwheel, - platform_tag: self.platform_tag, + skip_auditwheel, + platform_tag, cargo_extra_args, rustc_extra_args, interpreter, diff --git a/src/pyproject_toml.rs b/src/pyproject_toml.rs index 983387b85..caf363e71 100644 --- a/src/pyproject_toml.rs +++ b/src/pyproject_toml.rs @@ -1,3 +1,4 @@ +use crate::PlatformTag; use anyhow::{format_err, Context, Result}; use pyproject_toml::PyProjectToml as ProjectToml; use serde::{Deserialize, Serialize}; @@ -16,6 +17,15 @@ pub struct Tool { #[serde(rename_all = "kebab-case")] pub struct ToolMaturin { sdist_include: Option>, + bindings: Option, + cargo_extra_args: Option, + #[serde(alias = "manylinux")] + compatibility: Option, + rustc_extra_args: Option, + #[serde(default)] + skip_auditwheel: bool, + #[serde(default)] + strip: bool, } /// A pyproject.toml as specified in PEP 517 @@ -57,11 +67,59 @@ impl PyProjectToml { Ok(pyproject) } - /// Returns the value of `[maturin.sdist-include]` in pyproject.toml + /// Returns the value of `[tool.maturin.sdist-include]` in pyproject.toml pub fn sdist_include(&self) -> Option<&Vec> { self.tool.as_ref()?.maturin.as_ref()?.sdist_include.as_ref() } + /// Returns the value of `[tool.maturin.bindings]` in pyproject.toml + pub fn bindings(&self) -> Option<&str> { + self.tool.as_ref()?.maturin.as_ref()?.bindings.as_deref() + } + + /// Returns the value of `[tool.maturin.cargo-extra-args]` in pyproject.toml + pub fn cargo_extra_args(&self) -> Option<&str> { + self.tool + .as_ref()? + .maturin + .as_ref()? + .cargo_extra_args + .as_deref() + } + + /// Returns the value of `[tool.maturin.compatibility]` in pyproject.toml + pub fn compatibility(&self) -> Option { + self.tool.as_ref()?.maturin.as_ref()?.compatibility + } + + /// Returns the value of `[tool.maturin.rustc-extra-args]` in pyproject.toml + pub fn rustc_extra_args(&self) -> Option<&str> { + self.tool + .as_ref()? + .maturin + .as_ref()? + .rustc_extra_args + .as_deref() + } + + /// Returns the value of `[tool.maturin.skip-auditwheel]` in pyproject.toml + pub fn skip_auditwheel(&self) -> bool { + self.tool + .as_ref() + .and_then(|tool| tool.maturin.as_ref()) + .map(|maturin| maturin.skip_auditwheel) + .unwrap_or_default() + } + + /// Returns the value of `[tool.maturin.strip]` in pyproject.toml + pub fn strip(&self) -> bool { + self.tool + .as_ref() + .and_then(|tool| tool.maturin.as_ref()) + .map(|maturin| maturin.strip) + .unwrap_or_default() + } + /// Having a pyproject.toml without a version constraint is a bad idea /// because at some point we'll have to do breaking changes and then source /// distributions would break