Skip to content

Commit

Permalink
Merge pull request #716 from messense/macosx-deployment-target
Browse files Browse the repository at this point in the history
Account for `MACOSX_DEPLOYMENT_TARGET` env var in wheel platform tag
  • Loading branch information
messense authored Nov 29, 2021
2 parents 449d9ee + 81dc578 commit dc85742
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 38 deletions.
1 change: 1 addition & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Revert back to Rust 2018 edition in [#710](https://github.com/PyO3/maturin/pull/710)
* Warn missing `cffi` package dependency in [#711](https://github.com/PyO3/maturin/pull/711)
* Add support for Illumos in [#712](https://github.com/PyO3/maturin/pull/712)
* Account for `MACOSX_DEPLOYMENT_TARGET` env var in wheel platform tag in [#716](https://github.com/PyO3/maturin/pull/716)

## [0.12.2] - 2021-11-26

Expand Down
10 changes: 6 additions & 4 deletions src/build_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,9 @@ impl BuildContext {
major: u8,
min_minor: u8,
) -> Result<BuiltWheelMetadata> {
let platform = self.target.get_platform_tag(platform_tag, self.universal2);
let platform = self
.target
.get_platform_tag(platform_tag, self.universal2)?;
let tag = format!("cp{}{}-abi3-{}", major, min_minor, platform);

let mut writer = WheelWriter::new(&tag, &self.out, &self.metadata21, &[tag.clone()])?;
Expand Down Expand Up @@ -343,7 +345,7 @@ impl BuildContext {
artifact: &Path,
platform_tag: PlatformTag,
) -> Result<BuiltWheelMetadata> {
let tag = python_interpreter.get_tag(platform_tag, self.universal2);
let tag = python_interpreter.get_tag(platform_tag, self.universal2)?;

let mut writer = WheelWriter::new(&tag, &self.out, &self.metadata21, &[tag.clone()])?;

Expand Down Expand Up @@ -437,7 +439,7 @@ impl BuildContext {
) -> Result<BuiltWheelMetadata> {
let (tag, tags) = self
.target
.get_universal_tags(platform_tag, self.universal2);
.get_universal_tags(platform_tag, self.universal2)?;

let mut writer = WheelWriter::new(&tag, &self.out, &self.metadata21, &tags)?;

Expand Down Expand Up @@ -490,7 +492,7 @@ impl BuildContext {
) -> Result<BuiltWheelMetadata> {
let (tag, tags) = self
.target
.get_universal_tags(platform_tag, self.universal2);
.get_universal_tags(platform_tag, self.universal2)?;

if !self.metadata21.scripts.is_empty() {
bail!("Defining entrypoints and working with a binary doesn't mix well");
Expand Down
6 changes: 3 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -379,18 +379,18 @@ fn pep517(subcommand: Pep517Command) -> Result<()> {
// Since afaik all other PEP 517 backends also return linux tagged wheels, we do so too
let tags = match context.bridge {
BridgeModel::Bindings(_) => {
vec![context.interpreter[0].get_tag(PlatformTag::Linux, context.universal2)]
vec![context.interpreter[0].get_tag(PlatformTag::Linux, context.universal2)?]
}
BridgeModel::BindingsAbi3(major, minor) => {
let platform = context
.target
.get_platform_tag(PlatformTag::Linux, context.universal2);
.get_platform_tag(PlatformTag::Linux, context.universal2)?;
vec![format!("cp{}{}-abi3-{}", major, minor, platform)]
}
BridgeModel::Bin | BridgeModel::Cffi => {
context
.target
.get_universal_tags(PlatformTag::Linux, context.universal2)
.get_universal_tags(PlatformTag::Linux, context.universal2)?
.1
}
};
Expand Down
17 changes: 10 additions & 7 deletions src/python_interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -360,20 +360,22 @@ impl PythonInterpreter {
/// Don't ask me why or how, this is just what setuptools uses so I'm also going to use
///
/// If abi3 is true, cpython wheels use the generic abi3 with the given version as minimum
pub fn get_tag(&self, platform_tag: PlatformTag, universal2: bool) -> String {
pub fn get_tag(&self, platform_tag: PlatformTag, universal2: bool) -> Result<String> {
// Restrict `sysconfig.get_platform()` usage to Windows and non-portable Linux only for now
// so we don't need to deal with macOS deployment target
let use_sysconfig_platform = self.target.is_windows()
|| (self.target.is_linux() && !platform_tag.is_portable())
|| self.target.is_illumos();
let platform = if use_sysconfig_platform {
self.platform
.clone()
.unwrap_or_else(|| self.target.get_platform_tag(platform_tag, universal2))
if let Some(platform) = self.platform.clone() {
platform
} else {
self.target.get_platform_tag(platform_tag, universal2)?
}
} else {
self.target.get_platform_tag(platform_tag, universal2)
self.target.get_platform_tag(platform_tag, universal2)?
};
match self.interpreter_kind {
let tag = match self.interpreter_kind {
InterpreterKind::CPython => {
if self.target.is_unix() {
format!(
Expand Down Expand Up @@ -408,7 +410,8 @@ impl PythonInterpreter {
platform = platform,
)
}
}
};
Ok(tag)
}

/// Adds the ext_suffix we read from python or know (.pyd/.abi3.so) and adds it to the base name
Expand Down
120 changes: 96 additions & 24 deletions src/target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,8 @@ impl Target {
}

/// Returns the platform part of the tag for the wheel name
pub fn get_platform_tag(&self, platform_tag: PlatformTag, universal2: bool) -> String {
match (&self.os, &self.arch) {
pub fn get_platform_tag(&self, platform_tag: PlatformTag, universal2: bool) -> Result<String> {
let tag = match (&self.os, &self.arch) {
// FreeBSD
(Os::FreeBsd, Arch::X86_64)
| (Os::FreeBsd, Arch::Aarch64)
Expand All @@ -172,10 +172,7 @@ impl Target {
| (Os::OpenBsd, Arch::X86)
| (Os::OpenBsd, Arch::X86_64)
| (Os::OpenBsd, Arch::Aarch64) => {
let info = match PlatformInfo::new() {
Ok(info) => info,
Err(error) => panic!("{}", error),
};
let info = PlatformInfo::new()?;
let release = info.release().replace(".", "_").replace("-", "_");
let arch = match self.arch {
Arch::X86_64 => "amd64",
Expand All @@ -195,17 +192,14 @@ impl Target {
)
}
(Os::Illumos, Arch::X86_64) => {
let info = match PlatformInfo::new() {
Ok(info) => info,
Err(error) => panic!("{}", error),
};
let info = PlatformInfo::new()?;
let mut release = info.release().replace(".", "_").replace("-", "_");
let mut arch = info.machine().replace(' ', "_").replace('/', "_");

let mut os = self.os.to_string().to_ascii_lowercase();
// See https://github.com/python/cpython/blob/46c8d915715aa2bd4d697482aa051fe974d440e1/Lib/sysconfig.py#L722-L730
if let Some((major, other)) = release.split_once('_') {
let major_ver: u64 = major.parse().expect("illumos major version is not a number");
let major_ver: u64 = major.parse().context("illumos major version is not a number")?;
if major_ver >= 5 {
// SunOS 5 == Solaris 2
os = "solaris".to_string();
Expand Down Expand Up @@ -235,24 +229,39 @@ impl Target {
tags.join(".")
}
(Os::Macos, Arch::X86_64) => {
let ((x86_64_major, x86_64_minor), (arm64_major, arm64_minor)) = macosx_deployment_target(env::var("MACOSX_DEPLOYMENT_TARGET").ok().as_deref(), universal2)?;
if universal2 {
"macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2".to_string()
format!(
"macosx_{x86_64_major}_{x86_64_minor}_x86_64.macosx_{arm64_major}_{arm64_minor}_arm64.macosx_{x86_64_major}_{x86_64_minor}_universal2",
x86_64_major = x86_64_major,
x86_64_minor = x86_64_minor,
arm64_major = arm64_major,
arm64_minor = arm64_minor
)
} else {
"macosx_10_7_x86_64".to_string()
format!("macosx_{}_{}_x86_64", x86_64_major, x86_64_minor)
}
}
(Os::Macos, Arch::Aarch64) => {
let ((x86_64_major, x86_64_minor), (arm64_major, arm64_minor)) = macosx_deployment_target(env::var("MACOSX_DEPLOYMENT_TARGET").ok().as_deref(), universal2)?;
if universal2 {
"macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2".to_string()
format!(
"macosx_{x86_64_major}_{x86_64_minor}_x86_64.macosx_{arm64_major}_{arm64_minor}_arm64.macosx_{x86_64_major}_{x86_64_minor}_universal2",
x86_64_major = x86_64_major,
x86_64_minor = x86_64_minor,
arm64_major = arm64_major,
arm64_minor = arm64_minor
)
} else {
"macosx_11_0_arm64".to_string()
format!("macosx_{}_{}_arm64", arm64_major, arm64_minor)
}
}
(Os::Windows, Arch::X86) => "win32".to_string(),
(Os::Windows, Arch::X86_64) => "win_amd64".to_string(),
(Os::Windows, Arch::Aarch64) => "win_arm64".to_string(),
(_, _) => panic!("unsupported target should not have reached get_platform_tag()"),
}
};
Ok(tag)
}

/// Returns the name python uses in `sys.platform` for this os
Expand Down Expand Up @@ -351,11 +360,12 @@ impl Target {
}

/// Returns the tags for the WHEEL file for cffi wheels
pub fn get_py3_tags(&self, platform_tag: PlatformTag, universal2: bool) -> Vec<String> {
vec![format!(
pub fn get_py3_tags(&self, platform_tag: PlatformTag, universal2: bool) -> Result<Vec<String>> {
let tags = vec![format!(
"py3-none-{}",
self.get_platform_tag(platform_tag, universal2)
)]
self.get_platform_tag(platform_tag, universal2)?
)];
Ok(tags)
}

/// Returns the path to the python executable inside a venv
Expand Down Expand Up @@ -425,13 +435,13 @@ impl Target {
&self,
platform_tag: PlatformTag,
universal2: bool,
) -> (String, Vec<String>) {
) -> Result<(String, Vec<String>)> {
let tag = format!(
"py3-none-{platform}",
platform = self.get_platform_tag(platform_tag, universal2)
platform = self.get_platform_tag(platform_tag, universal2)?
);
let tags = self.get_py3_tags(platform_tag, universal2);
(tag, tags)
let tags = self.get_py3_tags(platform_tag, universal2)?;
Ok((tag, tags))
}
}

Expand Down Expand Up @@ -468,3 +478,65 @@ pub(crate) fn get_host_target() -> Result<String> {
.to_string();
Ok(host)
}

fn macosx_deployment_target(
deploy_target: Option<&str>,
universal2: bool,
) -> Result<((usize, usize), (usize, usize))> {
let x86_64_default = if universal2 { (10, 9) } else { (10, 7) };
let arm64_default = (11, 0);
let mut x86_64_ver = x86_64_default;
let mut arm64_ver = arm64_default;
if let Some(deploy_target) = deploy_target {
let err_ctx = "MACOSX_DEPLOYMENT_TARGET is invalid";
let mut parts = deploy_target.split('.');
let major = parts.next().context(err_ctx)?;
let major: usize = major.parse().context(err_ctx)?;
let minor = parts.next().context(err_ctx)?;
let minor: usize = minor.parse().context(err_ctx)?;
if (major, minor) > x86_64_default {
x86_64_ver = (major, minor);
}
if (major, minor) > arm64_default {
arm64_ver = (major, minor);
}
}
Ok((x86_64_ver, arm64_ver))
}

#[cfg(test)]
mod test {
use super::macosx_deployment_target;

#[test]
fn test_macosx_deployment_target() {
assert_eq!(
macosx_deployment_target(None, false).unwrap(),
(((10, 7), (11, 0)))
);
assert_eq!(
macosx_deployment_target(None, true).unwrap(),
(((10, 9), (11, 0)))
);
assert_eq!(
macosx_deployment_target(Some("10.6"), false).unwrap(),
(((10, 7), (11, 0)))
);
assert_eq!(
macosx_deployment_target(Some("10.6"), true).unwrap(),
(((10, 9), (11, 0)))
);
assert_eq!(
macosx_deployment_target(Some("10.9"), false).unwrap(),
(((10, 9), (11, 0)))
);
assert_eq!(
macosx_deployment_target(Some("11.0.0"), false).unwrap(),
(((11, 0), (11, 0)))
);
assert_eq!(
macosx_deployment_target(Some("11.1"), false).unwrap(),
(((11, 1), (11, 1)))
);
}
}

0 comments on commit dc85742

Please sign in to comment.