marzer / tomlplusplus

Header-only TOML config file parser and serializer for C++17.
https://marzer.github.io/tomlplusplus/
MIT License
1.47k stars 141 forks source link

Failed to compile with clang/libc++ using shared lib mode #226

Closed memchr closed 1 month ago

memchr commented 1 month ago

Environment

toml++ version and/or commit hash: 3.4.0

Compiler: clang 17

C++ standard mode: 17, 20, 23

Target arch: x64

Library configuration overrides: -DTOML_HEADER_ONLY=0 -DTOML_SHARED_LIB=1

Relevant compilation flags: -stdlib=libc++

Describe the bug

In shared library mode, Clang failed to compile C++ code using tomlplusplus with libc++. Undefined reference errors such as undefined reference totoml::v3::ex::parse_file' are reported.

Steps to reproduce (or a small repro code sample)

To reproduce this, use the following command

echo -e "#include <toml++/toml.hpp>\nint main(int, char** argv) {auto tbl=toml::parse_file(argv[1]);}" | clang++ -x c++ -DTOML_HEADER_ONLY=0 -DTOML_SHARED_LIB=1 -ltomlplusplus -stdlib=libc++ -std=c++23 -

Additional information

It also fails regardless of the combination of linkers (lld, ld, gold, mold), the c++ standards (c++17, c++20, c++23) or whether the -fexperimental-library flag is used.

Using clang with libc++ instead of GNU stdlibc++ may be necessary on latest C++ standards due to some conflicts between clang and stdlibc++ on some standard library features.

marzer commented 1 month ago

How are you compiling the shared lib? Presumably you are using a build system? The shared lib instrumentation assumes this is the case.

memchr commented 1 month ago

How are you compiling the shared lib

The shared lib is provided by the operating system repo (Arch). It was built with meson

marzer commented 1 month ago

Was the system-provided lib compiled with libc++ too?

marzer commented 1 month ago

Probably worth pointing out that toml++'s CI uses the lib in shared mode for it's linux runners:

[7/52] Linking target src/libtomlplusplus.so.3.4.0

Methinks this is not a bug in the library, but something about the way that distro packages it, and/or your build system. Have you tried using the header-only mode directly?

memchr commented 1 month ago

Was the system-provided lib compiled with libc++ too?

No,

Methinks this is not a bug in the library,

I think you are right. There could be some conflict with the libc++ compiled project link against the libstdc++ compiled tomlplusplus shared library.

I'm probably better off making a special case for clang/libc++ to compile the project with tomlplusplus in headers-only mode. Thanks for the help!

marzer commented 1 month ago

There could be some conflict with the libc++ compiled project link against the libstdc++ compiled tomlplusplus shared library.

Yes, that's absolutely the case. You're getting link errors because the two standard library implementations (rightly) use inline namespaces internally to safeguard against this sort of ABI mixing. Even if it did link, it wouldn't work - you'd get all sorts of catastropic bugs at runtime, because their internal implementations are different.

I'm probably better off making a special case for clang/libc++

Yeah, looks like that's your only option here, unfortunately 😅

Thanks for the help!

No worries :)