diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -408,7 +408,7 @@ static void addLibrary(StringRef name, bool isNeeded, bool isWeak, bool isReexport, bool isHidden, bool isExplicit, - LoadType loadType) { + LoadType loadType, StringRef refLoc = "") { if (std::optional path = findLibrary(name)) { if (auto *dylibFile = dyn_cast_or_null( addFile(*path, loadType, /*isLazy=*/false, isExplicit, @@ -424,12 +424,18 @@ } return; } - error("library not found for -l" + name); + + if (loadType == LoadType::LCLinkerOption) + warn("library not found for -l " + name + ", from LC_LINKER_OPTION in " + + refLoc); + else + error("library not found for -l" + name); } static DenseSet loadedObjectFrameworks; static void addFramework(StringRef name, bool isNeeded, bool isWeak, - bool isReexport, bool isExplicit, LoadType loadType) { + bool isReexport, bool isExplicit, LoadType loadType, + StringRef refLoc = "") { if (std::optional path = findFramework(name)) { if (loadedObjectFrameworks.contains(*path)) return; @@ -456,7 +462,11 @@ } return; } - error("framework not found for -framework " + name); + if (loadType == LoadType::LCLinkerOption) + warn("framework not found for -framework " + name + + ", from LC_LINKER_OPTION in " + refLoc); + else + error("framework not found for -framework " + name); } // Parses LC_LINKER_OPTION contents, which can add additional command line @@ -482,14 +492,14 @@ return; addLibrary(arg, /*isNeeded=*/false, /*isWeak=*/false, /*isReexport=*/false, /*isHidden=*/false, /*isExplicit=*/false, - LoadType::LCLinkerOption); + LoadType::LCLinkerOption, f->getName()); } else if (arg == "-framework") { StringRef name = argv[++i]; if (config->ignoreAutoLinkOptions.contains(name)) return; addFramework(name, /*isNeeded=*/false, /*isWeak=*/false, /*isReexport=*/false, /*isExplicit=*/false, - LoadType::LCLinkerOption); + LoadType::LCLinkerOption, f->getName()); } else { error(arg + " is not allowed in LC_LINKER_OPTION"); } diff --git a/lld/test/MachO/lc-linker-option.ll b/lld/test/MachO/lc-linker-option.ll --- a/lld/test/MachO/lc-linker-option.ll +++ b/lld/test/MachO/lc-linker-option.ll @@ -134,6 +134,21 @@ ; RUN: %lld %t/main -F %t -framework Foo -framework Foo -o /dev/null ; RUN: %lld -F %t -framework Foo -framework Foo %t/main -o /dev/null +;; Checks that "framework/library not found" from LC_LINKER_OPTIONS are reported +;; as warnings and not errors. +; RUN: %no-fatal-warnings-lld -ObjC %t/load-framework-foo.o %t/main.o -o %t/main-no-foo.out 2>&1 | FileCheck %s --check-prefix=WARN-FW +; RUN: %no-fatal-warnings-lld -dylib -ObjC %t/load-library-foo.o -o %t/no-lib-foo.out 2>&1 | FileCheck %s --check-prefix=WARN-LIB + +; RUN: llvm-objdump --macho --syms %t/main-no-foo.out | FileCheck %s --check-prefix=SYMS_NO_FOO + +; WARN-FW: ld64.lld: warning: framework not found for -framework Foo, from LC_LINKER_OPTION in {{.+}}load-framework-foo.o +; WARN-LIB: ld64.lld: warning: library not found for -l foo, from LC_LINKER_OPTION in {{.+}}load-library-foo.o + +;; Verify that nothing from the framework is included. +; SYMS_NO_FOO: SYMBOL TABLE: +; SYMS_NO_FOO-NEXT: g F __TEXT,__text _main +; SYMS_NO_FOO-NOT: g O __DATA,__objc_data _OBJC_CLASS_$_TestClass + ;--- framework.ll target triple = "x86_64-apple-macosx10.15.0" target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"