[lld] 3254f46 - [lld/mac] For catalyst outputs, tolerate implicitly linking against mac-only tbd files
Nico Weber via llvm-commits
llvm-commits at lists.llvm.org
Sat Apr 23 18:43:56 PDT 2022
Author: Nico Weber
Date: 2022-04-23T21:43:46-04:00
New Revision: 3254f46884d3ec2d6112ab49ba3c470906699cda
URL: https://github.com/llvm/llvm-project/commit/3254f46884d3ec2d6112ab49ba3c470906699cda
DIFF: https://github.com/llvm/llvm-project/commit/3254f46884d3ec2d6112ab49ba3c470906699cda.diff
LOG: [lld/mac] For catalyst outputs, tolerate implicitly linking against mac-only tbd files
Before this,
clang empty.cc -target x86_64-apple-ios13.1-macabi \
-framework CoreServices -fuse-ld=lld
would error out with
ld64.lld: error: path/to/MacOSX.sdk/System/Library/Frameworks/
CoreServices.framework/Versions/A/Frameworks/CarbonCore.framework/
Versions/A/CarbonCore.tbd(
/System/Library/Frameworks/
CoreServices.framework/Versions/A/Frameworks/CarbonCore.framework/
Versions/A/CarbonCore) is incompatible with x86_64 (macCatalyst)
Now it works, like with ld64.
Differential Revision: https://reviews.llvm.org/D124336
Added:
lld/test/MachO/Inputs/MacOSX.sdk/System/Library/Frameworks/MacOnly-Indirect.framework/MacOnly-Indirect.tbd
lld/test/MachO/Inputs/MacOSX.sdk/System/Library/Frameworks/MacOnly.framework/MacOnly.tbd
Modified:
lld/MachO/Driver.cpp
lld/MachO/Driver.h
lld/MachO/DriverUtils.cpp
lld/MachO/InputFiles.cpp
lld/MachO/InputFiles.h
lld/test/MachO/zippered.yaml
Removed:
################################################################################
diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp
index 23f9f1f1459d2..5b95278a991c3 100644
--- a/lld/MachO/Driver.cpp
+++ b/lld/MachO/Driver.cpp
@@ -327,11 +327,9 @@ static InputFile *addFile(StringRef path, ForceLoad forceLoadArchive,
case file_magic::macho_dynamically_linked_shared_lib:
case file_magic::macho_dynamically_linked_shared_lib_stub:
case file_magic::tapi_file:
- if (DylibFile *dylibFile = loadDylib(mbref)) {
- if (isExplicit)
- dylibFile->explicitlyLinked = true;
+ if (DylibFile *dylibFile =
+ loadDylib(mbref, nullptr, /*isBundleLoader=*/false, isExplicit))
newFile = dylibFile;
- }
break;
case file_magic::bitcode:
newFile = make<BitcodeFile>(mbref, "", 0, isLazy);
diff --git a/lld/MachO/Driver.h b/lld/MachO/Driver.h
index dbfc05a0497cf..355816272f87d 100644
--- a/lld/MachO/Driver.h
+++ b/lld/MachO/Driver.h
@@ -49,7 +49,8 @@ std::string createResponseFile(const llvm::opt::InputArgList &args);
llvm::Optional<StringRef> resolveDylibPath(llvm::StringRef path);
DylibFile *loadDylib(llvm::MemoryBufferRef mbref, DylibFile *umbrella = nullptr,
- bool isBundleLoader = false);
+ bool isBundleLoader = false,
+ bool explicitlyLinked = false);
void resetLoadedDylibs();
// Search for all possible combinations of `{root}/{name}.{extension}`.
diff --git a/lld/MachO/DriverUtils.cpp b/lld/MachO/DriverUtils.cpp
index 83940b54486ff..95a1183b71d94 100644
--- a/lld/MachO/DriverUtils.cpp
+++ b/lld/MachO/DriverUtils.cpp
@@ -204,11 +204,14 @@ Optional<StringRef> macho::resolveDylibPath(StringRef dylibPath) {
static DenseMap<CachedHashStringRef, DylibFile *> loadedDylibs;
DylibFile *macho::loadDylib(MemoryBufferRef mbref, DylibFile *umbrella,
- bool isBundleLoader) {
+ bool isBundleLoader, bool explicitlyLinked) {
CachedHashStringRef path(mbref.getBufferIdentifier());
DylibFile *&file = loadedDylibs[path];
- if (file)
+ if (file) {
+ if (explicitlyLinked)
+ file->explicitlyLinked = explicitlyLinked;
return file;
+ }
DylibFile *newFile;
file_magic magic = identify_magic(mbref.getBuffer());
@@ -219,7 +222,8 @@ DylibFile *macho::loadDylib(MemoryBufferRef mbref, DylibFile *umbrella,
": " + toString(result.takeError()));
return nullptr;
}
- file = make<DylibFile>(**result, umbrella, isBundleLoader);
+ file =
+ make<DylibFile>(**result, umbrella, isBundleLoader, explicitlyLinked);
// parseReexports() can recursively call loadDylib(). That's fine since
// we wrote the DylibFile we just loaded to the loadDylib cache via the
@@ -234,7 +238,7 @@ DylibFile *macho::loadDylib(MemoryBufferRef mbref, DylibFile *umbrella,
magic == file_magic::macho_dynamically_linked_shared_lib_stub ||
magic == file_magic::macho_executable ||
magic == file_magic::macho_bundle);
- file = make<DylibFile>(mbref, umbrella, isBundleLoader);
+ file = make<DylibFile>(mbref, umbrella, isBundleLoader, explicitlyLinked);
// parseLoadCommands() can also recursively call loadDylib(). See comment
// in previous block for why this means we must copy `file` here.
diff --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp
index c57ce60a7898f..0798abf28fe86 100644
--- a/lld/MachO/InputFiles.cpp
+++ b/lld/MachO/InputFiles.cpp
@@ -1134,7 +1134,8 @@ static DylibFile *findDylib(StringRef path, DylibFile *umbrella,
make_pointee_range(currentTopLevelTapi->documents())) {
assert(child.documents().empty());
if (path == child.getInstallName()) {
- auto file = make<DylibFile>(child, umbrella);
+ auto file = make<DylibFile>(child, umbrella, /*isBundleLoader=*/false,
+ /*explicitlyLinked=*/false);
file->parseReexports(child);
return file;
}
@@ -1175,9 +1176,9 @@ static void loadReexport(StringRef path, DylibFile *umbrella,
}
DylibFile::DylibFile(MemoryBufferRef mb, DylibFile *umbrella,
- bool isBundleLoader)
+ bool isBundleLoader, bool explicitlyLinked)
: InputFile(DylibKind, mb), refState(RefState::Unreferenced),
- isBundleLoader(isBundleLoader) {
+ explicitlyLinked(explicitlyLinked), isBundleLoader(isBundleLoader) {
assert(!isBundleLoader || !umbrella);
if (umbrella == nullptr)
umbrella = this;
@@ -1286,7 +1287,7 @@ void DylibFile::parseLoadCommands(MemoryBufferRef mb) {
}
}
-// Some versions of XCode ship with .tbd files that don't have the right
+// Some versions of Xcode ship with .tbd files that don't have the right
// platform settings.
constexpr std::array<StringRef, 4> skipPlatformChecks{
"/usr/lib/system/libsystem_kernel.dylib",
@@ -1294,10 +1295,19 @@ constexpr std::array<StringRef, 4> skipPlatformChecks{
"/usr/lib/system/libsystem_pthread.dylib",
"/usr/lib/system/libcompiler_rt.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));
+}
+
DylibFile::DylibFile(const InterfaceFile &interface, DylibFile *umbrella,
- bool isBundleLoader)
+ bool isBundleLoader, bool explicitlyLinked)
: InputFile(DylibKind, interface), refState(RefState::Unreferenced),
- isBundleLoader(isBundleLoader) {
+ explicitlyLinked(explicitlyLinked), isBundleLoader(isBundleLoader) {
// FIXME: Add test for the missing TBD code path.
if (umbrella == nullptr)
@@ -1313,7 +1323,8 @@ DylibFile::DylibFile(const InterfaceFile &interface, DylibFile *umbrella,
inputFiles.insert(this);
if (!is_contained(skipPlatformChecks, installName) &&
- !is_contained(interface.targets(), config->platformInfo.target)) {
+ !is_contained(interface.targets(), config->platformInfo.target) &&
+ !skipPlatformCheckForCatalyst(interface, explicitlyLinked)) {
error(toString(this) + " is incompatible with " +
std::string(config->platformInfo.target));
return;
diff --git a/lld/MachO/InputFiles.h b/lld/MachO/InputFiles.h
index 725f02af7b9a5..ca9943605a99b 100644
--- a/lld/MachO/InputFiles.h
+++ b/lld/MachO/InputFiles.h
@@ -184,10 +184,10 @@ class DylibFile final : public InputFile {
// to the root. On the other hand, if a dylib is being directly loaded
// (through an -lfoo flag), then `umbrella` should be a nullptr.
explicit DylibFile(MemoryBufferRef mb, DylibFile *umbrella,
- bool isBundleLoader = false);
+ bool isBundleLoader, bool explicitlyLinked);
explicit DylibFile(const llvm::MachO::InterfaceFile &interface,
- DylibFile *umbrella = nullptr,
- bool isBundleLoader = false);
+ DylibFile *umbrella, bool isBundleLoader,
+ bool explicitlyLinked);
void parseLoadCommands(MemoryBufferRef mb);
void parseReexports(const llvm::MachO::InterfaceFile &interface);
diff --git a/lld/test/MachO/Inputs/MacOSX.sdk/System/Library/Frameworks/MacOnly-Indirect.framework/MacOnly-Indirect.tbd b/lld/test/MachO/Inputs/MacOSX.sdk/System/Library/Frameworks/MacOnly-Indirect.framework/MacOnly-Indirect.tbd
new file mode 100644
index 0000000000000..a7f0322b0fd56
--- /dev/null
+++ b/lld/test/MachO/Inputs/MacOSX.sdk/System/Library/Frameworks/MacOnly-Indirect.framework/MacOnly-Indirect.tbd
@@ -0,0 +1,22 @@
+--- !tapi-tbd
+tbd-version: 4
+targets: [ x86_64-macos, x86_64-maccatalyst ]
+uuids:
+ - target: x86_64-maccatalyst
+ value: 00000000-0000-0000-0000-000000000000
+ - target: x86_64-macos
+ value: 00000000-0000-0000-0000-000000000000
+install-name: 'MacOnly-Indirect.dylib'
+current-version: 0001.001.1
+reexported-libraries:
+ - targets: [ x86_64-macos, x86_64-maccatalyst ]
+ libraries: [ 'MacOnly-reexport.dylib' ]
+--- !tapi-tbd
+tbd-version: 4
+targets: [ x86_64-macos ]
+uuids:
+ - target: x86_64-macos
+ value: 00000000-0000-0000-0000-000000000000
+install-name: 'MacOnly-reexport.dylib'
+current-version: 0001.001.1
+...
diff --git a/lld/test/MachO/Inputs/MacOSX.sdk/System/Library/Frameworks/MacOnly.framework/MacOnly.tbd b/lld/test/MachO/Inputs/MacOSX.sdk/System/Library/Frameworks/MacOnly.framework/MacOnly.tbd
new file mode 100644
index 0000000000000..cd9c7da82b4f3
--- /dev/null
+++ b/lld/test/MachO/Inputs/MacOSX.sdk/System/Library/Frameworks/MacOnly.framework/MacOnly.tbd
@@ -0,0 +1,9 @@
+--- !tapi-tbd
+tbd-version: 4
+targets: [ x86_64-macos ]
+uuids:
+ - target: x86_64-macos
+ value: 00000000-0000-0000-0000-000000000000
+install-name: 'MacOnly.dylib'
+current-version: 0001.001.1
+...
diff --git a/lld/test/MachO/zippered.yaml b/lld/test/MachO/zippered.yaml
index bc289669e8d0b..1972be4454a47 100644
--- a/lld/test/MachO/zippered.yaml
+++ b/lld/test/MachO/zippered.yaml
@@ -8,6 +8,12 @@
# RUN: %lld -lSystem -dylib %t/test.dylib %t/test_macos.o -o /dev/null
# RUN: %no-arg-lld -syslibroot %S/Inputs/MacOSX.sdk -lSystem -dylib -arch x86_64 -platform_version mac-catalyst 13.15.0 14.0 %t/test.dylib %t/test_maccatalyst.o -o /dev/null
+
+# RUN: %no-arg-lld -syslibroot %S/Inputs/MacOSX.sdk -lSystem -dylib -arch x86_64 -platform_version mac-catalyst 13.15.0 14.0 %t/test_maccatalyst.o -o /dev/null -framework MacOnly-Indirect
+
+# RUN: not %no-arg-lld -syslibroot %S/Inputs/MacOSX.sdk -lSystem -dylib -arch x86_64 -platform_version mac-catalyst 13.15.0 14.0 %t/test_maccatalyst.o -o /dev/null -framework MacOnly 2>&1 | FileCheck --check-prefix=INCOMPATIBLE %s
+# INCOMPATIBLE: System/Library/Frameworks{{[\\/]}}MacOnly.framework{{[\\/]}}MacOnly.tbd(MacOnly.dylib) is incompatible with x86_64 (macCatalyst)
+
# RUN: not %no-arg-lld -syslibroot %S/Inputs/MacOSX.sdk -lSystem -dylib -arch x86_64 -platform_version ios 13.15.0 14.0 %t/test.dylib %t/test_ios.o -o /dev/null 2>&1 | FileCheck %s
# CHECK: test.dylib has platform macOS/macCatalyst, which is
diff erent from target platform iOS
More information about the llvm-commits
mailing list