如何在没有 .lib 的情况下将 clang link 直接转换为 Windows 中的 DLL

How do you make clang link directly to a DLL in Windows without a .lib

TinyCC 和 GCC 都支持无库链接,支持直接链接到 DLL 文件有一段时间了(因为自 Win3.1 以来库没有真正的用途)。但是在 Windows 中出于某种原因,Clang 坚持将 .dll 文件解释为 .lib 文件。根据 LLVM 的页面,此处 https://lld.llvm.org/windows_support.htmllld-link 确实支持直接 dll 链接,但实际上,我没有看到任何指定方式。 (这适用于 LLVM 10.0 和 11.0)

需要说明的是,我指的不是使用 LoadLibraryGetProcAddress 手动加载。我指的是像这样调用编译器:

"C:\Program Files\mingw-w64\x86_64-8.1.0-win32-seh-rt_v6-rev0\mingw64\bin\gcc" -o rdtest.exe rdtest.c -lgdi32 -luser32 openvr_api.dll C:\windows\system32\opengl32.dll C:\windows\system32\msvcrt.dll

^^ 有效

"C:\Program Files\LLVM\bin\clang.exe" -fuse-ld=lld-link -v -o rdtest.exe rdtest.c -lgdi32 -luser32 openvr_api.dll C:\windows\system32\opengl32.dll C:\windows\system32\msvcrt.dll
[...]
1 warning generated.
 "C:\Program Files\LLVM\bin\lld-link" -out:rdtest.exe -defaultlib:libcmt "-libpath:C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.28.29333\lib\x64" "-libpath:C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.28.29333\atlmfc\lib\x64" "-libpath:C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\x64" "-libpath:C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\um\x64" -nologo "C:\Users\cnlohr\AppData\Local\Temp\rdtest-a9472b.o" gdi32.lib user32.lib openvr_api.dll "C:\windows\system32\opengl32.dll" "C:\windows\system32\msvcrt.dll"
lld-link: error: openvr_api.dll: bad file type. Did you specify a DLL instead of an import library?
lld-link: error: C:\windows\system32\opengl32.dll: bad file type. Did you specify a DLL instead of an import library?
lld-link: error: C:\windows\system32\msvcrt.dll: bad file type. Did you specify a DLL instead of an import library?
clang: error: linker command failed with exit code 1 (use -v to see invocation)

^^ 失败

你误读了 LLVM 的文档。我相信你指的部分是:

Linking against DLL

Done. LLD can read import libraries needed to link against DLL. Both export-by-name and export-by-ordinal are supported.

它们与 MinGW / TinyCC 的“直接”(没有 .lib)linking 的意思不同。它们的字面意思是“LLD 可以 link 到 Windows 上的共享库,并且能够读取 .lib 文件来做到这一点 ”。没错,但是您仍然需要 .lib,就像 MSVC 一样。

所以答案是,不幸的是,你不能让 Clang/LLD 在撰写本文时这样做

这是最近在上游 https://reviews.llvm.org/rGa9ff1ce1b9a52add7557cf0579d424c9d0678860 上实现的,并已向后移植到 MSYS2 llvm 包。