Index: lld/MachO/Config.h =================================================================== --- lld/MachO/Config.h +++ lld/MachO/Config.h @@ -96,6 +96,7 @@ bool headerPadMaxInstallNames = false; bool ltoNewPassManager = LLVM_ENABLE_NEW_PASS_MANAGER; bool markDeadStrippableDylib = false; + bool printDylibSearch = false; bool printEachFile = false; bool printWhyLoad = false; bool searchDylibsFirst = false; Index: lld/MachO/Driver.h =================================================================== --- lld/MachO/Driver.h +++ lld/MachO/Driver.h @@ -81,11 +81,6 @@ explicit DependencyTracker(llvm::StringRef path); // Adds the given path to the set of not-found files. - inline void logFileNotFound(std::string path) { - if (active) - notFounds.insert(std::move(path)); - } - inline void logFileNotFound(const Twine &path) { if (active) notFounds.insert(path.str()); Index: lld/MachO/Driver.cpp =================================================================== --- lld/MachO/Driver.cpp +++ lld/MachO/Driver.cpp @@ -1020,6 +1020,8 @@ config->headerPad = args::getHex(args, OPT_headerpad, /*Default=*/32); config->headerPadMaxInstallNames = args.hasArg(OPT_headerpad_max_install_names); + config->printDylibSearch = + args.hasArg(OPT_print_dylib_search) || getenv("RC_TRACE_DYLIB_SEARCHING"); config->printEachFile = args.hasArg(OPT_t); config->printWhyLoad = args.hasArg(OPT_why_load); config->outputType = getOutputType(args); Index: lld/MachO/DriverUtils.cpp =================================================================== --- lld/MachO/DriverUtils.cpp +++ lld/MachO/DriverUtils.cpp @@ -176,20 +176,27 @@ return std::string(data.str()); } -Optional macho::resolveDylibPath(StringRef path) { - // TODO: if a tbd and dylib are both present, we should check to make sure - // they are consistent. - if (fs::exists(path)) - return std::string(path); - else +static void searchedDylib(const Twine &path, bool found) { + if (config->printDylibSearch) + message("searched " + path + (found ? ", found " : ", not found")); + if (!found) depTracker->logFileNotFound(path); +} - SmallString<261> location = path; - path::replace_extension(location, ".tbd"); - if (fs::exists(location)) - return std::string(location); - else - depTracker->logFileNotFound(location); +Optional macho::resolveDylibPath(StringRef dylibPath) { + // TODO: if a tbd and dylib are both present, we should check to make sure + // they are consistent. + bool dylibExists = fs::exists(dylibPath); + searchedDylib(dylibPath, dylibExists); + if (dylibExists) + return std::string(dylibPath); + + SmallString<261> tbdPath = dylibPath; + path::replace_extension(tbdPath, ".tbd"); + bool tbdExists = fs::exists(tbdPath); + searchedDylib(tbdPath, tbdExists); + if (tbdExists) + return std::string(tbdPath); return {}; } @@ -249,10 +256,10 @@ path::append(base, name); for (StringRef ext : extensions) { Twine location = base + ext; - if (fs::exists(location)) + bool exists = fs::exists(location); + searchedDylib(location, exists); + if (exists) return saver.save(location.str()); - else - depTracker->logFileNotFound(location); } } return {}; Index: lld/MachO/Options.td =================================================================== --- lld/MachO/Options.td +++ lld/MachO/Options.td @@ -49,8 +49,12 @@ def time_trace: Flag<["--"], "time-trace">, HelpText<"Record time trace">; def time_trace_granularity_eq: Joined<["--"], "time-trace-granularity=">, HelpText<"Minimum time granularity (in microseconds) traced by time profiler">; -def time_trace_file_eq: Joined<["--"], "time-trace-file=">, HelpText<"Specify time trace output file">; -def deduplicate_literals: Flag<["--"], "deduplicate-literals">, HelpText<"Enable literal deduplication">; +def time_trace_file_eq: Joined<["--"], "time-trace-file=">, + HelpText<"Specify time trace output file">; +def deduplicate_literals: Flag<["--"], "deduplicate-literals">, + HelpText<"Enable literal deduplication">; +def print_dylib_search: Flag<["--"], "print-dylib-search">, + HelpText<"Print which paths lld searched when trying to find dylibs">; // This is a complete Options.td compiled from Apple's ld(1) manpage // dated 2018-03-07 and cross checked with ld64 source code in repo Index: lld/test/MachO/link-search-order.s =================================================================== --- lld/test/MachO/link-search-order.s +++ lld/test/MachO/link-search-order.s @@ -15,7 +15,8 @@ ################ default, which is the same as -search_paths_first # RUN: %lld -L%S/Inputs/MacOSX.sdk/usr/lib -o %t/test -Z \ -# RUN: -L%tA -L%tD -L%t -lhello -lgoodbye -lSystem %t/test.o +# RUN: -L%tA -L%tD -L%t -lhello -lgoodbye -lSystem %t/test.o \ +# RUN: --print-dylib-search | FileCheck --check-prefix=ARCHIVESEARCH -DPATH=%t %s # RUN: llvm-objdump --macho --dylibs-used %t/test | FileCheck --check-prefix=ARCHIVE %s ################ Test all permutations of -L%t{A,D} with -search_paths_first @@ -33,8 +34,9 @@ # RUN: llvm-objdump --macho --dylibs-used %t/test | FileCheck --check-prefix=DYLIB %s ################ Test all permutations of -L%t{A,D} with -search_dylibs_first -# RUN: %lld -L%S/Inputs/MacOSX.sdk/usr/lib -o %t/test -Z \ -# RUN: -L%tA -L%tD -L%t -lhello -lgoodbye -lSystem %t/test.o -search_dylibs_first +# RUN: env RC_TRACE_DYLIB_SEARCHING=1 %lld -L%S/Inputs/MacOSX.sdk/usr/lib -o %t/test -Z \ +# RUN: -L%tA -L%tD -L%t -lhello -lgoodbye -lSystem %t/test.o -search_dylibs_first \ +# RUN: | FileCheck --check-prefix=DYLIBSEARCH -DPATH=%t %s # RUN: llvm-objdump --macho --dylibs-used %t/test | FileCheck --check-prefix=DYLIB %s # RUN: %lld -L%S/Inputs/MacOSX.sdk/usr/lib -o %t/test -Z \ # RUN: -L%tD -L%tA -L%t -lhello -lgoodbye -lSystem %t/test.o -search_dylibs_first @@ -50,10 +52,26 @@ # DYLIB: @executable_path/libgoodbye.dylib # DYLIB: /usr/lib/libSystem.dylib +# DYLIBSEARCH: searched {{.*}}/MacOSX.sdk/usr/lib/libhello.tbd, not found +# DYLIBSEARCH-NEXT: searched {{.*}}/MacOSX.sdk/usr/lib/libhello.dylib, not found +# DYLIBSEARCH-NEXT: searched [[PATH]]A/libhello.tbd, not found +# DYLIBSEARCH-NEXT: searched [[PATH]]A/libhello.dylib, not found +# DYLIBSEARCH: searched [[PATH]]/libhello.dylib, found +# DYLIBSEARCH: searched [[PATH]]D/libgoodbye.dylib, found + # ARCHIVE: @executable_path/libhello.dylib # ARCHIVE-NOT: @executable_path/libgoodbye.dylib # ARCHIVE: /usr/lib/libSystem.dylib +# ARCHIVESEARCH: searched {{.*}}/MacOSX.sdk/usr/lib/libhello.tbd, not found +# ARCHIVESEARCH-NEXT: searched {{.*}}/MacOSX.sdk/usr/lib/libhello.dylib, not found +# ARCHIVESEARCH-NEXT: searched {{.*}}/MacOSX.sdk/usr/lib/libhello.a, not found +# ARCHIVESEARCH-NEXT: searched [[PATH]]A/libhello.tbd, not found +# ARCHIVESEARCH-NEXT: searched [[PATH]]A/libhello.dylib, not found +# ARCHIVESEARCH-NEXT: searched [[PATH]]A/libhello.a, not found +# ARCHIVESEARCH: searched [[PATH]]/libhello.dylib, found +# ARCHIVESEARCH: searched [[PATH]]A/libgoodbye.a, found + .section __TEXT,__text .global _main