Static linking error on Windows
Tectu opened this issue · 9 comments
I recently switched from linking SOCI dynamically to linking it statically.
On FreeBSD everything works like a charm. However, I just fired up the test builds on WIndows (under MSYS2) And I am getting the following link time error:
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\msys64\tmp\ccMVg5XN.ltrans1.ltrans.o::(.text+0x472b): undefined reference to `soci::details::parse_std_tm(char const*, tm&)'
This is with:
- SOCI commit 074722a (second last commit on
master
branch) - GCC 12.2.0
- CMake 3.24.2
- Compiling under MSYS2
- My application uses C++20 (shouldn't be relevant but just for completion)
I'm linking to both Soci::core_static
and Soci::sqlite3_static
.
I'm observing the same problem no matter the values of SOCI_VISIBILITY
and SOCI_LTO
(the former shouldn't matter anyway).
Any ideas what I'm missing?
I had another quick go at this but still couldn't find the underlying issue. Any ideas?
Do you define SOCI_DLL
when building your project?
Thank you for your response.
SOCI_DLL
was not defined. For testing purposes I did define SOCI_DLL
and performed a clean built. This results in way more linking errors.
It would also seem like SOCI_DLL
would not be needed when building static libraries anyway. It only seems to have an effect regarding shared library import/exports.
Any other ideas or hints?
Ah, wait, could it be just the usual static linking library order problem? You need to put the core library after all the backend libraries when linking statically.
That was spot on! After ensuring that the core gets linked after the backends everything works as expected :)
Why exactly is this a thing? What underlying mechanism is at play here?
Thanks for your help - once again!
This is just a property of classic Unix linkers, they resolve dependencies in left to right order, i.e. when you link with -lA -lB -lC
, only symbols used by libA will be taken from libB, and anything used by libC won't be -- because by the time libB is processed they're not used yet and the linker never goes back to look for them later.
This is the way linking has worked on Unix since always and probably will remain working for as long as the concept of linking still exists...
This part I get. What I am curious about is why these symptoms didn't show up under FreeBSD/Clang but do show up under Windows/MinGW :D
I should probably have worded my question different than "Why is this a thing?".
I don't know enough about FreeBSD to answer this, but normally you should have had the same problem there if the link order was the same. You definitely should have it under Linux.
Yeah this is curious. I inspected the resulting FreeBSD binaries and SOCI was linked statically. moreover, the resulting binary ran fine on a foreign system where SOCI libs are definitely not present in any form.
If I happen to have some spare time I'll dive into this, it's really curious.
Of course, this is nothing related to SOCI anymore so I'll stop wasting your time now. Thanks again - much appreciated!