8

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).

Bruce Adams
  • 4,953
  • 4
  • 48
  • 111
  • I didn't answered the question but having solved my problem the answer is no longer important to me. This question can be closed. – Bruce Adams Jan 13 '16 at 11:56
  • 1
    libstdc++ is forward compatible, I'm not even sure they follow any form of semantic versioning. I bet that if you linked with 6.0.19 and ran the resulting code with 6.0.20, it would work just fine. – rubenvb Jan 13 '16 at 12:14
  • While its intended to be true. You can still have problems. I broke some (internal) programs using a later version of the library that were bug incompatible in some subtle manner. I wouldn't want to risk breaking a system program that way as it would be very hard to debug. See also http://stackoverflow.com/questions/25979778/forcing-or-preventing-use-of-a-particular-minor-version-of-libstdc – Bruce Adams Jan 13 '16 at 15:25
  • I like living in my ideal bug-free world! – rubenvb Jan 13 '16 at 15:45
  • @BruceAdams you can delete the question yourself. – Ben Jan 14 '16 at 09:52
  • I can't see the option for it. Perhaps my reputation is too low? But in any case its been upvoted a few times so possibly other people are curious. – Bruce Adams Jan 14 '16 at 10:27

1 Answers1

7

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
Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521
  • 1
    That's almost right but for me using gcc 4.9.3 or RHEL7 native 4.8 the macro to use seems to be _GLIBCXX_ABI_TAG_CXX11 or _CXXABI_FORCED_H: ` >echo "#include " | g++ -x c++ -E -dM - | grep ABI #define _CXXABI_FORCED_H 1 #define __GXX_ABI_VERSION 1002 #define _GLIBCXX_ABI_TAG_CXX11 __attribute ((__abi_tag__ ("cxx11"))) ` gcc6 on the other hand also adds: ` #define _GLIBCXX_USE_DUAL_ABI 1 #define _GLIBCXX_USE_CXX11_ABI 1 ` – Bruce Adams Jul 22 '16 at 10:56
  • No, those are completely different macros. Neither GCC 4.9.3 nor 4.8 supports the [Dual ABI](https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html) introduced with GCC 5.1, so they are **always** equivalent to `_GLIBCXX_USE_CXX11_ABI=0` – Jonathan Wakely Jul 22 '16 at 10:59
  • If you're using RHEL you should look at the [devtoolset](https://access.redhat.com/documentation/en/red-hat-developer-toolset/) which gives you an up-to-date GCC that produces binaries that only depend on the host libstdc++ (and which also matches the system defaults in terms of `std::string` ABI) – Jonathan Wakely Jul 22 '16 at 11:02
  • Trouble with mini-markdown there... devtoolset is not available on RHEL5 which I still have to support despite its age. Also it isn't quite as bleeding edge as I desire. I'm still waiting for a version of gcc that supports [http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0305r0.html P0305] (if initialisers) for example and I will pounce on a new stable version of gcc that supports it as soon as I can. – Bruce Adams Jul 22 '16 at 11:12
  • Yup, that might not be supported until gcc-7, which will be in devtoolset-7 some time in 2017. – Jonathan Wakely Jul 22 '16 at 11:17