[lld/mac] For catalyst outputs, tolerate implicitly linking against arm64e mac tbd files (#193065)

Some mac libraries published in the Xcode SDK are now arm64e only, and
catalyst applications should be able to link against these even if
building for arm64.

This matches ld-prime behavior.

https://reviews.llvm.org/D124336 allows linking against MacOS libraries,
but only if the architecture matches exactly.
https://reviews.llvm.org/D130683 allows linking against tbds with ABI
compatibility architectures, but the logic isn't used for this
particular case.

[Assisted-by](https://t.ly/Dkjjk): [Claude Opus
4.6](https://www.anthropic.com/news/claude-opus-4-6)

---------

Co-authored-by: Nuri Amari <nuriamari@fb.com>
This commit is contained in:
Nuri Amari
2026-04-21 14:07:29 -04:00
committed by GitHub
parent d794e04651
commit bddd3d32bc
2 changed files with 62 additions and 9 deletions

View File

@@ -1858,15 +1858,6 @@ constexpr std::array<StringRef, 3> skipPlatformChecks{
"/usr/lib/system/libsystem_platform.dylib",
"/usr/lib/system/libsystem_pthread.dylib"};
static bool skipPlatformCheckForCatalyst(const InterfaceFile &interface,
bool explicitlyLinked) {
// Catalyst outputs can link against implicitly linked macOS-only libraries.
if (config->platform() != PLATFORM_MACCATALYST || explicitlyLinked)
return false;
return is_contained(interface.targets(),
MachO::Target(config->arch(), PLATFORM_MACOS));
}
static bool isArchABICompatible(ArchitectureSet archSet,
Architecture targetArch) {
uint32_t cpuType;
@@ -1879,6 +1870,18 @@ static bool isArchABICompatible(ArchitectureSet archSet,
});
}
static bool skipPlatformCheckForCatalyst(const InterfaceFile &interface,
bool explicitlyLinked) {
// Catalyst outputs can link against implicitly linked macOS-only libraries.
if (config->platform() != PLATFORM_MACCATALYST || explicitlyLinked)
return false;
ArchitectureSet macOSArchs;
for (const auto &target : interface.targets())
if (target.Platform == PLATFORM_MACOS)
macOSArchs.set(target.Arch);
return isArchABICompatible(macOSArchs, config->arch());
}
static bool isTargetPlatformArchCompatible(
InterfaceFile::const_target_range interfaceTargets, Target target) {
if (is_contained(interfaceTargets, target))

View File

@@ -0,0 +1,50 @@
# REQUIRES: aarch64
## When linking a macCatalyst arm64 output, lld should tolerate implicitly
## linked re-exported dylibs that only declare arm64e-macos targets, even if targeting arm64.
# arm64 and arm64e are ABI compatible (same CPU type), and ld64 accepts this.
# RUN: rm -rf %t; split-file --no-leading-lines %s %t
# RUN: llvm-mc -filetype=obj -triple=arm64-apple-ios13.15.0-macabi -o %t/test.o /dev/null
# RUN: %no-arg-lld -syslibroot %t/sdk -lSystem -dylib -arch arm64 \
# RUN: -platform_version mac-catalyst 13.15.0 14.0 %t/test.o -o /dev/null
## Explicitly linking an arm64e-macos-only library should still be an error.
# RUN: not %no-arg-lld -syslibroot %t/sdk -lSystem -dylib -arch arm64 \
# RUN: -platform_version mac-catalyst 13.15.0 14.0 %t/test.o -o /dev/null \
# RUN: -L %t/explicit -larm64e_only 2>&1 | FileCheck %s
# CHECK: libarm64e_only.dylib) is incompatible with arm64 (macCatalyst13.15.0)
#--- sdk/usr/lib/libSystem.tbd
--- !tapi-tbd
tbd-version: 4
targets: [ arm64-macos, arm64-maccatalyst ]
install-name: '/usr/lib/libSystem.dylib'
current-version: 0001.001.1
reexported-libraries:
- targets: [ arm64-macos, arm64-maccatalyst ]
libraries: [ '/usr/lib/system/libsystem_eligibility.dylib' ]
--- !tapi-tbd
tbd-version: 4
targets: [ x86_64-macos, arm64e-macos ]
install-name: '/usr/lib/system/libsystem_eligibility.dylib'
current-version: 0001.001.1
parent-umbrella:
- targets: [ x86_64-macos, arm64e-macos ]
umbrella: System
exports:
- targets: [ x86_64-macos, arm64e-macos ]
symbols: [ _os_eligibility_get_domain_answer ]
...
#--- explicit/libarm64e_only.tbd
--- !tapi-tbd
tbd-version: 4
targets: [ x86_64-macos, arm64e-macos ]
install-name: '/usr/lib/libarm64e_only.dylib'
current-version: 0001.001.1
exports:
- targets: [ x86_64-macos, arm64e-macos ]
symbols: [ _arm64e_only_func ]
...