odygrd / quill

Asynchronous Low Latency C++ Logging Library
MIT License
1.14k stars 130 forks source link

Linkage problem when linking to shared library defining a custom formatter #472

Closed TillAlex closed 1 month ago

TillAlex commented 1 month ago

I have a library implementing a custom formatter deriving from fmtquill::formatter. When building this library and statically linking to it everything is ok, but when linking to the static library I get a linker error complaining about an

undefined reference to `void fmtquill::v10::detail::vformat_to(fmtquill::v10::detail::buffer&, fmtquill::v10::basic_string_view, fmtquill::v10::detail::vformat_args::type, fmtquill::v10::detail::locale_ref)'

Does anyone have an idea what I am doing wrong?

odygrd commented 1 month ago

It can be related to the symbol not exported for the shared library from libfmt header only version.

Would it be possible to submit an example so it's easier to investigate ?

What OS are you using ?

TillAlex commented 1 month ago

In this case I am using Ubuntu 22.04. I will try to submit a minimal reproducer as soon as possible.

TillAlex commented 1 month ago

Unfortunately I was not able to generate a minimal reproducer.

However, while playing around with my code I figured out that adding user_quill_codec.h from the quill examples makes my formatter link correctly. Digging deeper into this showed that including "quill/std/Array.h" was the main difference between the two formatters. Looking through the includes of Array.h in the end I found that I had to include "quill/bundled/fmt/format.h" in my formatter file to make it link correctly.

I do not really understand why it compiles without that include, but does not link.

odygrd commented 1 month ago

After version 4, Quill includes only core.h from fmt by default, not format.h, to minimize includes. It also uses the header-only version of libfmt.

The following line has been removed in the internal Quill libfmt, which I believe is causing the issue. While the header-only libfmt includes format.h by default, Quill does not:

https://github.com/fmtlib/fmt/blob/e69e5f977d458f2650bb346dadf2ad30c5320281/include/fmt/core.h#L2967

I suspect libfmt does not expect the header-only version to be used without format.h, resulting in the symbol not being exported for the shared library. Since format.h is not needed for logging built-in types, I prefer to avoid including it every time.

To resolve this, please always include format.h explicitly when using a user-defined formatter.

TillAlex commented 1 month ago

Ok, problem solved. Thanks for your help and for all your work here again!