[lld] 66a1ecd - [lld/mac] Implement -needed_framework, -needed_library, -needed-l
Nico Weber via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 2 08:07:16 PDT 2021
Author: Nico Weber
Date: 2021-06-02T11:06:42-04:00
New Revision: 66a1ecd2cf905d6119477516601126f44be297a8
URL: https://github.com/llvm/llvm-project/commit/66a1ecd2cf905d6119477516601126f44be297a8
DIFF: https://github.com/llvm/llvm-project/commit/66a1ecd2cf905d6119477516601126f44be297a8.diff
LOG: [lld/mac] Implement -needed_framework, -needed_library, -needed-l
These allow overriding dead_strip_dylibs.
Differential Revision: https://reviews.llvm.org/D103499
Added:
Modified:
lld/MachO/Driver.cpp
lld/MachO/InputFiles.h
lld/MachO/Options.td
lld/MachO/Writer.cpp
lld/test/MachO/dead-strip-dylibs.s
Removed:
################################################################################
diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp
index 3a51fde3cb89..b568609a65e1 100644
--- a/lld/MachO/Driver.cpp
+++ b/lld/MachO/Driver.cpp
@@ -326,11 +326,13 @@ static InputFile *addFile(StringRef path, bool forceLoadArchive,
return newFile;
}
-static void addLibrary(StringRef name, bool isWeak, bool isReexport,
- bool isExplicit) {
+static void addLibrary(StringRef name, bool isNeeded, bool isWeak,
+ bool isReexport, bool isExplicit) {
if (Optional<StringRef> path = findLibrary(name)) {
if (auto *dylibFile = dyn_cast_or_null<DylibFile>(
addFile(*path, /*forceLoadArchive=*/false, isExplicit))) {
+ if (isNeeded)
+ dylibFile->forceNeeded = true;
if (isWeak)
dylibFile->forceWeakImport = true;
if (isReexport) {
@@ -343,11 +345,13 @@ static void addLibrary(StringRef name, bool isWeak, bool isReexport,
error("library not found for -l" + name);
}
-static void addFramework(StringRef name, bool isWeak, bool isReexport,
- bool isExplicit) {
+static void addFramework(StringRef name, bool isNeeded, bool isWeak,
+ bool isReexport, bool isExplicit) {
if (Optional<std::string> path = findFramework(name)) {
if (auto *dylibFile = dyn_cast_or_null<DylibFile>(
addFile(*path, /*forceLoadArchive=*/false, isExplicit))) {
+ if (isNeeded)
+ dylibFile->forceNeeded = true;
if (isWeak)
dylibFile->forceWeakImport = true;
if (isReexport) {
@@ -383,12 +387,12 @@ void macho::parseLCLinkerOption(InputFile *f, unsigned argc, StringRef data) {
for (const Arg *arg : args) {
switch (arg->getOption().getID()) {
case OPT_l:
- addLibrary(arg->getValue(), /*isWeak=*/false, /*isReexport=*/false,
- /*isExplicit=*/false);
+ addLibrary(arg->getValue(), /*isNeeded=*/false, /*isWeak=*/false,
+ /*isReexport=*/false, /*isExplicit=*/false);
break;
case OPT_framework:
- addFramework(arg->getValue(), /*isWeak=*/false, /*isReexport=*/false,
- /*isExplicit=*/false);
+ addFramework(arg->getValue(), /*isNeeded=*/false, /*isWeak=*/false,
+ /*isReexport=*/false, /*isExplicit=*/false);
break;
default:
error(arg->getSpelling() + " is not allowed in LC_LINKER_OPTION");
@@ -880,6 +884,11 @@ void createFiles(const InputArgList &args) {
case OPT_INPUT:
addFile(rerootPath(arg->getValue()), /*forceLoadArchive=*/false);
break;
+ case OPT_needed_library:
+ if (auto *dylibFile = dyn_cast_or_null<DylibFile>(
+ addFile(rerootPath(arg->getValue()), false)))
+ dylibFile->forceNeeded = true;
+ break;
case OPT_reexport_library:
if (auto *dylibFile = dyn_cast_or_null<DylibFile>(addFile(
rerootPath(arg->getValue()), /*forceLoadArchive=*/false))) {
@@ -899,15 +908,19 @@ void createFiles(const InputArgList &args) {
addFile(rerootPath(arg->getValue()), /*forceLoadArchive=*/true);
break;
case OPT_l:
+ case OPT_needed_l:
case OPT_reexport_l:
case OPT_weak_l:
- addLibrary(arg->getValue(), opt.getID() == OPT_weak_l,
- opt.getID() == OPT_reexport_l, /*isExplicit=*/true);
+ addLibrary(arg->getValue(), opt.getID() == OPT_needed_l,
+ opt.getID() == OPT_weak_l, opt.getID() == OPT_reexport_l,
+ /*isExplicit=*/true);
break;
case OPT_framework:
+ case OPT_needed_framework:
case OPT_reexport_framework:
case OPT_weak_framework:
- addFramework(arg->getValue(), opt.getID() == OPT_weak_framework,
+ addFramework(arg->getValue(), opt.getID() == OPT_needed_framework,
+ opt.getID() == OPT_weak_framework,
opt.getID() == OPT_reexport_framework, /*isExplicit=*/true);
break;
default:
diff --git a/lld/MachO/InputFiles.h b/lld/MachO/InputFiles.h
index 321ea0e6774f..c26cd0f97622 100644
--- a/lld/MachO/InputFiles.h
+++ b/lld/MachO/InputFiles.h
@@ -156,6 +156,7 @@ class DylibFile : public InputFile {
int64_t ordinal = 0; // Ordinal numbering starts from 1, so 0 is a sentinel
RefState refState;
bool reexport = false;
+ bool forceNeeded = false;
bool forceWeakImport = false;
bool deadStrippable = false;
bool explicitlyLinked = false;
diff --git a/lld/MachO/Options.td b/lld/MachO/Options.td
index cc5ab09ef550..47c6d9997e98 100644
--- a/lld/MachO/Options.td
+++ b/lld/MachO/Options.td
@@ -114,6 +114,14 @@ def weak_library : Separate<["-"], "weak_library">,
MetaVarName<"<path>">,
HelpText<"Like bare <path>, but mark library and its references as weak imports">,
Group<grp_libs>;
+def needed_l : Joined<["-"], "needed-l">,
+ MetaVarName<"<name>">,
+ HelpText<"Like -l<name>, but link library even if its symbols are not used and -dead_strip_dylibs is active">,
+ Group<grp_libs>;
+def needed_library : Separate<["-"], "needed_library">,
+ MetaVarName<"<path>">,
+ HelpText<"Like bare <path>, but link library even if its symbols are not used and -dead_strip_dylibs is active">,
+ Group<grp_libs>;
def reexport_l : Joined<["-"], "reexport-l">,
MetaVarName<"<name>">,
HelpText<"Like -l<name>, but export all symbols of <name> from newly created library">,
@@ -157,6 +165,10 @@ def weak_framework : Separate<["-"], "weak_framework">,
MetaVarName<"<name>">,
HelpText<"Like -framework <name>, but mark framework and its references as weak imports">,
Group<grp_libs>;
+def needed_framework : Separate<["-"], "needed_framework">,
+ MetaVarName<"<name>">,
+ HelpText<"Like -framework <name>, but link <name> even if none of its symbols are used and -dead_strip_dylibs is active">,
+ Group<grp_libs>;
def reexport_framework : Separate<["-"], "reexport_framework">,
MetaVarName<"<name>">,
HelpText<"Like -framework <name>, but export all symbols of <name> from the newly created library">,
diff --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp
index 22bb20aa4604..da2ae690c45b 100644
--- a/lld/MachO/Writer.cpp
+++ b/lld/MachO/Writer.cpp
@@ -697,7 +697,7 @@ template <class LP> void Writer::createLoadCommands() {
// FIXME: `isReferenced()` is currently computed before dead code
// stripping, so references from dead code keep a dylib alive. This
// matches ld64, but it's something we should do better.
- if (!dylibFile->isReferenced() &&
+ if (!dylibFile->isReferenced() && !dylibFile->forceNeeded &&
(!dylibFile->explicitlyLinked || dylibFile->deadStrippable ||
config->deadStripDylibs))
continue;
diff --git a/lld/test/MachO/dead-strip-dylibs.s b/lld/test/MachO/dead-strip-dylibs.s
index 821c36c565b0..4ea5041c59d6 100644
--- a/lld/test/MachO/dead-strip-dylibs.s
+++ b/lld/test/MachO/dead-strip-dylibs.s
@@ -4,6 +4,7 @@
# RUN: llvm-mc %t/bar.s -triple=x86_64-apple-macos -filetype=obj -o %t/bar.o
# RUN: %lld -dylib %t/bar.o -o %t/bar.dylib
+# RUN: %lld -dylib %t/bar.o -o %t/libbar.dylib
# RUN: %lld -dylib -mark_dead_strippable_dylib %t/bar.o -o %t/bar-strip.dylib
# RUN: llvm-mc %t/foo.s -triple=x86_64-apple-macos -filetype=obj -o %t/foo.o
@@ -36,7 +37,7 @@
# RUN: -dead_strip_dylibs
# RUN: llvm-otool -L %t/main | FileCheck --check-prefix=NOBAR %s
-## ...or bar is explicitly marked dead-strippable
+## ...or bar is explicitly marked dead-strippable.
# RUN: %lld -lSystem %t/main.o -o %t/main %t/foo.dylib %t/bar-strip.dylib
# RUN: llvm-otool -L %t/main | FileCheck --check-prefix=NOBARSTRIP %s
# NOBARSTRIP-NOT: bar-strip.dylib
@@ -45,9 +46,16 @@
# NOBARSTRIP: foo.dylib
# NOBARSTRIP-NOT: bar-strip.dylib
+## But -needed_library and -needed-l win over -dead_strip_dylibs again.
+# RUN: %lld -lSystem %t/main.o -o %t/main %t/foo_with_bar.dylib \
+# RUN: -needed_library %t/bar.dylib -dead_strip_dylibs
+# RUN: llvm-otool -L %t/main | FileCheck --check-prefix=BAR %s
+# RUN: %lld -lSystem %t/main.o -o %t/main %t/foo_with_bar.dylib \
+# RUN: -L%t -needed-lbar -dead_strip_dylibs
+# RUN: llvm-otool -L %t/main | FileCheck --check-prefix=BAR %s
+
## LC_LINKER_OPTION does not count as an explicit reference.
# RUN: llvm-mc %t/linkopt_bar.s -triple=x86_64-apple-macos -filetype=obj -o %t/linkopt_bar.o
-# RUN: %lld -dylib %t/bar.o -o %t/libbar.dylib
# RUN: %lld -lSystem %t/main.o %t/linkopt_bar.o -o %t/main -L %t %t/foo.dylib
# RUN: llvm-otool -L %t/main | FileCheck --check-prefix=NOLIBBAR %s
# NOLIBBAR-NOT: libbar.dylib
More information about the llvm-commits
mailing list