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) {
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) {
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");
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))) {
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:
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">,
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">,
# 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
# 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
# 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