diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -235,6 +235,7 @@ } static InputFile *addFile(StringRef path, bool forceLoadArchive, + bool isExplicit = true, bool isBundleLoader = false) { Optional buffer = readFile(path); if (!buffer) @@ -294,7 +295,8 @@ case file_magic::macho_dynamically_linked_shared_lib_stub: case file_magic::tapi_file: if (DylibFile * dylibFile = loadDylib(mbref)) { - dylibFile->explicitlyLinked = true; + if (isExplicit) + dylibFile->explicitlyLinked = true; newFile = dylibFile; } break; @@ -327,8 +329,8 @@ static void addLibrary(StringRef name, bool isWeak, bool isReexport, bool isExplicit) { if (Optional path = findLibrary(name)) { - if (auto *dylibFile = dyn_cast_or_null(addFile(*path, false))) { - dylibFile->explicitlyLinked = isExplicit; + if (auto *dylibFile = dyn_cast_or_null( + addFile(*path, /*forceLoadArchive=*/false, isExplicit))) { if (isWeak) dylibFile->forceWeakImport = true; if (isReexport) { @@ -344,8 +346,8 @@ static void addFramework(StringRef name, bool isWeak, bool isReexport, bool isExplicit) { if (Optional path = findFramework(name)) { - if (auto *dylibFile = dyn_cast_or_null(addFile(*path, false))) { - dylibFile->explicitlyLinked = isExplicit; + if (auto *dylibFile = dyn_cast_or_null( + addFile(*path, /*forceLoadArchive=*/false, isExplicit))) { if (isWeak) dylibFile->forceWeakImport = true; if (isReexport) { @@ -400,7 +402,7 @@ return; MemoryBufferRef mbref = *buffer; for (StringRef path : args::getLines(mbref)) - addFile(rerootPath(path), false); + addFile(rerootPath(path), /*forceLoadArchive=*/false); } // An order file has one entry per line, in the following format: @@ -876,25 +878,25 @@ switch (opt.getID()) { case OPT_INPUT: - addFile(rerootPath(arg->getValue()), false); + addFile(rerootPath(arg->getValue()), /*forceLoadArchive=*/false); break; case OPT_reexport_library: - if (auto *dylibFile = dyn_cast_or_null( - addFile(rerootPath(arg->getValue()), false))) { + if (auto *dylibFile = dyn_cast_or_null(addFile( + rerootPath(arg->getValue()), /*forceLoadArchive=*/false))) { config->hasReexports = true; dylibFile->reexport = true; } break; case OPT_weak_library: if (auto *dylibFile = dyn_cast_or_null( - addFile(rerootPath(arg->getValue()), false))) + addFile(rerootPath(arg->getValue()), /*forceLoadArchive=*/false))) dylibFile->forceWeakImport = true; break; case OPT_filelist: addFileList(arg->getValue()); break; case OPT_force_load: - addFile(rerootPath(arg->getValue()), true); + addFile(rerootPath(arg->getValue()), /*forceLoadArchive=*/true); break; case OPT_l: case OPT_reexport_l: @@ -1001,7 +1003,8 @@ if (const Arg *arg = args.getLastArg(OPT_bundle_loader)) { if (config->outputType != MH_BUNDLE) error("-bundle_loader can only be used with MachO bundle output"); - addFile(arg->getValue(), false, true); + addFile(arg->getValue(), /*forceLoadArchive=*/false, /*isExplicit=*/false, + /*isBundleLoader=*/true); } config->ltoObjPath = args.getLastArgValue(OPT_object_path_lto); config->ltoNewPassManager = diff --git a/lld/test/MachO/dead-strip-dylibs.s b/lld/test/MachO/dead-strip-dylibs.s --- a/lld/test/MachO/dead-strip-dylibs.s +++ b/lld/test/MachO/dead-strip-dylibs.s @@ -48,8 +48,22 @@ ## 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_with_bar.dylib -# RUN: llvm-otool -L %t/main | FileCheck --check-prefix=NOBAR %s +# 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 +# NOLIBBAR: /usr/lib/libSystem.dylib +# NOLIBBAR-NOT: libbar.dylib +# NOLIBBAR: foo.dylib +# NOLIBBAR-NOT: libbar.dylib + +## ...but with an additional explicit reference it's not stripped again. +# RUN: %lld -lSystem %t/main.o %t/linkopt_bar.o -o %t/main -L %t %t/foo.dylib -lbar +# RUN: llvm-otool -L %t/main | FileCheck --check-prefix=LIBBAR %s +# RUN: %lld -lSystem %t/main.o -o %t/main -L %t %t/foo.dylib -lbar %t/linkopt_bar.o +# RUN: llvm-otool -L %t/main | FileCheck --check-prefix=LIBBAR %s +# LIBBAR-DAG: /usr/lib/libSystem.dylib +# LIBBAR-DAG: libbar.dylib +# LIBBAR-DAG: foo.dylib ## Test that a DylibSymbol being replaced by a DefinedSymbol marks the ## dylib as unreferenced.