119 lines
5.2 KiB
Diff
119 lines
5.2 KiB
Diff
From 892e84e37a525cc546d7016e9d933934e1719cd6 Mon Sep 17 00:00:00 2001
|
|
From: Tomohiro Kashiwada <kikairoya@gmail.com>
|
|
Date: Sat, 14 Jun 2025 02:10:56 +0900
|
|
Subject: [PATCH] [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>
|
|
---
|
|
lld/MinGW/Driver.cpp | 14 ++++++++++----
|
|
lld/MinGW/Options.td | 2 ++
|
|
lld/test/MinGW/lib.test | 7 +++++++
|
|
3 files changed, 19 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/lld/MinGW/Driver.cpp b/lld/MinGW/Driver.cpp
|
|
index a77d86b443..bda272b64b 100644
|
|
--- a/lld/MinGW/Driver.cpp
|
|
+++ b/lld/MinGW/Driver.cpp
|
|
@@ -139,8 +139,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)))
|
|
@@ -161,7 +162,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;
|
|
@@ -545,6 +546,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) {
|
|
@@ -556,7 +561,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:";
|
|
diff --git a/lld/MinGW/Options.td b/lld/MinGW/Options.td
|
|
index 01b0197211..e6cf48e685 100644
|
|
--- a/lld/MinGW/Options.td
|
|
+++ b/lld/MinGW/Options.td
|
|
@@ -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)">;
|
|
diff --git a/lld/test/MinGW/lib.test b/lld/test/MinGW/lib.test
|
|
index 8bd8a0e930..ac002e7549 100644
|
|
--- a/lld/test/MinGW/lib.test
|
|
+++ b/lld/test/MinGW/lib.test
|
|
@@ -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
|
|
--
|
|
2.50.1.windows.1
|
|
|