return v;
}
-static void addFile(StringRef path) {
+static InputFile *addFile(StringRef path) {
Optional<MemoryBufferRef> buffer = readFile(path);
if (!buffer)
- return;
+ return nullptr;
MemoryBufferRef mbref = *buffer;
+ InputFile *newFile = nullptr;
switch (identify_magic(mbref.getBuffer())) {
case file_magic::archive: {
inputFiles.push_back(make<ObjFile>(member));
}
- inputFiles.push_back(make<ArchiveFile>(std::move(file)));
+ newFile = make<ArchiveFile>(std::move(file));
break;
}
case file_magic::macho_object:
- inputFiles.push_back(make<ObjFile>(mbref));
+ newFile = make<ObjFile>(mbref);
break;
case file_magic::macho_dynamically_linked_shared_lib:
- inputFiles.push_back(make<DylibFile>(mbref));
+ newFile = make<DylibFile>(mbref);
break;
case file_magic::tapi_file: {
Optional<DylibFile *> dylibFile = makeDylibFromTAPI(mbref);
if (!dylibFile)
- return;
- inputFiles.push_back(*dylibFile);
+ return nullptr;
+ newFile = *dylibFile;
break;
}
default:
error(path + ": unhandled file type");
}
+ inputFiles.push_back(newFile);
+ return newFile;
}
static void addFileList(StringRef path) {
warnIfDeprecatedOption(opt);
warnIfUnimplementedOption(opt);
// TODO: are any of these better handled via filtered() or getLastArg()?
- switch (arg->getOption().getID()) {
+ switch (opt.getID()) {
case OPT_INPUT:
addFile(arg->getValue());
break;
+ case OPT_weak_library: {
+ auto *dylibFile = dyn_cast_or_null<DylibFile>(addFile(arg->getValue()));
+ if (dylibFile != nullptr)
+ dylibFile->forceWeakImport = true;
+ break;
+ }
case OPT_filelist:
addFileList(arg->getValue());
break;
case OPT_force_load:
forceLoadArchive(arg->getValue());
break;
- case OPT_l: {
+ case OPT_l:
+ case OPT_weak_l: {
StringRef name = arg->getValue();
if (Optional<std::string> path = findLibrary(name)) {
- addFile(*path);
+ auto *dylibFile = dyn_cast_or_null<DylibFile>(addFile(*path));
+ if (opt.getID() == OPT_weak_l && dylibFile != nullptr)
+ dylibFile->forceWeakImport = true;
break;
}
error("library not found for -l" + name);
break;
}
- case OPT_framework: {
+ case OPT_framework:
+ case OPT_weak_framework: {
StringRef name = arg->getValue();
if (Optional<std::string> path = findFramework(name)) {
- addFile(*path);
+ auto *dylibFile = dyn_cast_or_null<DylibFile>(addFile(*path));
+ if (opt.getID() == OPT_weak_framework && dylibFile != nullptr)
+ dylibFile->forceWeakImport = true;
break;
}
error("framework not found for -framework " + name);
def weak_l : Joined<["-"], "weak-l">,
MetaVarName<"<name>">,
HelpText<"Like -l<name>, but mark library and its references as weak imports">,
- Flags<[HelpHidden]>,
Group<grp_libs>;
def weak_library : Separate<["-"], "weak_library">,
MetaVarName<"<path>">,
HelpText<"Like bare <path>, but mark library and its references as weak imports">,
- Flags<[HelpHidden]>,
Group<grp_libs>;
def reexport_l : Joined<["-"], "reexport-l">,
MetaVarName<"<name>">,
def weak_framework : Separate<["-"], "weak_framework">,
MetaVarName<"<name>">,
HelpText<"Like -framework <name>, but mark framework and its references as weak imports">,
- Flags<[HelpHidden]>,
Group<grp_libs>;
def reexport_framework : Separate<["-"], "reexport_framework">,
MetaVarName<"<name>">,
uint64_t dylibOrdinal = 1;
for (InputFile *file : inputFiles) {
if (auto *dylibFile = dyn_cast<DylibFile>(file)) {
- in.header->addLoadCommand(
- make<LCDylib>(LC_LOAD_DYLIB, dylibFile->dylibName));
+ // TODO: dylibs that are only referenced by weak refs should also be
+ // loaded via LC_LOAD_WEAK_DYLIB.
+ LoadCommandType lcType =
+ dylibFile->forceWeakImport ? LC_LOAD_WEAK_DYLIB : LC_LOAD_DYLIB;
+ in.header->addLoadCommand(make<LCDylib>(lcType, dylibFile->dylibName));
dylibFile->ordinal = dylibOrdinal++;
if (dylibFile->reexport)
--- /dev/null
+# REQUIRES: x86
+# RUN: split-file %s %t
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/test.s -o %t/test.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/foo.s -o %t/foo.o
+# RUN: lld -flavor darwinnew -syslibroot %S/Inputs/MacOSX.sdk -lSystem -dylib %t/foo.o -o %t/libfoo.dylib
+
+# RUN: lld -flavor darwinnew -syslibroot %S/Inputs/MacOSX.sdk -weak-lSystem %t/test.o -weak_framework CoreFoundation -weak_library %t/libfoo.dylib -o %t/test
+# RUN: llvm-objdump --macho --all-headers %t/test | FileCheck %s -DDIR=%t
+
+# CHECK: cmd LC_LOAD_WEAK_DYLIB
+# CHECK-NEXT: cmdsize
+# CHECK-NEXT: name /usr/lib/libSystem.B.dylib
+
+# CHECK: cmd LC_LOAD_WEAK_DYLIB
+# CHECK-NEXT: cmdsize
+# CHECK-NEXT: name /System/Library/Frameworks/CoreFoundation.framework/CoreFoundation
+
+# CHECK: cmd LC_LOAD_WEAK_DYLIB
+# CHECK-NEXT: cmdsize
+# CHECK-NEXT: name [[DIR]]/libfoo.dylib
+
+#--- foo.s
+.globl _foo
+_foo:
+ ret
+
+#--- test.s
+.globl _main
+.text
+_main:
+ ret