1
Fork 0

Always add LC_BUILD_VERSION for metadata object files

As of Xcode 15 Apple's linker has become a bit more strict about the
warnings it produces. One of those new warnings requires all valid
Mach-O object files in an archive to have a LC_BUILD_VERSION load
command:

```
ld: warning: no platform load command found in 'ARCHIVE[arm64][2106](lib.rmeta)', assuming: iOS-simulator
```

This was already being done for Mac Catalyst so this change expands this
logic to include it for all Apple platforms. I filed this behavior
change as FB12546320 and was told it was the new intentional behavior.
This commit is contained in:
Keith Smiley 2023-07-26 20:18:03 -07:00
parent fe5f591257
commit d37fdc95d4
No known key found for this signature in database
GPG key ID: 33BA60D44C7167F8
4 changed files with 71 additions and 25 deletions

View file

@ -179,20 +179,66 @@ pub fn opts(os: &'static str, arch: Arch) -> TargetOptions {
}
}
pub fn deployment_target(target: &Target) -> Option<String> {
pub fn sdk_version(platform: u32) -> Option<(u32, u32)> {
match platform {
object::macho::PLATFORM_MACOS => Some((13, 1)),
object::macho::PLATFORM_IOS
| object::macho::PLATFORM_IOSSIMULATOR
| object::macho::PLATFORM_TVOS
| object::macho::PLATFORM_TVOSSIMULATOR
| object::macho::PLATFORM_MACCATALYST => Some((16, 2)),
object::macho::PLATFORM_WATCHOS | object::macho::PLATFORM_WATCHOSSIMULATOR => Some((9, 1)),
_ => None,
}
}
pub fn platform(target: &Target) -> Option<u32> {
Some(match &*target.os {
"macos" => object::macho::PLATFORM_MACOS,
"ios" => {
if target.llvm_target.ends_with("-macabi") {
object::macho::PLATFORM_MACCATALYST
} else if target.llvm_target.ends_with("-simulator") {
object::macho::PLATFORM_IOSSIMULATOR
} else {
object::macho::PLATFORM_IOS
}
}
"watchos" => {
if target.llvm_target.ends_with("-simulator") {
object::macho::PLATFORM_WATCHOSSIMULATOR
} else {
object::macho::PLATFORM_WATCHOS
}
}
"tvos" => {
if target.llvm_target.ends_with("-simulator") {
object::macho::PLATFORM_TVOSSIMULATOR
} else {
object::macho::PLATFORM_TVOS
}
}
_ => return None,
})
}
pub fn deployment_target(target: &Target) -> Option<(u32, u32)> {
let (major, minor) = match &*target.os {
"macos" => {
// This does not need to be specific. It just needs to handle x86 vs M1.
let arch = if target.arch == "x86" || target.arch == "x86_64" { X86_64 } else { Arm64 };
macos_deployment_target(arch)
}
"ios" => ios_deployment_target(),
"ios" => match &*target.options.abi {
"macabi" => mac_catalyst_deployment_target(),
_ => ios_deployment_target(),
},
"watchos" => watchos_deployment_target(),
"tvos" => tvos_deployment_target(),
_ => return None,
};
Some(format!("{major}.{minor}"))
Some((major, minor))
}
fn from_set_deployment_target(var_name: &str) -> Option<(u32, u32)> {
@ -274,6 +320,11 @@ fn ios_deployment_target() -> (u32, u32) {
from_set_deployment_target("IPHONEOS_DEPLOYMENT_TARGET").unwrap_or((7, 0))
}
fn mac_catalyst_deployment_target() -> (u32, u32) {
// If you are looking for the default deployment target, prefer `rustc --print deployment-target`.
from_set_deployment_target("IPHONEOS_DEPLOYMENT_TARGET").unwrap_or((14, 0))
}
pub fn ios_llvm_target(arch: Arch) -> String {
// Modern iOS tooling extracts information about deployment target
// from LC_BUILD_VERSION. This load command will only be emitted when

View file

@ -61,6 +61,8 @@ mod aix_base;
mod android_base;
mod apple_base;
pub use apple_base::deployment_target as current_apple_deployment_target;
pub use apple_base::platform as current_apple_platform;
pub use apple_base::sdk_version as current_apple_sdk_version;
mod avr_gnu_base;
pub use avr_gnu_base::ef_avr_arch;
mod bpf_base;