Auto merge of #138947 - madsmtm:refactor-apple-versions, r=Noratrieb
Refactor Apple version handling in the compiler Move various Apple version handling code in the compiler out `rustc_codegen_ssa` and into a place where it can be accessed by `rustc_attr_parsing`, which I found to be necessary when doing https://github.com/rust-lang/rust/pull/136867. Thought I'd split it out to make it easier to land, and to make further changes like https://github.com/rust-lang/rust/pull/131477 have fewer conflicts / PR dependencies. There should be no functional changes in this PR. `@rustbot` label O-apple r? rust-lang/compiler
This commit is contained in:
commit
f5c510260b
17 changed files with 190 additions and 166 deletions
|
@ -12,6 +12,7 @@
|
|||
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
||||
#![doc(rust_logo)]
|
||||
#![feature(assert_matches)]
|
||||
#![feature(debug_closure_helpers)]
|
||||
#![feature(iter_intersperse)]
|
||||
#![feature(let_chains)]
|
||||
#![feature(rustc_attrs)]
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
use std::borrow::Cow;
|
||||
use std::env;
|
||||
use std::fmt::{Display, from_fn};
|
||||
use std::num::ParseIntError;
|
||||
use std::str::FromStr;
|
||||
|
||||
use crate::spec::{
|
||||
BinaryFormat, Cc, DebuginfoKind, FloatAbi, FramePointer, LinkerFlavor, Lld, RustcAbi,
|
||||
SplitDebuginfo, StackProbeType, StaticCow, TargetOptions, cvs,
|
||||
SplitDebuginfo, StackProbeType, StaticCow, Target, TargetOptions, cvs,
|
||||
};
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -222,3 +225,107 @@ fn link_env_remove(os: &'static str) -> StaticCow<[StaticCow<str>]> {
|
|||
cvs!["MACOSX_DEPLOYMENT_TARGET"]
|
||||
}
|
||||
}
|
||||
|
||||
/// Deployment target or SDK version.
|
||||
///
|
||||
/// The size of the numbers in here are limited by Mach-O's `LC_BUILD_VERSION`.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct OSVersion {
|
||||
pub major: u16,
|
||||
pub minor: u8,
|
||||
pub patch: u8,
|
||||
}
|
||||
|
||||
impl FromStr for OSVersion {
|
||||
type Err = ParseIntError;
|
||||
|
||||
/// Parse an OS version triple (SDK version or deployment target).
|
||||
fn from_str(version: &str) -> Result<Self, ParseIntError> {
|
||||
if let Some((major, minor)) = version.split_once('.') {
|
||||
let major = major.parse()?;
|
||||
if let Some((minor, patch)) = minor.split_once('.') {
|
||||
Ok(Self { major, minor: minor.parse()?, patch: patch.parse()? })
|
||||
} else {
|
||||
Ok(Self { major, minor: minor.parse()?, patch: 0 })
|
||||
}
|
||||
} else {
|
||||
Ok(Self { major: version.parse()?, minor: 0, patch: 0 })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl OSVersion {
|
||||
pub fn new(major: u16, minor: u8, patch: u8) -> Self {
|
||||
Self { major, minor, patch }
|
||||
}
|
||||
|
||||
pub fn fmt_pretty(self) -> impl Display {
|
||||
let Self { major, minor, patch } = self;
|
||||
from_fn(move |f| {
|
||||
write!(f, "{major}.{minor}")?;
|
||||
if patch != 0 {
|
||||
write!(f, ".{patch}")?;
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
pub fn fmt_full(self) -> impl Display {
|
||||
let Self { major, minor, patch } = self;
|
||||
from_fn(move |f| write!(f, "{major}.{minor}.{patch}"))
|
||||
}
|
||||
|
||||
/// Minimum operating system versions currently supported by `rustc`.
|
||||
pub fn os_minimum_deployment_target(os: &str) -> Self {
|
||||
// When bumping a version in here, remember to update the platform-support docs too.
|
||||
//
|
||||
// NOTE: The defaults may change in future `rustc` versions, so if you are looking for the
|
||||
// default deployment target, prefer:
|
||||
// ```
|
||||
// $ rustc --print deployment-target
|
||||
// ```
|
||||
let (major, minor, patch) = match os {
|
||||
"macos" => (10, 12, 0),
|
||||
"ios" => (10, 0, 0),
|
||||
"tvos" => (10, 0, 0),
|
||||
"watchos" => (5, 0, 0),
|
||||
"visionos" => (1, 0, 0),
|
||||
_ => unreachable!("tried to get deployment target for non-Apple platform"),
|
||||
};
|
||||
Self { major, minor, patch }
|
||||
}
|
||||
|
||||
/// The deployment target for the given target.
|
||||
///
|
||||
/// This is similar to `os_minimum_deployment_target`, except that on certain targets it makes sense
|
||||
/// to raise the minimum OS version.
|
||||
///
|
||||
/// This matches what LLVM does, see in part:
|
||||
/// <https://github.com/llvm/llvm-project/blob/llvmorg-18.1.8/llvm/lib/TargetParser/Triple.cpp#L1900-L1932>
|
||||
pub fn minimum_deployment_target(target: &Target) -> Self {
|
||||
let (major, minor, patch) = match (&*target.os, &*target.arch, &*target.abi) {
|
||||
("macos", "aarch64", _) => (11, 0, 0),
|
||||
("ios", "aarch64", "macabi") => (14, 0, 0),
|
||||
("ios", "aarch64", "sim") => (14, 0, 0),
|
||||
("ios", _, _) if target.llvm_target.starts_with("arm64e") => (14, 0, 0),
|
||||
// Mac Catalyst defaults to 13.1 in Clang.
|
||||
("ios", _, "macabi") => (13, 1, 0),
|
||||
("tvos", "aarch64", "sim") => (14, 0, 0),
|
||||
("watchos", "aarch64", "sim") => (7, 0, 0),
|
||||
(os, _, _) => return Self::os_minimum_deployment_target(os),
|
||||
};
|
||||
Self { major, minor, patch }
|
||||
}
|
||||
}
|
||||
|
||||
/// Name of the environment variable used to fetch the deployment target on the given OS.
|
||||
pub fn deployment_target_env_var(os: &str) -> &'static str {
|
||||
match os {
|
||||
"macos" => "MACOSX_DEPLOYMENT_TARGET",
|
||||
"ios" => "IPHONEOS_DEPLOYMENT_TARGET",
|
||||
"watchos" => "WATCHOS_DEPLOYMENT_TARGET",
|
||||
"tvos" => "TVOS_DEPLOYMENT_TARGET",
|
||||
"visionos" => "XROS_DEPLOYMENT_TARGET",
|
||||
_ => unreachable!("tried to get deployment target env var for non-Apple platform"),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use super::OSVersion;
|
||||
use crate::spec::targets::{
|
||||
aarch64_apple_darwin, aarch64_apple_ios_sim, aarch64_apple_visionos_sim,
|
||||
aarch64_apple_watchos_sim, i686_apple_darwin, x86_64_apple_darwin, x86_64_apple_ios,
|
||||
|
@ -42,3 +43,11 @@ fn macos_link_environment_unmodified() {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_version() {
|
||||
assert_eq!("10".parse(), Ok(OSVersion::new(10, 0, 0)));
|
||||
assert_eq!("10.12".parse(), Ok(OSVersion::new(10, 12, 0)));
|
||||
assert_eq!("10.12.6".parse(), Ok(OSVersion::new(10, 12, 6)));
|
||||
assert_eq!("9999.99.99".parse(), Ok(OSVersion::new(9999, 99, 99)));
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
pub(crate) mod aix;
|
||||
pub(crate) mod android;
|
||||
pub(crate) mod apple;
|
||||
pub mod apple;
|
||||
pub(crate) mod avr;
|
||||
pub(crate) mod bpf;
|
||||
pub(crate) mod cygwin;
|
||||
|
|
|
@ -60,6 +60,7 @@ pub mod crt_objects;
|
|||
mod base;
|
||||
mod json;
|
||||
|
||||
pub use base::apple;
|
||||
pub use base::avr::ef_avr_arch;
|
||||
|
||||
/// Linker is called through a C/C++ compiler.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue