Skip to content

Commit 9afe713

Browse files
committed
Auto merge of rust-lang#129341 - madsmtm:refactor-deployment-target, r=petrochenkov
Apple: Refactor deployment target version parsing Refactor deployment target parsing to make it easier to do rust-lang#129342 (I wanted to make sure of all the places that `std::env::var` is called). Specifically, my goal was to minimize the amount of target-specific configuration, so to that end I renamed the `opts` function that generates the `TargetOptions` to `base`, and made it return the LLVM target and `target_arch` too. In the future, I would like to move even more out of the target files and into `spec::apple`, as it makes it easier for me to maintain. For example, this fixed a bug in `aarch64-apple-watchos`, which wasn't passing the deployment target as part of the LLVM triple. This (probably) fixes rust-lang#123582 and fixes rust-lang#107630. We also now parse the patch version of deployment targets, allowing the user to specify e.g. `MACOSX_DEPLOYMENT_TARGET=10.12.6`. Finally, this fixes the LLVM target name for visionOS, it should be `*-apple-xros` and not `*-apple-visionos`. Since I have changed all the Apple targets here, I smoke-tested my changes by running the following: ```console # Build each target ./x build library --target="aarch64-apple-darwin,aarch64-apple-ios,aarch64-apple-ios-macabi,aarch64-apple-ios-sim,aarch64-apple-tvos,aarch64-apple-tvos-sim,aarch64-apple-visionos,aarch64-apple-visionos-sim,aarch64-apple-watchos,aarch64-apple-watchos-sim,arm64_32-apple-watchos,arm64e-apple-ios,armv7k-apple-watchos,armv7s-apple-ios,i386-apple-ios,x86_64-apple-darwin,x86_64-apple-ios,x86_64-apple-ios-macabi,x86_64-apple-tvos,x86_64-apple-watchos-sim,x86_64h-apple-darwin" # Test that we can still at least link basic projects cargo new foobar && cd foobar && cargo +stage1 build --target=aarch64-apple-darwin --target=aarch64-apple-ios --target=aarch64-apple-ios-macabi --target=aarch64-apple-ios-sim --target=aarch64-apple-tvos --target=aarch64-apple-tvos-sim --target=aarch64-apple-visionos --target=aarch64-apple-visionos-sim --target=aarch64-apple-watchos --target=aarch64-apple-watchos-sim --target=arm64_32-apple-watchos --target=armv7s-apple-ios --target=i386-apple-ios --target=x86_64-apple-darwin --target=x86_64-apple-ios --target=x86_64-apple-ios-macabi --target=x86_64-apple-tvos --target=x86_64-apple-watchos-sim --target=x86_64h-apple-darwin ``` I couldn't build for the `arm64e-apple-darwin` target, the `armv7k-apple-watchos` and `arm64e-apple-ios` targets failed to link, and I know that the `i686-apple-darwin` target requires a bit of setup, but all of this is as it was before this PR. r? thomcc CC `@BlackHoleFox` I would recommend using `rollup=never` when merging this, in case we need to bisect this later.
2 parents 26b5599 + bd56857 commit 9afe713

28 files changed

+381
-374
lines changed

Diff for: compiler/rustc_codegen_ssa/src/back/metadata.rs

+24-9
Original file line numberDiff line numberDiff line change
@@ -372,27 +372,42 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
372372
Some(file)
373373
}
374374

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

385401
let platform =
386402
rustc_target::spec::current_apple_platform(target).expect("unknown Apple target OS");
387-
let min_os = rustc_target::spec::current_apple_deployment_target(target)
388-
.expect("unknown Apple target OS");
389-
let sdk =
403+
let min_os = rustc_target::spec::current_apple_deployment_target(target);
404+
let (sdk_major, sdk_minor) =
390405
rustc_target::spec::current_apple_sdk_version(platform).expect("unknown Apple target OS");
391406

392407
let mut build_version = object::write::MachOBuildVersion::default();
393408
build_version.platform = platform;
394409
build_version.minos = pack_version(min_os);
395-
build_version.sdk = pack_version(sdk);
410+
build_version.sdk = pack_version((sdk_major, sdk_minor, 0));
396411
build_version
397412
}
398413

Diff for: compiler/rustc_driver_impl/src/lib.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -862,9 +862,9 @@ fn print_crate_info(
862862
use rustc_target::spec::current_apple_deployment_target;
863863

864864
if sess.target.is_like_osx {
865-
let (major, minor) = current_apple_deployment_target(&sess.target)
866-
.expect("unknown Apple target OS");
867-
println_info!("deployment_target={}", format!("{major}.{minor}"))
865+
let (major, minor, patch) = current_apple_deployment_target(&sess.target);
866+
let patch = if patch != 0 { format!(".{patch}") } else { String::new() };
867+
println_info!("deployment_target={major}.{minor}{patch}")
868868
} else {
869869
#[allow(rustc::diagnostic_outside_of_impl)]
870870
sess.dcx().fatal("only Apple targets currently support deployment version info")

0 commit comments

Comments
 (0)