Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't link with lib files made by MSVC with -static #305

Closed
kkqy opened this issue Sep 30, 2022 · 10 comments
Closed

Can't link with lib files made by MSVC with -static #305

kkqy opened this issue Sep 30, 2022 · 10 comments

Comments

@kkqy
Copy link

kkqy commented Sep 30, 2022

MinGW-w64 can link with lib files made by MSVC, but llvm-mingw dosen't support?

@longnguyen2004
Copy link
Contributor

Just to be clear, I've never seen a case where someone would do that. Mixing libraries made by 2 different compilers will potentially causes problems, due to incompatible CRT, debug symbol format, etc etc. With that said, what's the error from the linker?

@kkqy
Copy link
Author

kkqy commented Oct 1, 2022

Just to be clear, I've never seen a case where someone would do that. Mixing libraries made by 2 different compilers will potentially causes problems, due to incompatible CRT, debug symbol format, etc etc. With that said, what's the error from the linker?

Oh , I just found that the problem is actually that the linker ignore the lib files of DLL if "--static".

I tested mingw-w64, if I set "--static",it will link statically mostly and link agaist libs dynamically if they can't be link statically.
It seems like that llvm-mingw has defferent behavior about this.

@mstorsjo
Copy link
Owner

mstorsjo commented Oct 1, 2022

Llvm-mingw should be able to link against import libraries made by MSVC just fine. GCC based toolchains (that use binutils for linking) has had some problems with that earlier, but it should work better with recent releases (and there are some fixes that will be part of the next release too).

Mixing toolchains at this level is supposed to work - but if the libraries use different CRTs, and share CRT objects (FILE* etc) across DLL boundaries (or allocate memory with CRT routines in one DLL, and free it in another), or will break.

Mixing static libraries between MSVC and mingw is not supported in general (neither with GCC/binutils based toolchains not with LLVM based ones). It might work by pure luck in some cases, but it can’t be relied upon.

@mstorsjo
Copy link
Owner

mstorsjo commented Oct 1, 2022

Just to be clear, I've never seen a case where someone would do that. Mixing libraries made by 2 different compilers will potentially causes problems, due to incompatible CRT, debug symbol format, etc etc. With that said, what's the error from the linker?

Oh , I just found that the problem is actually that the linker ignore the lib files of DLL if "--static".

I tested mingw-w64, if I set "--static",it will link statically mostly and link agaist libs dynamically if they can't be link statically. It seems like that llvm-mingw has defferent behavior about this.

To be able to reproduce this issue, you need to tell more exactly what your files are named and exactly what command you execute which behaves differently.

@kkqy
Copy link
Author

kkqy commented Oct 1, 2022

Just to be clear, I've never seen a case where someone would do that. Mixing libraries made by 2 different compilers will potentially causes problems, due to incompatible CRT, debug symbol format, etc etc. With that said, what's the error from the linker?

Oh , I just found that the problem is actually that the linker ignore the lib files of DLL if "--static".
I tested mingw-w64, if I set "--static",it will link statically mostly and link agaist libs dynamically if they can't be link statically. It seems like that llvm-mingw has defferent behavior about this.

To be able to reproduce this issue, you need to tell more exactly what your files are named and exactly what command you execute which behaves differently.

I am sorry for that.
I know the defferent ABI of defferent toolchain ,but my situation is complex.
because my project use Golang mainly instead of C/C++,
BUT some packages use CGO to link with libraries built by MSVC (I don't have the source of thoese libraries) ,
BUT CGO of Golang only supports GCC-like compiler including LLVM/Clang,
BUT linker of CGO links statically.
so I just described simplely at that time.

The linker of CGO runs the command blow:
"clang++" "-m64" "-mconsole" "-Wl,--tsaware" "-Wl,--nxcompat" "-Wl,--major-os-version=6" "-Wl,--minor-os-version=1" "-Wl,--major-subsystem-version=6" "-Wl,--minor-subsystem-version=1" "-Wl,--dynamicbase" "-Wl,--high-entropy-va" "-o" "C:\\Users\\User\\AppData\\Local\\Temp\\go-build2201061765\\b001\\exe\\a.out.exe" "-Qunused-arguments" "C:\\Users\\User\\AppData\\Local\\Temp\\go-link-4058251765\\go.o" "C:\\Users\\User\\AppData\\Local\\Temp\\go-link-4058251765\\000000.o" "C:\\Users\\User\\AppData\\Local\\Temp\\go-link-4058251765\\000001.o" "C:\\Users\\User\\AppData\\Local\\Temp\\go-link-4058251765\\000002.o" "C:\\Users\\User\\AppData\\Local\\Temp\\go-link-4058251765\\000003.o" "C:\\Users\\User\\AppData\\Local\\Temp\\go-link-4058251765\\000004.o" "C:\\Users\\User\\AppData\\Local\\Temp\\go-link-4058251765\\000005.o" "C:\\Users\\User\\AppData\\Local\\Temp\\go-link-4058251765\\000006.o" "C:\\Users\\User\\AppData\\Local\\Temp\\go-link-4058251765\\000007.o" "C:\\Users\\User\\AppData\\Local\\Temp\\go-link-4058251765\\000008.o" "C:\\Users\\User\\AppData\\Local\\Temp\\go-link-4058251765\\000009.o" "C:\\Users\\User\\AppData\\Local\\Temp\\go-link-4058251765\\000010.o" "C:\\Users\\User\\AppData\\Local\\Temp\\go-link-4058251765\\000011.o" "C:\\Users\\User\\AppData\\Local\\Temp\\go-link-4058251765\\000012.o" "C:\\Users\\User\\AppData\\Local\\Temp\\go-link-4058251765\\000013.o" "C:\\Users\\User\\AppData\\Local\\Temp\\go-link-4058251765\\000014.o" "C:\\Users\\User\\AppData\\Local\\Temp\\go-link-4058251765\\000015.o" "C:\\Users\\User\\AppData\\Local\\Temp\\go-link-4058251765\\000016.o" "C:\\Users\\User\\AppData\\Local\\Temp\\go-link-4058251765\\000017.o" "C:\\Users\\User\\AppData\\Local\\Temp\\go-link-4058251765\\000018.o" "C:\\Users\\User\\AppData\\Local\\Temp\\go-link-4058251765\\000019.o" "C:\\Users\\User\\AppData\\Local\\Temp\\go-link-4058251765\\000020.o" "C:\\Users\\User\\AppData\\Local\\Temp\\go-link-4058251765\\000021.o" "C:\\Users\\User\\AppData\\Local\\Temp\\go-link-4058251765\\000022.o" "C:\\Users\\User\\AppData\\Local\\Temp\\go-link-4058251765\\000023.o" "-g" "-O2" "-static" "-lmd" "-ltrader" "-LD:/Libs/windows/x64" "-g" "-O2" "-g" "-O2" "-Wl,--start-group" "-lmingwex" "-lmingw32" "-Wl,--end-group" "-lkernel32"

and reports error below:

D:\data\project\go\pkg\tool\windows_amd64\link.exe: running clang++ failed: exit status 1
lld: error: unable to find library -lmd
lld: error: unable to find library -ltrader
clang-15: error: linker command failed with exit code 1 (use -v to see invocation)

md.lib and trader.lib are placed in D:\Libs\windows\x64 .

I remove the "--static" flag and then it works well.
llvm-mingw has defferent behavior from original MinGW about this:
if "--static" set:

  1. Original MinGW would link statically mostly and allow dynamical library too;
  2. LLVM-MinGW would link statically only but refuse all lib files of dynamical libraries.

if "--static" not set:

  1. Original MinGW will link dynamically such as stdc++ and other runtime.
  2. LLVM-MinGW would link statically mostly and allow dynamical library too.

This issue is sovled , but if I need support the two compilers , I have to set defferent flags of linker.

@kkqy kkqy closed this as completed Oct 1, 2022
@longnguyen2004
Copy link
Contributor

Sounds like cgo needs to fix that then, anyway glad that your problem is solved.

@mstorsjo
Copy link
Owner

mstorsjo commented Oct 11, 2022

I observed that GNU ld indeed does look for <libname>.lib (for -l<libname>) even if -static was specified, and dug through the ld sources to figure out why it does that. I posted https://reviews.llvm.org/D135651 with a patch to lld to make it match this behaviour.

I think it'd be good to reopen this bug until this is fixed in a release, but with modified issue subject.

@mstorsjo mstorsjo reopened this Oct 11, 2022
@mstorsjo mstorsjo changed the title Can't link with lib files made by MSVC? Can't link with lib files made by MSVC with -static Oct 11, 2022
@mstorsjo
Copy link
Owner

(Sorry, I posted the wrong review url above; I edited the comment above. The correct one is https://reviews.llvm.org/D135651.)

@mstorsjo
Copy link
Owner

Reopening this again, until the fix is released.

@mstorsjo
Copy link
Owner

The fix for this issue is now available as the prerelease with LLVM 16.0.0 RC 1 is available: https://github.com/mstorsjo/llvm-mingw/releases/tag/20230130

veselypeta pushed a commit to veselypeta/cherillvm that referenced this issue May 28, 2024
This matches how ld.bfd works in practice; this fixes
mstorsjo/llvm-mingw#305.

Adding a test for the new lib name combination that this allows, but
also adding a few negative tests for combinations that aren't
matched when -static is specified (because this change in itself
didn't break any of the existing tests either).

The logic in how ld.bfd looks for various libraries based on
an -l<libname> argument is rather complex; the
ldemul_open_dynamic_archive function looks for various combinations:
https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=ld/emultempl/pep.em;h=e68d1e69f17ad73af065b6bed19ae89ded913172;hb=b51c2fec1da205ea3e7354cbb3e253018d64873c#l2066
This function is only called if looking for dynamic libraries
(i.e. if -static wasn't specified):
https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=ld/ldfile.c;h=731ae5f7aedcf921bd36a1b32a3e0f5bfa189071;hb=b51c2fec1da205ea3e7354cbb3e253018d64873c#l365

However even this function is skipped, it still looks for libraries
in the form of "lib<libname>.a" (this is what lld did before):
https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=ld/ldfile.c;h=731ae5f7aedcf921bd36a1b32a3e0f5bfa189071;hb=b51c2fec1da205ea3e7354cbb3e253018d64873c#l440
But it also calls a format specific function called
ldemul_find_potential_libraries, which for PE targets looks for
files named "<libname>.lib":
https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=ld/emultempl/pep.em;h=e68d1e69f17ad73af065b6bed19ae89ded913172;hb=b51c2fec1da205ea3e7354cbb3e253018d64873c#l2175

Differential Revision: https://reviews.llvm.org/D135651
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants