Skip to content

Apple: Refactor deployment target version parsing #129341

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

Merged
merged 3 commits into from
Sep 7, 2024
Merged
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
33 changes: 24 additions & 9 deletions compiler/rustc_codegen_ssa/src/back/metadata.rs
Original file line number Diff line number Diff line change
@@ -372,27 +372,42 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
Some(file)
}

/// Since Xcode 15 Apple's LD requires object files to contain information about what they were
/// built for (LC_BUILD_VERSION): the platform (macOS/watchOS etc), minimum OS version, and SDK
/// version. This returns a `MachOBuildVersion` for the target.
/// Mach-O files contain information about:
/// - The platform/OS they were built for (macOS/watchOS/Mac Catalyst/iOS simulator etc).
/// - The minimum OS version / deployment target.
/// - The version of the SDK they were targetting.
///
/// In the past, this was accomplished using the LC_VERSION_MIN_MACOSX, LC_VERSION_MIN_IPHONEOS,
/// LC_VERSION_MIN_TVOS or LC_VERSION_MIN_WATCHOS load commands, which each contain information
/// about the deployment target and SDK version, and implicitly, by their presence, which OS they
/// target. Simulator targets were determined if the architecture was x86_64, but there was e.g. a
/// LC_VERSION_MIN_IPHONEOS present.
///
/// This is of course brittle and limited, so modern tooling emit the LC_BUILD_VERSION load
/// command (which contains all three pieces of information in one) when the deployment target is
/// high enough, or the target is something that wouldn't be encodable with the old load commands
/// (such as Mac Catalyst, or Aarch64 iOS simulator).
///
/// Since Xcode 15, Apple's LD apparently requires object files to use this load command, so this
/// returns the `MachOBuildVersion` for the target to do so.
fn macho_object_build_version_for_target(target: &Target) -> object::write::MachOBuildVersion {
/// The `object` crate demands "X.Y.Z encoded in nibbles as xxxx.yy.zz"
/// e.g. minOS 14.0 = 0x000E0000, or SDK 16.2 = 0x00100200
fn pack_version((major, minor): (u32, u32)) -> u32 {
(major << 16) | (minor << 8)
fn pack_version((major, minor, patch): (u16, u8, u8)) -> u32 {
let (major, minor, patch) = (major as u32, minor as u32, patch as u32);
(major << 16) | (minor << 8) | patch
}

let platform =
rustc_target::spec::current_apple_platform(target).expect("unknown Apple target OS");
let min_os = rustc_target::spec::current_apple_deployment_target(target)
.expect("unknown Apple target OS");
let sdk =
let min_os = rustc_target::spec::current_apple_deployment_target(target);
let (sdk_major, sdk_minor) =
rustc_target::spec::current_apple_sdk_version(platform).expect("unknown Apple target OS");

let mut build_version = object::write::MachOBuildVersion::default();
build_version.platform = platform;
build_version.minos = pack_version(min_os);
build_version.sdk = pack_version(sdk);
build_version.sdk = pack_version((sdk_major, sdk_minor, 0));
build_version
}

6 changes: 3 additions & 3 deletions compiler/rustc_driver_impl/src/lib.rs
Original file line number Diff line number Diff line change
@@ -871,9 +871,9 @@ fn print_crate_info(
use rustc_target::spec::current_apple_deployment_target;

if sess.target.is_like_osx {
let (major, minor) = current_apple_deployment_target(&sess.target)
.expect("unknown Apple target OS");
println_info!("deployment_target={}", format!("{major}.{minor}"))
let (major, minor, patch) = current_apple_deployment_target(&sess.target);
let patch = if patch != 0 { format!(".{patch}") } else { String::new() };
println_info!("deployment_target={major}.{minor}{patch}")
} else {
#[allow(rustc::diagnostic_outside_of_impl)]
sess.dcx().fatal("only Apple targets currently support deployment version info")
329 changes: 184 additions & 145 deletions compiler/rustc_target/src/spec/base/apple/mod.rs

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions compiler/rustc_target/src/spec/base/apple/tests.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use super::parse_version;
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!(parse_version("10"), Ok((10, 0, 0)));
assert_eq!(parse_version("10.12"), Ok((10, 12, 0)));
assert_eq!(parse_version("10.12.6"), Ok((10, 12, 6)));
assert_eq!(parse_version("9999.99.99"), Ok((9999, 99, 99)));
}
4 changes: 2 additions & 2 deletions compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
@@ -60,8 +60,8 @@ pub mod crt_objects;

mod base;
pub use base::apple::{
deployment_target as current_apple_deployment_target, platform as current_apple_platform,
sdk_version as current_apple_sdk_version,
deployment_target_for_target as current_apple_deployment_target,
platform as current_apple_platform, sdk_version as current_apple_sdk_version,
};
pub use base::avr_gnu::ef_avr_arch;

24 changes: 9 additions & 15 deletions compiler/rustc_target/src/spec/targets/aarch64_apple_darwin.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,10 @@
use crate::spec::base::apple::{macos_llvm_target, opts, Arch, TargetAbi};
use crate::spec::base::apple::{base, Arch, TargetAbi};
use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions};

pub(crate) fn target() -> Target {
let arch = Arch::Arm64;
let mut base = opts("macos", arch, TargetAbi::Normal);
base.cpu = "apple-m1".into();
base.max_atomic_width = Some(128);

// FIXME: The leak sanitizer currently fails the tests, see #88132.
base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::THREAD;

let (opts, llvm_target, arch) = base("macos", Arch::Arm64, TargetAbi::Normal);
Target {
// Clang automatically chooses a more specific target based on
// MACOSX_DEPLOYMENT_TARGET. To enable cross-language LTO to work
// correctly, we do too.
llvm_target: macos_llvm_target(arch).into(),
llvm_target,
metadata: crate::spec::TargetMetadata {
description: Some("ARM64 macOS (11.0+, Big Sur+)".into()),
tier: Some(1),
@@ -23,11 +13,15 @@ pub(crate) fn target() -> Target {
},
pointer_width: 64,
data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(),
arch: arch.target_arch(),
arch,
options: TargetOptions {
mcount: "\u{1}mcount".into(),
frame_pointer: FramePointer::NonLeaf,
..base
cpu: "apple-m1".into(),
max_atomic_width: Some(128),
// FIXME: The leak sanitizer currently fails the tests, see #88132.
supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::THREAD,
..opts
},
}
}
18 changes: 6 additions & 12 deletions compiler/rustc_target/src/spec/targets/aarch64_apple_ios.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,10 @@
use crate::spec::base::apple::{ios_llvm_target, opts, Arch, TargetAbi};
use crate::spec::base::apple::{base, Arch, TargetAbi};
use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions};

pub(crate) fn target() -> Target {
let arch = Arch::Arm64;
let mut base = opts("ios", arch, TargetAbi::Normal);
base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD;

let (opts, llvm_target, arch) = base("ios", Arch::Arm64, TargetAbi::Normal);
Target {
// Clang automatically chooses a more specific target based on
// IPHONEOS_DEPLOYMENT_TARGET.
// This is required for the target to pick the right
// MACH-O commands, so we do too.
llvm_target: ios_llvm_target(arch).into(),
llvm_target,
metadata: crate::spec::TargetMetadata {
description: Some("ARM64 iOS".into()),
tier: Some(2),
@@ -20,12 +13,13 @@ pub(crate) fn target() -> Target {
},
pointer_width: 64,
data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(),
arch: arch.target_arch(),
arch,
options: TargetOptions {
features: "+neon,+fp-armv8,+apple-a7".into(),
max_atomic_width: Some(128),
frame_pointer: FramePointer::NonLeaf,
..base
supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::THREAD,
..opts
},
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
use crate::spec::base::apple::{mac_catalyst_llvm_target, opts, Arch, TargetAbi};
use crate::spec::base::apple::{base, Arch, TargetAbi};
use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions};

pub(crate) fn target() -> Target {
let arch = Arch::Arm64;
let mut base = opts("ios", arch, TargetAbi::MacCatalyst);
base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::THREAD;

let (opts, llvm_target, arch) = base("ios", Arch::Arm64, TargetAbi::MacCatalyst);
Target {
llvm_target: mac_catalyst_llvm_target(arch).into(),
llvm_target,
metadata: crate::spec::TargetMetadata {
description: Some("Apple Catalyst on ARM64".into()),
tier: Some(2),
@@ -16,12 +13,13 @@ pub(crate) fn target() -> Target {
},
pointer_width: 64,
data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(),
arch: arch.target_arch(),
arch,
options: TargetOptions {
features: "+neon,+fp-armv8,+apple-a12".into(),
max_atomic_width: Some(128),
frame_pointer: FramePointer::NonLeaf,
..base
supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::THREAD,
..opts
},
}
}
18 changes: 6 additions & 12 deletions compiler/rustc_target/src/spec/targets/aarch64_apple_ios_sim.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,10 @@
use crate::spec::base::apple::{ios_sim_llvm_target, opts, Arch, TargetAbi};
use crate::spec::base::apple::{base, Arch, TargetAbi};
use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions};

pub(crate) fn target() -> Target {
let arch = Arch::Arm64;
let mut base = opts("ios", arch, TargetAbi::Simulator);
base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD;

let (opts, llvm_target, arch) = base("ios", Arch::Arm64, TargetAbi::Simulator);
Target {
// Clang automatically chooses a more specific target based on
// IPHONEOS_DEPLOYMENT_TARGET.
// This is required for the simulator target to pick the right
// MACH-O commands, so we do too.
llvm_target: ios_sim_llvm_target(arch).into(),
llvm_target,
metadata: crate::spec::TargetMetadata {
description: Some("Apple iOS Simulator on ARM64".into()),
tier: Some(2),
@@ -20,12 +13,13 @@ pub(crate) fn target() -> Target {
},
pointer_width: 64,
data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(),
arch: arch.target_arch(),
arch,
options: TargetOptions {
features: "+neon,+fp-armv8,+apple-a7".into(),
max_atomic_width: Some(128),
frame_pointer: FramePointer::NonLeaf,
..base
supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::THREAD,
..opts
},
}
}
10 changes: 5 additions & 5 deletions compiler/rustc_target/src/spec/targets/aarch64_apple_tvos.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use crate::spec::base::apple::{opts, tvos_llvm_target, Arch, TargetAbi};
use crate::spec::base::apple::{base, Arch, TargetAbi};
use crate::spec::{FramePointer, Target, TargetOptions};

pub(crate) fn target() -> Target {
let arch = Arch::Arm64;
let (opts, llvm_target, arch) = base("tvos", Arch::Arm64, TargetAbi::Normal);
Target {
llvm_target: tvos_llvm_target(arch).into(),
llvm_target,
metadata: crate::spec::TargetMetadata {
description: Some("ARM64 tvOS".into()),
tier: Some(3),
@@ -13,12 +13,12 @@ pub(crate) fn target() -> Target {
},
pointer_width: 64,
data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(),
arch: arch.target_arch(),
arch,
options: TargetOptions {
features: "+neon,+fp-armv8,+apple-a7".into(),
max_atomic_width: Some(128),
frame_pointer: FramePointer::NonLeaf,
..opts("tvos", arch, TargetAbi::Normal)
..opts
},
}
}
10 changes: 5 additions & 5 deletions compiler/rustc_target/src/spec/targets/aarch64_apple_tvos_sim.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use crate::spec::base::apple::{opts, tvos_sim_llvm_target, Arch, TargetAbi};
use crate::spec::base::apple::{base, Arch, TargetAbi};
use crate::spec::{FramePointer, Target, TargetOptions};

pub(crate) fn target() -> Target {
let arch = Arch::Arm64;
let (opts, llvm_target, arch) = base("tvos", Arch::Arm64, TargetAbi::Simulator);
Target {
llvm_target: tvos_sim_llvm_target(arch).into(),
llvm_target,
metadata: crate::spec::TargetMetadata {
description: Some("ARM64 tvOS Simulator".into()),
tier: Some(3),
@@ -13,12 +13,12 @@ pub(crate) fn target() -> Target {
},
pointer_width: 64,
data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(),
arch: arch.target_arch(),
arch,
options: TargetOptions {
features: "+neon,+fp-armv8,+apple-a7".into(),
max_atomic_width: Some(128),
frame_pointer: FramePointer::NonLeaf,
..opts("tvos", arch, TargetAbi::Simulator)
..opts
},
}
}
14 changes: 6 additions & 8 deletions compiler/rustc_target/src/spec/targets/aarch64_apple_visionos.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
use crate::spec::base::apple::{opts, visionos_llvm_target, Arch, TargetAbi};
use crate::spec::base::apple::{base, Arch, TargetAbi};
use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions};

pub(crate) fn target() -> Target {
let arch = Arch::Arm64;
let mut base = opts("visionos", arch, TargetAbi::Normal);
base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD;

let (opts, llvm_target, arch) = base("visionos", Arch::Arm64, TargetAbi::Normal);
Target {
llvm_target: visionos_llvm_target(arch).into(),
llvm_target,
metadata: crate::spec::TargetMetadata {
description: Some("ARM64 Apple visionOS".into()),
tier: Some(3),
@@ -16,12 +13,13 @@ pub(crate) fn target() -> Target {
},
pointer_width: 64,
data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(),
arch: arch.target_arch(),
arch,
options: TargetOptions {
features: "+neon,+fp-armv8,+apple-a16".into(),
max_atomic_width: Some(128),
frame_pointer: FramePointer::NonLeaf,
..base
supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::THREAD,
..opts
},
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
use crate::spec::base::apple::{opts, visionos_sim_llvm_target, Arch, TargetAbi};
use crate::spec::base::apple::{base, Arch, TargetAbi};
use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions};

pub(crate) fn target() -> Target {
let arch = Arch::Arm64;
let mut base = opts("visionos", arch, TargetAbi::Simulator);
base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD;

let (opts, llvm_target, arch) = base("visionos", Arch::Arm64, TargetAbi::Simulator);
Target {
llvm_target: visionos_sim_llvm_target(arch).into(),
llvm_target,
metadata: crate::spec::TargetMetadata {
description: Some("ARM64 Apple visionOS simulator".into()),
tier: Some(3),
@@ -16,12 +13,13 @@ pub(crate) fn target() -> Target {
},
pointer_width: 64,
data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(),
arch: arch.target_arch(),
arch,
options: TargetOptions {
features: "+neon,+fp-armv8,+apple-a16".into(),
max_atomic_width: Some(128),
frame_pointer: FramePointer::NonLeaf,
..base
supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::THREAD,
..opts
},
}
}
10 changes: 5 additions & 5 deletions compiler/rustc_target/src/spec/targets/aarch64_apple_watchos.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use crate::spec::base::apple::{opts, Arch, TargetAbi};
use crate::spec::base::apple::{base, Arch, TargetAbi};
use crate::spec::{Target, TargetOptions};

pub(crate) fn target() -> Target {
let base = opts("watchos", Arch::Arm64, TargetAbi::Normal);
let (opts, llvm_target, arch) = base("watchos", Arch::Arm64, TargetAbi::Normal);
Target {
llvm_target: "aarch64-apple-watchos".into(),
llvm_target,
metadata: crate::spec::TargetMetadata {
description: Some("ARM64 Apple WatchOS".into()),
tier: Some(3),
@@ -13,13 +13,13 @@ pub(crate) fn target() -> Target {
},
pointer_width: 64,
data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(),
arch: "aarch64".into(),
arch,
options: TargetOptions {
features: "+v8a,+neon,+fp-armv8,+apple-a7".into(),
max_atomic_width: Some(128),
dynamic_linking: false,
position_independent_executables: true,
..base
..opts
},
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
use crate::spec::base::apple::{opts, watchos_sim_llvm_target, Arch, TargetAbi};
use crate::spec::base::apple::{base, Arch, TargetAbi};
use crate::spec::{FramePointer, Target, TargetOptions};

pub(crate) fn target() -> Target {
let arch = Arch::Arm64;
let (opts, llvm_target, arch) = base("watchos", Arch::Arm64, TargetAbi::Simulator);
Target {
// Clang automatically chooses a more specific target based on
// WATCHOS_DEPLOYMENT_TARGET.
// This is required for the simulator target to pick the right
// MACH-O commands, so we do too.
llvm_target: watchos_sim_llvm_target(arch).into(),
llvm_target,
metadata: crate::spec::TargetMetadata {
description: Some("ARM64 Apple WatchOS Simulator".into()),
tier: Some(3),
@@ -17,12 +13,12 @@ pub(crate) fn target() -> Target {
},
pointer_width: 64,
data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(),
arch: arch.target_arch(),
arch,
options: TargetOptions {
features: "+neon,+fp-armv8,+apple-a7".into(),
max_atomic_width: Some(128),
frame_pointer: FramePointer::NonLeaf,
..opts("watchos", arch, TargetAbi::Simulator)
..opts
},
}
}
11 changes: 5 additions & 6 deletions compiler/rustc_target/src/spec/targets/arm64_32_apple_watchos.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
use crate::spec::base::apple::{opts, watchos_llvm_target, Arch, TargetAbi};
use crate::spec::base::apple::{base, Arch, TargetAbi};
use crate::spec::{Target, TargetOptions};

pub(crate) fn target() -> Target {
let arch = Arch::Arm64_32;
let base = opts("watchos", arch, TargetAbi::Normal);
let (opts, llvm_target, arch) = base("watchos", Arch::Arm64_32, TargetAbi::Normal);
Target {
llvm_target: watchos_llvm_target(arch).into(),
llvm_target,
metadata: crate::spec::TargetMetadata {
description: Some("Arm Apple WatchOS 64-bit with 32-bit pointers".into()),
tier: Some(3),
@@ -14,13 +13,13 @@ pub(crate) fn target() -> Target {
},
pointer_width: 32,
data_layout: "e-m:o-p:32:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
arch: "aarch64".into(),
arch,
options: TargetOptions {
features: "+v8a,+neon,+fp-armv8,+apple-a7".into(),
max_atomic_width: Some(128),
dynamic_linking: false,
position_independent_executables: true,
..base
..opts
},
}
}
24 changes: 9 additions & 15 deletions compiler/rustc_target/src/spec/targets/arm64e_apple_darwin.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,10 @@
use crate::spec::base::apple::{macos_llvm_target, opts, Arch, TargetAbi};
use crate::spec::base::apple::{base, Arch, TargetAbi};
use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions};

pub(crate) fn target() -> Target {
let arch = Arch::Arm64e;
let mut base = opts("macos", arch, TargetAbi::Normal);
base.cpu = "apple-m1".into();
base.max_atomic_width = Some(128);

// FIXME: The leak sanitizer currently fails the tests, see #88132.
base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::THREAD;

let (opts, llvm_target, arch) = base("macos", Arch::Arm64e, TargetAbi::Normal);
Target {
// Clang automatically chooses a more specific target based on
// MACOSX_DEPLOYMENT_TARGET. To enable cross-language LTO to work
// correctly, we do too.
llvm_target: macos_llvm_target(arch).into(),
llvm_target,
metadata: crate::spec::TargetMetadata {
description: Some("ARM64e Apple Darwin".into()),
tier: Some(3),
@@ -23,11 +13,15 @@ pub(crate) fn target() -> Target {
},
pointer_width: 64,
data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(),
arch: arch.target_arch(),
arch,
options: TargetOptions {
mcount: "\u{1}mcount".into(),
frame_pointer: FramePointer::NonLeaf,
..base
cpu: "apple-m1".into(),
max_atomic_width: Some(128),
// FIXME: The leak sanitizer currently fails the tests, see #88132.
supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::THREAD,
..opts
},
}
}
18 changes: 6 additions & 12 deletions compiler/rustc_target/src/spec/targets/arm64e_apple_ios.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,10 @@
use crate::spec::base::apple::{ios_llvm_target, opts, Arch, TargetAbi};
use crate::spec::base::apple::{base, Arch, TargetAbi};
use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions};

pub(crate) fn target() -> Target {
let arch = Arch::Arm64e;
let mut base = opts("ios", arch, TargetAbi::Normal);
base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD;

let (opts, llvm_target, arch) = base("ios", Arch::Arm64e, TargetAbi::Normal);
Target {
// Clang automatically chooses a more specific target based on
// IPHONEOS_DEPLOYMENT_TARGET.
// This is required for the target to pick the right
// MACH-O commands, so we do too.
llvm_target: ios_llvm_target(arch).into(),
llvm_target,
metadata: crate::spec::TargetMetadata {
description: Some("ARM64e Apple iOS".into()),
tier: Some(3),
@@ -20,12 +13,13 @@ pub(crate) fn target() -> Target {
},
pointer_width: 64,
data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(),
arch: arch.target_arch(),
arch,
options: TargetOptions {
features: "+neon,+fp-armv8,+apple-a12,+v8.3a,+pauth".into(),
max_atomic_width: Some(128),
frame_pointer: FramePointer::NonLeaf,
..base
supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::THREAD,
..opts
},
}
}
10 changes: 5 additions & 5 deletions compiler/rustc_target/src/spec/targets/armv7k_apple_watchos.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use crate::spec::base::apple::{opts, Arch, TargetAbi};
use crate::spec::base::apple::{base, Arch, TargetAbi};
use crate::spec::{Target, TargetOptions};

pub(crate) fn target() -> Target {
let arch = Arch::Armv7k;
let (opts, llvm_target, arch) = base("watchos", Arch::Armv7k, TargetAbi::Normal);
Target {
llvm_target: "armv7k-apple-watchos".into(),
llvm_target,
metadata: crate::spec::TargetMetadata {
description: Some("Armv7-A Apple WatchOS".into()),
tier: Some(3),
@@ -13,13 +13,13 @@ pub(crate) fn target() -> Target {
},
pointer_width: 32,
data_layout: "e-m:o-p:32:32-Fi8-i64:64-a:0:32-n32-S128".into(),
arch: arch.target_arch(),
arch,
options: TargetOptions {
features: "+v7,+vfp4,+neon".into(),
max_atomic_width: Some(64),
dynamic_linking: false,
position_independent_executables: true,
..opts("watchos", arch, TargetAbi::Normal)
..opts
},
}
}
10 changes: 5 additions & 5 deletions compiler/rustc_target/src/spec/targets/armv7s_apple_ios.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use crate::spec::base::apple::{ios_llvm_target, opts, Arch, TargetAbi};
use crate::spec::base::apple::{base, Arch, TargetAbi};
use crate::spec::{Target, TargetOptions};

pub(crate) fn target() -> Target {
let arch = Arch::Armv7s;
let (opts, llvm_target, arch) = base("ios", Arch::Armv7s, TargetAbi::Normal);
Target {
llvm_target: ios_llvm_target(arch).into(),
llvm_target,
metadata: crate::spec::TargetMetadata {
description: Some("Armv7-A Apple-A6 Apple iOS".into()),
tier: Some(3),
@@ -13,11 +13,11 @@ pub(crate) fn target() -> Target {
},
pointer_width: 32,
data_layout: "e-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32".into(),
arch: arch.target_arch(),
arch,
options: TargetOptions {
features: "+v7,+vfp4,+neon".into(),
max_atomic_width: Some(64),
..opts("ios", arch, TargetAbi::Normal)
..opts
},
}
}
15 changes: 5 additions & 10 deletions compiler/rustc_target/src/spec/targets/i386_apple_ios.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
use crate::spec::base::apple::{ios_sim_llvm_target, opts, Arch, TargetAbi};
use crate::spec::base::apple::{base, Arch, TargetAbi};
use crate::spec::{Target, TargetOptions};

pub(crate) fn target() -> Target {
let arch = Arch::I386;
// i386-apple-ios is a simulator target, even though it isn't declared
// that way in the target name like the other ones...
let abi = TargetAbi::Simulator;
let (opts, llvm_target, arch) = base("ios", Arch::I386, TargetAbi::Simulator);
Target {
// Clang automatically chooses a more specific target based on
// IPHONEOS_DEPLOYMENT_TARGET.
// This is required for the target to pick the right
// MACH-O commands, so we do too.
llvm_target: ios_sim_llvm_target(arch).into(),
llvm_target,
metadata: crate::spec::TargetMetadata {
description: Some("32-bit x86 iOS".into()),
tier: Some(3),
@@ -22,7 +17,7 @@ pub(crate) fn target() -> Target {
data_layout: "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-\
i128:128-f64:32:64-f80:128-n8:16:32-S128"
.into(),
arch: arch.target_arch(),
options: TargetOptions { max_atomic_width: Some(64), ..opts("ios", arch, abi) },
arch,
options: TargetOptions { max_atomic_width: Some(64), ..opts },
}
}
26 changes: 11 additions & 15 deletions compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,12 @@
use crate::spec::base::apple::{macos_llvm_target, opts, Arch, TargetAbi};
use crate::spec::base::apple::{base, Arch, TargetAbi};
use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, Target, TargetOptions};

pub(crate) fn target() -> Target {
// ld64 only understands i386 and not i686
let arch = Arch::I386;
let mut base = opts("macos", arch, TargetAbi::Normal);
base.max_atomic_width = Some(64);
base.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m32"]);
base.frame_pointer = FramePointer::Always;
let (mut opts, llvm_target, arch) = base("macos", Arch::I686, TargetAbi::Normal);
opts.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m32"]);

Target {
// Clang automatically chooses a more specific target based on
// MACOSX_DEPLOYMENT_TARGET. To enable cross-language LTO to work
// correctly, we do too.
//
// While ld64 doesn't understand i686, LLVM does.
llvm_target: macos_llvm_target(Arch::I686).into(),
llvm_target,
metadata: crate::spec::TargetMetadata {
description: Some("32-bit macOS (10.12+, Sierra+)".into()),
tier: Some(3),
@@ -26,7 +17,12 @@ pub(crate) fn target() -> Target {
data_layout: "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-\
i128:128-f64:32:64-f80:128-n8:16:32-S128"
.into(),
arch: arch.target_arch(),
options: TargetOptions { mcount: "\u{1}mcount".into(), ..base },
arch,
options: TargetOptions {
mcount: "\u{1}mcount".into(),
max_atomic_width: Some(64),
frame_pointer: FramePointer::Always,
..opts
},
}
}
30 changes: 15 additions & 15 deletions compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,11 @@
use crate::spec::base::apple::{macos_llvm_target, opts, Arch, TargetAbi};
use crate::spec::base::apple::{base, Arch, TargetAbi};
use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, SanitizerSet, Target, TargetOptions};

pub(crate) fn target() -> Target {
let arch = Arch::X86_64;
let mut base = opts("macos", arch, TargetAbi::Normal);
base.max_atomic_width = Some(128); // penryn+ supports cmpxchg16b
base.frame_pointer = FramePointer::Always;
base.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m64"]);
base.supported_sanitizers =
SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::LEAK | SanitizerSet::THREAD;

let (mut opts, llvm_target, arch) = base("macos", Arch::X86_64, TargetAbi::Normal);
opts.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m64"]);
Target {
// Clang automatically chooses a more specific target based on
// MACOSX_DEPLOYMENT_TARGET. To enable cross-language LTO to work
// correctly, we do too.
llvm_target: macos_llvm_target(arch).into(),
llvm_target,
metadata: crate::spec::TargetMetadata {
description: Some("64-bit macOS (10.12+, Sierra+)".into()),
tier: Some(1),
@@ -24,7 +15,16 @@ pub(crate) fn target() -> Target {
pointer_width: 64,
data_layout:
"e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(),
arch: arch.target_arch(),
options: TargetOptions { mcount: "\u{1}mcount".into(), ..base },
arch,
options: TargetOptions {
mcount: "\u{1}mcount".into(),
max_atomic_width: Some(128), // penryn+ supports cmpxchg16b
frame_pointer: FramePointer::Always,
supported_sanitizers: SanitizerSet::ADDRESS
| SanitizerSet::CFI
| SanitizerSet::LEAK
| SanitizerSet::THREAD,
..opts
},
}
}
17 changes: 9 additions & 8 deletions compiler/rustc_target/src/spec/targets/x86_64_apple_ios.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
use crate::spec::base::apple::{ios_sim_llvm_target, opts, Arch, TargetAbi};
use crate::spec::base::apple::{base, Arch, TargetAbi};
use crate::spec::{SanitizerSet, Target, TargetOptions};

pub(crate) fn target() -> Target {
let arch = Arch::X86_64;
// x86_64-apple-ios is a simulator target, even though it isn't declared
// that way in the target name like the other ones...
let mut base = opts("ios", arch, TargetAbi::Simulator);
base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD;

let (opts, llvm_target, arch) = base("ios", Arch::X86_64, TargetAbi::Simulator);
Target {
llvm_target: ios_sim_llvm_target(arch).into(),
llvm_target,
metadata: crate::spec::TargetMetadata {
description: Some("64-bit x86 iOS".into()),
tier: Some(2),
@@ -19,7 +16,11 @@ pub(crate) fn target() -> Target {
pointer_width: 64,
data_layout:
"e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(),
arch: arch.target_arch(),
options: TargetOptions { max_atomic_width: Some(128), ..base },
arch,
options: TargetOptions {
max_atomic_width: Some(128),
supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::THREAD,
..opts
},
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
use crate::spec::base::apple::{mac_catalyst_llvm_target, opts, Arch, TargetAbi};
use crate::spec::base::apple::{base, Arch, TargetAbi};
use crate::spec::{SanitizerSet, Target, TargetOptions};

pub(crate) fn target() -> Target {
let arch = Arch::X86_64;
let mut base = opts("ios", arch, TargetAbi::MacCatalyst);
base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::THREAD;

let (opts, llvm_target, arch) = base("ios", Arch::X86_64, TargetAbi::MacCatalyst);
Target {
llvm_target: mac_catalyst_llvm_target(arch).into(),
llvm_target,
metadata: crate::spec::TargetMetadata {
description: Some("Apple Catalyst on x86_64".into()),
tier: Some(2),
@@ -17,7 +14,11 @@ pub(crate) fn target() -> Target {
pointer_width: 64,
data_layout:
"e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(),
arch: arch.target_arch(),
options: TargetOptions { max_atomic_width: Some(128), ..base },
arch,
options: TargetOptions {
max_atomic_width: Some(128),
supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::THREAD,
..opts
},
}
}
11 changes: 5 additions & 6 deletions compiler/rustc_target/src/spec/targets/x86_64_apple_tvos.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
use crate::spec::base::apple::{opts, tvos_sim_llvm_target, Arch, TargetAbi};
use crate::spec::base::apple::{base, Arch, TargetAbi};
use crate::spec::{Target, TargetOptions};

pub(crate) fn target() -> Target {
let arch = Arch::X86_64;
// x86_64-apple-tvos is a simulator target, even though it isn't declared
// that way in the target name like the other ones...
let abi = TargetAbi::Simulator;
let (opts, llvm_target, arch) = base("tvos", Arch::X86_64, TargetAbi::Simulator);
Target {
llvm_target: tvos_sim_llvm_target(arch).into(),
llvm_target,
metadata: crate::spec::TargetMetadata {
description: Some("x86 64-bit tvOS".into()),
tier: Some(3),
@@ -17,7 +16,7 @@ pub(crate) fn target() -> Target {
pointer_width: 64,
data_layout:
"e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(),
arch: arch.target_arch(),
options: TargetOptions { max_atomic_width: Some(128), ..opts("tvos", arch, abi) },
arch,
options: TargetOptions { max_atomic_width: Some(128), ..opts },
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use crate::spec::base::apple::{opts, watchos_sim_llvm_target, Arch, TargetAbi};
use crate::spec::base::apple::{base, Arch, TargetAbi};
use crate::spec::{Target, TargetOptions};

pub(crate) fn target() -> Target {
let arch = Arch::X86_64;
let (opts, llvm_target, arch) = base("watchos", Arch::X86_64, TargetAbi::Simulator);
Target {
llvm_target: watchos_sim_llvm_target(arch).into(),
llvm_target,
metadata: crate::spec::TargetMetadata {
description: Some("x86 64-bit Apple WatchOS simulator".into()),
tier: Some(3),
@@ -14,10 +14,7 @@ pub(crate) fn target() -> Target {
pointer_width: 64,
data_layout:
"e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(),
arch: arch.target_arch(),
options: TargetOptions {
max_atomic_width: Some(128),
..opts("watchos", arch, TargetAbi::Simulator)
},
arch,
options: TargetOptions { max_atomic_width: Some(128), ..opts },
}
}
26 changes: 11 additions & 15 deletions compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
use crate::spec::base::apple::{macos_llvm_target, opts, Arch, TargetAbi};
use crate::spec::base::apple::{base, Arch, TargetAbi};
use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, SanitizerSet, Target, TargetOptions};

pub(crate) fn target() -> Target {
let arch = Arch::X86_64h;
let mut base = opts("macos", arch, TargetAbi::Normal);
base.max_atomic_width = Some(128);
base.frame_pointer = FramePointer::Always;
base.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m64"]);
base.supported_sanitizers =
let (mut opts, llvm_target, arch) = base("macos", Arch::X86_64h, TargetAbi::Normal);
opts.max_atomic_width = Some(128);
opts.frame_pointer = FramePointer::Always;
opts.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m64"]);
opts.supported_sanitizers =
SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::LEAK | SanitizerSet::THREAD;

// x86_64h is core2-avx without a few of the features which would otherwise
@@ -20,19 +19,16 @@ pub(crate) fn target() -> Target {
// It would be nice if this were not the case, but fixing it seems tricky
// (and given that the main use-case for this target is for use in universal
// binaries, probably not that important).
base.features = "-rdrnd,-aes,-pclmul,-rtm,-fsgsbase".into();
opts.features = "-rdrnd,-aes,-pclmul,-rtm,-fsgsbase".into();
// Double-check that the `cpu` is what we expect (if it's not the list above
// may need updating).
assert_eq!(
base.cpu, "core-avx2",
opts.cpu, "core-avx2",
"you need to adjust the feature list in x86_64h-apple-darwin if you change this",
);

Target {
// Clang automatically chooses a more specific target based on
// MACOSX_DEPLOYMENT_TARGET. To enable cross-language LTO to work
// correctly, we do too.
llvm_target: macos_llvm_target(arch).into(),
llvm_target,
metadata: crate::spec::TargetMetadata {
description: Some("macOS with late-gen Intel (at least Haswell)".into()),
tier: Some(3),
@@ -42,7 +38,7 @@ pub(crate) fn target() -> Target {
pointer_width: 64,
data_layout:
"e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(),
arch: arch.target_arch(),
options: TargetOptions { mcount: "\u{1}mcount".into(), ..base },
arch,
options: TargetOptions { mcount: "\u{1}mcount".into(), ..opts },
}
}