SOCI / soci

Official repository of the SOCI - The C++ Database Access Library
http://soci.sourceforge.net/
Boost Software License 1.0
1.41k stars 477 forks source link

Static linking error on Windows #1018

Closed Tectu closed 1 year ago

Tectu commented 1 year ago

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:

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?

Tectu commented 1 year ago

I had another quick go at this but still couldn't find the underlying issue. Any ideas?

vadz commented 1 year ago

Do you define SOCI_DLL when building your project?

Tectu commented 1 year ago

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?

vadz commented 1 year ago

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.

Tectu commented 1 year ago

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!

vadz commented 1 year ago

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...

Tectu commented 1 year ago

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?".

vadz commented 1 year ago

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.

Tectu commented 1 year ago

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!