Auto merge of #121430 - madsmtm:mac-catalyst-iOSSupport, r=wesleywiser

Add `/System/iOSSupport` to the library search path on Mac Catalyst

On macOS, `/System/iOSSupport` contains iOS frameworks like UIKit, which is the whole idea of Mac Catalyst.

To link to these, we need to explicitly tell the linker about the support library stubs provided in the macOS SDK under the same path.

Concretely, when building a binary for Mac Catalyst, Xcode passes the following flags to the linker:
```
-iframework /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.2.sdk/System/iOSSupport/System/Library/Frameworks
-L/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.2.sdk/System/iOSSupport/usr/lib
```

This is not something that can be disabled (it's enabled as soon as you enable `SUPPORTS_MACCATALYST`), so I think it's pretty safe to say that we don't need an option to turn these off.

I've chosen to slightly deviate from what Xcode does and use `-F` instead of `-iframework`, since we don't need to change the header search path, and this way the flags nicely match on all the linkers. From what I could tell by reading Clang sources, there shouldn't be a difference when just running the linker.

CC `@BlackHoleFox,` `@shepmaster` (I accidentally let rustbot choose the reviewer).
This commit is contained in:
bors 2024-04-12 22:27:33 +00:00
commit 9782770a81
3 changed files with 42 additions and 0 deletions

View File

@ -3000,6 +3000,16 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
}
_ => unreachable!(),
}
if llvm_target.contains("macabi") {
// Mac Catalyst uses the macOS SDK, but to link to iOS-specific
// frameworks, we must have the support library stubs in the library
// search path.
// The flags are called `-L` and `-F` both in Clang, ld64 and ldd.
cmd.arg(format!("-L{sdk_root}/System/iOSSupport/usr/lib"));
cmd.arg(format!("-F{sdk_root}/System/iOSSupport/System/Library/Frameworks"));
}
}
fn get_apple_sdk_root(sdk_name: &str) -> Result<String, errors::AppleSdkRootError<'_>> {

View File

@ -790,15 +790,18 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
"ignore-thumb",
"ignore-thumbv8m.base-none-eabi",
"ignore-thumbv8m.main-none-eabi",
"ignore-tvos",
"ignore-unix",
"ignore-unknown",
"ignore-uwp",
"ignore-visionos",
"ignore-vxworks",
"ignore-wasi",
"ignore-wasm",
"ignore-wasm32",
"ignore-wasm32-bare",
"ignore-wasm64",
"ignore-watchos",
"ignore-windows",
"ignore-windows-gnu",
"ignore-x32",
@ -856,6 +859,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
"only-cdb",
"only-gnu",
"only-i686-pc-windows-msvc",
"only-ios",
"only-linux",
"only-loongarch64",
"only-loongarch64-unknown-linux-gnu",
@ -871,10 +875,13 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
"only-sparc64",
"only-stable",
"only-thumb",
"only-tvos",
"only-unix",
"only-visionos",
"only-wasm32",
"only-wasm32-bare",
"only-wasm32-wasip1",
"only-watchos",
"only-windows",
"only-x86",
"only-x86_64",

View File

@ -0,0 +1,25 @@
//! Check that linking to UIKit on platforms where that is available works.
//@ revisions: ios tvos watchos visionos
//@ [ios]only-ios
//@ [tvos]only-tvos
//@ [watchos]only-watchos
//@ [visionos]only-visionos
//@ build-pass
use std::ffi::{c_char, c_int, c_void};
#[link(name = "UIKit", kind = "framework")]
extern "C" {
pub fn UIApplicationMain(
argc: c_int,
argv: *const c_char,
principalClassName: *const c_void,
delegateClassName: *const c_void,
) -> c_int;
}
pub fn main() {
unsafe {
UIApplicationMain(0, core::ptr::null(), core::ptr::null(), core::ptr::null());
}
}