23

We received some libraries (.a) compiled for linux (probably compiled with GCC 6.x).

We are using GCC 4.8 and we are getting the error of the type: undefined reference to std::__cxx11::basic_string when trying to link.

Normally this could be fixed by making sure all units have been compiled with the same _GLIBCXX_USE_CXX11_ABI flag. However if I understood correctly, this was introduced by GCC 5.1 and on.

  1. Is there a way to make this work with GCC 4.8 or do we need to ask the people to recompile the libraries with a different _GLIBCXX_USE_CXX11_ABI?
  2. I guess if we are able to switch to GCC >= 5.1 we can make this work?

Thanks!

jww
  • 97,681
  • 90
  • 411
  • 885
Tanasis
  • 795
  • 1
  • 9
  • 21
  • 2
    Also see [GCC5 and the C++11 ABI](https://developers.redhat.com/blog/2015/02/05/gcc5-and-the-c11-abi/) on the Red Hat blogs, the [Dual ABI](https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html) in the GCC manual and [Linking problems due to symbols with abi::cxx11?](https://stackoverflow.com/q/36159238/608639) on Stack overflow. That caused us a lot of problems, especially when Clang was not GCC5/C++11 aware. This looks like your dup, but it has no answers: [How should I handle ABI incompatibility between gcc-4.9 and gcc-5?](https://stackoverflow.com/q/37145066/608639) – jww Jul 31 '17 at 20:09

1 Answers1

16

It's possible to use the C++11 ABI with gcc 4.8.2, but it's a dangerous hack; you would be far better off if at all possible to ask your vendors to ship libraries compiled with the C++03 ABI (-D_GLIBCXX_USE_CXX11_ABI=0) or to upgrade to GCC 5 or above.

You would need to download and install gcc 5 so that you can use its libstdc++ headers and libraries, then direct gcc 4.8 to use those in preference to its own. In addition, because gcc 4.8 is missing some intrinsics required by the libstdc++ shipped with gcc 5, you would need to hack out their usage.

For example, to compile a simple single-file application that includes <string>:

/usr/local/gcc-4.8.2/bin/g++ \
   -std=c++11 \
   -D_GLIBCXX_USE_CXX11_ABI=1 \
   -D'__is_trivially_copyable(...)=0' \
   -D'__is_trivially_constructible(...)=0' \
   -D'__is_trivially_assignable(...)=0' \
   -nostdinc++ \
   -isystem /usr/local/gcc-5.4.0/include/c++/5.4.0/ \
   -isystem /usr/local/gcc-5.4.0/include/c++/5.4.0/x86_64-unknown-linux-gnu \
   -L /usr/local/gcc-5.4.0/lib64
   a.cpp

This is dangerous because the gcc 5.4 libstdc++ is not designed to work with gcc 4.8, and redefining the intrinsics used (__is_trivially_copyable etc.) could change the layout of structures or otherwise cause binary incompatibility between your programs and the vendor's libraries.

In order to run the resulting executable, you would also need to ensure that the dynamic linker finds a compatible libstdc++, for example by adding /usr/local/gcc-5.4.0/lib64 to /etc/ld.so.conf, or using -Wl,-rpath /usr/local/gcc-5.4.0/lib64.

ecatmur
  • 152,476
  • 27
  • 293
  • 366
  • May make sense to add `-Wl,-rpath` too. – yugr Jul 31 '17 at 16:10
  • Wow this is scary (and cool) stuff! Better minimize risk and follow the safe path and ask for a recompile. – Tanasis Aug 03 '17 at 08:10
  • when upgrading gcc, does it mean we MUST update kernel too ? I see that the new toolchain for the newer gcc requires a newer kernel header ? Does it mean we must update kernel ? – ransh Dec 27 '18 at 12:38
  • @ransh no. GCC should not require newer kernel headers, it should work with whatever kernel headers are present when you build it. I don't know where you see "that the new toolchain for the newer gcc requires a newer kernel header". – Jonathan Wakely Mar 02 '20 at 12:07