Skip to content

Commit

Permalink
Auto merge of rust-lang#121430 - madsmtm:mac-catalyst-iOSSupport, r=w…
Browse files Browse the repository at this point in the history
…esleywiser

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).
  • Loading branch information
bors committed Apr 12, 2024
2 parents 7942405 + ff3f0a3 commit 9782770
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 0 deletions.
10 changes: 10 additions & 0 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<'_>> {
Expand Down
7 changes: 7 additions & 0 deletions src/tools/compiletest/src/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand All @@ -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",
Expand Down
25 changes: 25 additions & 0 deletions tests/ui/linkage-attr/uikit-framework.rs
Original file line number Diff line number Diff line change
@@ -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());
}
}

0 comments on commit 9782770

Please sign in to comment.