forked from OSchip/llvm-project
[lld/mac] Implement -needed_framework, -needed_library, -needed-l
These allow overriding dead_strip_dylibs. Differential Revision: https://reviews.llvm.org/D103499
This commit is contained in:
parent
e14fd7d879
commit
66a1ecd2cf
|
@ -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:
|
||||
|
|
|
@ -156,6 +156,7 @@ public:
|
|||
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;
|
||||
|
|
|
@ -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">,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue