[LLD][Cygwin] Implement --dll-search-prefix (#143263)

GCC on Cygwin environment invokes linker with passing
`--dll-search-prefix=cyg`.
Implementing this option makes lld-mingw invokable by `gcc -fuse-ld=lld`.

---------

Co-authored-by: jeremyd2019 <github@jdrake.com>
This commit is contained in:
Tomohiro Kashiwada
2025-06-14 02:10:56 +09:00
committed by GitHub
parent 65d88d31ea
commit 9e23e85d65
3 changed files with 19 additions and 4 deletions

View File

@@ -138,8 +138,9 @@ static std::optional<std::string> findFile(StringRef path1,
}
// This is for -lfoo. We'll look for libfoo.dll.a or libfoo.a from search paths.
static std::string
searchLibrary(StringRef name, ArrayRef<StringRef> searchPaths, bool bStatic) {
static std::string searchLibrary(StringRef name,
ArrayRef<StringRef> searchPaths, bool bStatic,
StringRef prefix) {
if (name.starts_with(":")) {
for (StringRef dir : searchPaths)
if (std::optional<std::string> s = findFile(dir, name.substr(1)))
@@ -160,7 +161,7 @@ searchLibrary(StringRef name, ArrayRef<StringRef> searchPaths, bool bStatic) {
if (std::optional<std::string> s = findFile(dir, name + ".lib"))
return *s;
if (!bStatic) {
if (std::optional<std::string> s = findFile(dir, "lib" + name + ".dll"))
if (std::optional<std::string> s = findFile(dir, prefix + name + ".dll"))
return *s;
if (std::optional<std::string> s = findFile(dir, name + ".dll"))
return *s;
@@ -554,6 +555,10 @@ bool link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS,
add("-libpath:" + StringRef(a->getValue()));
}
StringRef dllPrefix = "lib";
if (auto *arg = args.getLastArg(OPT_dll_search_prefix))
dllPrefix = arg->getValue();
StringRef prefix = "";
bool isStatic = false;
for (auto *a : args) {
@@ -565,7 +570,8 @@ bool link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS,
add(prefix + StringRef(a->getValue()));
break;
case OPT_l:
add(prefix + searchLibrary(a->getValue(), searchPaths, isStatic));
add(prefix +
searchLibrary(a->getValue(), searchPaths, isStatic, dllPrefix));
break;
case OPT_whole_archive:
prefix = "-wholearchive:";

View File

@@ -79,6 +79,8 @@ defm exclude_symbols: Eq<"exclude-symbols",
"Exclude symbols from automatic export">, MetaVarName<"<symbol[,symbol,...]>">;
def export_all_symbols: F<"export-all-symbols">,
HelpText<"Export all symbols even if a def file or dllexport attributes are used">;
defm dll_search_prefix:Eq<"dll-search-prefix", "Specify DLL prefix instead of 'lib'">,
MetaVarName<"<dll_search_prefix>">;
defm fatal_warnings: B<"fatal-warnings",
"Treat warnings as errors",
"Do not treat warnings as errors (default)">;

View File

@@ -5,6 +5,7 @@ LIB1: unable to find library -lfoo
RUN: echo > %t/lib/libfoo.dll.a
RUN: ld.lld -### -m i386pep -lfoo -L%t/lib 2>&1 | FileCheck -check-prefix=LIB2 %s
RUN: ld.lld -### -m i386pep -lfoo --dll-search-prefix=cyg -L%t/lib 2>&1 | FileCheck -check-prefix=LIB2 %s
LIB2: libfoo.dll.a
RUN: not ld.lld -### -m i386pep -l:barefilename -L%t/lib 2>&1 | FileCheck -check-prefix=LIB-LITERAL-FAIL %s
@@ -22,6 +23,7 @@ LIB3: unable to find library -lfoo
RUN: echo > %t/lib/libfoo.a
RUN: ld.lld -### -m i386pep -Bstatic -lfoo -L%t/lib 2>&1 | FileCheck -check-prefix=LIB4 %s
RUN: ld.lld -### -m i386pep -Bstatic -lfoo --dll-search-prefix=cyg -L%t/lib 2>&1 | FileCheck -check-prefix=LIB4 %s
LIB4: libfoo.a
RUN: echo > %t/lib/libbar.dll.a
@@ -46,12 +48,17 @@ MSVCSTYLE: msvcstyle.lib
RUN: echo > %t/lib/libnoimplib.dll
RUN: echo > %t/lib/noprefix_noimplib.dll
RUN: echo > %t/lib/cygnoimplib2.dll
RUN: ld.lld -### -m i386pep -L%t/lib -lnoimplib 2>&1 | FileCheck -check-prefix=DLL1 %s
RUN: ld.lld -### -m i386pep -L%t/lib -lnoprefix_noimplib 2>&1 | FileCheck -check-prefix=DLL2 %s
RUN: ld.lld -### -m i386pep -L%t/lib -lnoimplib2 --dll-search-prefix=cyg 2>&1 | FileCheck -check-prefix=DLL3 %s
DLL1: libnoimplib.dll
DLL2: noprefix_noimplib.dll
DLL3: cygnoimplib2.dll
RUN: not ld.lld -### -m i386pep -L%t/lib -static -lnoimplib 2>&1 | FileCheck -check-prefix=ERROR-NOIMPLIB %s
RUN: not ld.lld -### -m i386pep -L%t/lib -static -lnoprefix_noimplib 2>&1 | FileCheck -check-prefix=ERROR-NOPREFIX-NOIMPLIB %s
RUN: not ld.lld -### -m i386pep -L%t/lib -static -lnoimplib2 --dll-search-prefix=cyg 2>&1 | FileCheck -check-prefix=ERROR-CYG-NOIMPLIB %s
ERROR-NOIMPLIB: unable to find library -lnoimplib
ERROR-NOPREFIX-NOIMPLIB: unable to find library -lnoprefix_noimplib
ERROR-CYG-NOIMPLIB: unable to find library -lnoimplib2