[lld-macho] Support -sub_umbrella
authorJez Ng <jezng@fb.com>
Tue, 15 Dec 2020 03:55:28 +0000 (22:55 -0500)
committerJez Ng <jezng@fb.com>
Tue, 15 Dec 2020 20:58:26 +0000 (15:58 -0500)
From what I can tell, it's essentially identical to
`-sub_library`, but it doesn't match files ending in ".dylib".

Reviewed By: #lld-macho, thakis

Differential Revision: https://reviews.llvm.org/D93276

lld/MachO/Driver.cpp
lld/MachO/Options.td
lld/test/MachO/sub-library.s

index 96972cb17e6fa5752915b51adb18e32559e891f9..8bac9b7b877fe283a0091d9b19b27737a004199e 100644 (file)
@@ -488,12 +488,13 @@ static void parseOrderFile(StringRef path) {
 // with a path of .*/libfoo.{dylib, tbd}.
 // XXX ld64 seems to ignore the extension entirely when matching sub-libraries;
 // I'm not sure what the use case for that is.
-static bool markSubLibrary(StringRef searchName) {
+static bool markReexport(StringRef searchName, ArrayRef<StringRef> extensions) {
   for (InputFile *file : inputFiles) {
     if (auto *dylibFile = dyn_cast<DylibFile>(file)) {
       StringRef filename = path::filename(dylibFile->getName());
       if (filename.consume_front(searchName) &&
-          (filename == ".dylib" || filename == ".tbd")) {
+          (filename.empty() ||
+           find(extensions, filename) != extensions.end())) {
         dylibFile->reexport = true;
         return true;
       }
@@ -836,11 +837,17 @@ bool macho::link(llvm::ArrayRef<const char *> argsArr, bool canExitEarly,
 
   // Now that all dylibs have been loaded, search for those that should be
   // re-exported.
-  for (opt::Arg *arg : args.filtered(OPT_sub_library)) {
+  for (opt::Arg *arg : args.filtered(OPT_sub_library, OPT_sub_umbrella)) {
     config->hasReexports = true;
     StringRef searchName = arg->getValue();
-    if (!markSubLibrary(searchName))
-      error("-sub_library " + searchName + " does not match a supplied dylib");
+    std::vector<StringRef> extensions;
+    if (arg->getOption().getID() == OPT_sub_library)
+      extensions = {".dylib", ".tbd"};
+    else
+      extensions = {".tbd"};
+    if (!markReexport(searchName, extensions))
+      error(arg->getSpelling() + " " + searchName +
+            " does not match a supplied dylib");
   }
 
   // Parse LTO options.
index ca666613e3b9e188e69e28e35c22893dfcc560a1..e3ee14a74328277a05e665ea15248c3a0a66d0ed 100644 (file)
@@ -672,7 +672,6 @@ def sub_library : Separate<["-"], "sub_library">,
 def sub_umbrella : Separate<["-"], "sub_umbrella">,
      MetaVarName<"<name>">,
      HelpText<"Re-export the framework as <name>">,
-     Flags<[HelpHidden]>,
      Group<grp_rare>;
 def allowable_client : Separate<["-"], "allowable_client">,
      MetaVarName<"<name>">,
index 0e5b596dc04ad40bfb402002e8a17223f309951e..7f5e2904e962109f98ddf399f794a4bbb39c88ea 100644 (file)
 # RUN:   --check-prefix=HELLO-HEADERS
 # HELLO-HEADERS: NO_REEXPORTED_DYLIBS
 
-# RUN: llvm-objdump --macho --all-headers %t/libgoodbye.dylib | FileCheck %s -DDIR=%t \
-# RUN:   --check-prefix=GOODBYE-HEADERS
-# GOODBYE-HEADERS-NOT: NO_REEXPORTED_DYLIBS
-# GOODBYE-HEADERS:     cmd     LC_REEXPORT_DYLIB
-# GOODBYE-HEADERS-NOT: Load command
-# GOODBYE-HEADERS:     name    [[DIR]]/libhello.dylib
-
-# RUN: llvm-objdump --macho --all-headers %t/libsuper.dylib | FileCheck %s -DDIR=%t \
-# RUN:   --check-prefix=SUPER-HEADERS
-# SUPER-HEADERS-NOT: NO_REEXPORTED_DYLIBS
-# SUPER-HEADERS:     cmd     LC_REEXPORT_DYLIB
-# SUPER-HEADERS-NOT: Load command
-# SUPER-HEADERS:     name    [[DIR]]/libgoodbye.dylib
+# RUN: llvm-objdump --macho --all-headers %t/libgoodbye.dylib | FileCheck %s \
+# RUN:   --check-prefix=REEXPORT-HEADERS -DPATH=%t/libhello.dylib
+
+# RUN: llvm-objdump --macho --all-headers %t/libsuper.dylib | FileCheck %s \
+# RUN:   --check-prefix=REEXPORT-HEADERS -DPATH=%t/libgoodbye.dylib
+
+# REEXPORT-HEADERS-NOT: NO_REEXPORTED_DYLIBS
+# REEXPORT-HEADERS:     cmd     LC_REEXPORT_DYLIB
+# REEXPORT-HEADERS-NOT: Load command
+# REEXPORT-HEADERS:     name    [[PATH]]
 
 # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t/sub-library.o
 # RUN: %lld -o %t/sub-library -L%t -lsuper %t/sub-library.o
 # RUN:  | FileCheck %s --check-prefix=MISSING-REEXPORT -DDIR=%t
 # MISSING-REEXPORT: error: unable to locate re-export with install name [[DIR]]/libgoodbye.dylib
 
+
+## We can match dylibs without extensions too.
+# RUN: mkdir -p %t/Hello.framework/Versions
+# RUN: %lld -dylib %t/libhello.o -o %t/Hello.framework/Versions/Hello
+# RUN: %lld -dylib -o %t/libgoodbye2.dylib -sub_library Hello %t/Hello.framework/Versions/Hello %t/libgoodbye.o
+# RUN: llvm-objdump --macho --all-headers %t/libgoodbye2.dylib | FileCheck %s \
+# RUN:   --check-prefix=REEXPORT-HEADERS -DPATH=%t/Hello.framework/Versions/Hello
+
+## -sub_umbrella works almost identically...
+# RUN: %lld -dylib -o %t/libgoodbye3.dylib -sub_umbrella Hello %t/Hello.framework/Versions/Hello %t/libgoodbye.o
+# RUN: llvm-objdump --macho --all-headers %t/libgoodbye3.dylib | FileCheck %s \
+# RUN:   --check-prefix=REEXPORT-HEADERS -DPATH=%t/Hello.framework/Versions/Hello
+
+## But it doesn't match .dylib extensions:
+# RUN: not %lld -dylib -L%t -sub_umbrella libhello -lhello %t/libgoodbye.o \
+# RUN:   -o %t/libgoodbye.dylib 2>&1 | FileCheck %s --check-prefix=MISSING-FRAMEWORK
+# MISSING-FRAMEWORK: error: -sub_umbrella libhello does not match a supplied dylib
+
 .text
 .globl _main