1

I'm debugging a build that links against JsonCpp and I get a linker error where the demangled name it's trying to link to is _ZNK4Json6Reader25getFormattedErrorMessagesB5cxx11Ev and the one the library provides is _ZNK4Json6Reader25getFormattedErrorMessagesEv. There's an extra code in the mangled name (B5cxx11) that the compiler added for some reason. How do I tell the compiler not to mangle in this C++ 11 flag?

This is the code around where the symbol is needed:

Json::Reader jreader;

if (jreader.parse(buffer.str(), value))
{
    ret = 0;
}
else
{
    ret = INPUT_PARSE_ERROR;
    std::cerr << jreader.getFormattedErrorMessages() << std::endl;
}

Environment: Ubuntu 20.04, GCC 9.3.0, CMake 3.16.3

Edit: I tried adding #define _GLIBCXX_USE_CXX11_ABI 0 to the top of the compilation unit and it makes this specific error go away, but causes a bunch of other linker failures.

John Stanford
  • 993
  • 1
  • 7
  • 18
  • 3
    The library is probably compiled against the old `std::string` ABI, Set the `_GLIBCXX_USE_CXX11_ABI` macro to zero to use the old one. See https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html. – user17732522 Mar 06 '22 at 23:22
  • 1
    Does this answer your question? [Converting std::\_\_cxx11::string to std::string](https://stackoverflow.com/questions/33394934/converting-std-cxx11string-to-stdstring) – user17732522 Mar 06 '22 at 23:24
  • Just removing the `B5cxx11` part from the mangled name will not do you any good. It is there to make sure that you don't accidentally link two libraries with ABI mismatch. – user17732522 Mar 06 '22 at 23:26
  • 3
    There's a reason the compiler mangles symbols this way. A very good reason. The problem is not the different symbol, but the underlying reason for the different symbol: different ABIs, code compiled by different compiler versions. ABI compatibility issues don't get fixed simply by changing their mangled symbol names. – Sam Varshavchik Mar 06 '22 at 23:31
  • According to [this](https://chromium.googlesource.com/external/github.com/open-source-parsers/jsoncpp/+/refs/heads/0.y.z/README.md) "The recommended approach to integrating JsonCpp in your project is to include the amalgamated source (a single .cpp file and two .h files) in your project, and compile and build as you would any other source file. This ensures consistency of compilation flags and ABI compatibility", and there's a link there to help you do that. – Paul Sanders Mar 06 '22 at 23:35
  • Also on that page, it says: "1.y.z is built with C++11. 0.y.z can be used with older compilers." So you must have a very old version of the library there, where did you get it from? – Paul Sanders Mar 07 '22 at 00:10
  • It came as a package in a build I got that is supposed to be self-contained, but it's got a lot of complicated environmental dependencies I'm trying to troubleshoot. It's not from the official repos. The comments in the code say it's from 2011, so that's probably the problem. I'll probably have to just pull in the JsonCpp source code and recompile. – John Stanford Mar 07 '22 at 00:53
  • I suggest to compile all of your code in the same version of gcc if possible. Use `_GLIBCXX_USE_CXX11_ABI=0` if and only if you're out of luck to get the source code of your library. Most of time you need to create a shared library to bridge between two different `std::string` implementation. Since you won't like all codes compile against `_GLIBCXX_USE_CXX11_ABI=0` – Louis Go Mar 07 '22 at 01:36
  • Related [post](https://stackoverflow.com/q/45417707/4123703) – Louis Go Mar 07 '22 at 02:49

1 Answers1

0

I think the solution is a combination of what Sam Varshavchik and Paul Sanders said. It sounds like what I was trying to do isn't meant to be done and it's better to just include the JsonCpp source in your build, so that's what I did.

John Stanford
  • 993
  • 1
  • 7
  • 18