Bruce Adams Bruce Adams - 4 months ago 27
Linux Question

How to probe the C++ ABI used by the system version of gcc on the target platform

I have a configuration probe that determines what flags to pass to g++ based on platform and version. I typically use a later version of gcc than the native install version in order to gain access to C++14 features.
On older platforms this means I need to add -D_GLIBCXX_USE_CXX11_ABI=0 to use the older C++ ABI or I cannot link with host versions of C++ libraries.
However some newer platforms do use the new ABI in which case -D_GLIBCXX_USE_CXX11_ABI=1 (or nothing at all) is required.

I can do this based on the version of the target platform (i.e. the output of lsb_release -a) but I would like a more general method.

I think I'm half way there with compiling a C++ hello world program with the native compiler (as opposed to my later one) but I can't quite figure out how to probe the ABI version.
E.g.


>strings hello | grep ABI
.note.ABI-tag
>strings hello | grep CXX
GLIBCXX_3.4


or similarly on the version of libstdc++ used by the hello probe program.


ldd ./hello | grep stdc++ | sed -e 's_.* /_/_' | cut -f 1 -d' ' |xargs strings | grep


Does anyone have any better suggestions?

update:
In fact I don't need to do this at all. My real problem was that I had an older version of libstdc++.so hanging around. Compilation picked up one version 6.0.20 and the runtime picked up an incompatible one 6.0.19 (or possibly visa versa). I had an unresolved symbol which I incorrectly blamed on the ABI version. Contrary to popular belief minor versions of libstdc++ aren't always binary compatible. My intention is always to use the exact same version at run and compile time (if not using the host native one).

Answer

Contrary to popular belief minor versions of libstdc++ aren't always binary compatible.

They aren't binary compatible in both directions. libstdc++.so.6.0.20 can be used when libstdc++.so.6.0.19 is required, but not the other way round.

However, prior to GCC 5 the C++11 support was still experimental (i.e. work in progress) and so the ABI of new C++11 components was not stable, so you can't mix C++11/C++14 code compiled with GCC 4.x and GCC 4.y, or GCC 4 and GCC 5. For C++98 code you can mix&match freely (just use the newer libstdc++.so because it's only compatible in one direction).

The details of the major C++11 incompatibilities prior to GCC 5 are documented at https://gcc.gnu.org/wiki/Cxx11AbiCompatibility

Anyway, to answer the now irrelevant question:

I think I'm half way there with compiling a C++ hello world program with the native compiler (as opposed to my later one) but I can't quite figure out how to probe the ABI version

If you can run the native compiler then I don't see what the problem is, just check the default value of the macro:

echo '#include <string>' | g++ -x c++ -E -dM - | fgrep _GLIBCXX_USE_CXX11_ABI