C++

C++ is what people most often think of when people say Linux binary incompatibility. This section looks at the problems.

The "ABI" is the set of rules used by compilers as they generate binary code from source code. The rules dictate things like how C++ classes are laid out in memory, and how C++ type signatures are converted into unique symbol names (mangling). There are 3 ABI versions in circulation on Linux. The first is the one generated by the GCC 2.95 series of compilers, this is sufficiently far in the past that we no longer need to care about it. The second is the GCC 3.2/3.3 ABI, and the third is the GCC 3.4/4.0 ABI.

The latter two ABIs are virtually identical: only bugfixes distinguish them. They both attempt to follow the Itanium C++ ABI specification, which is fully documented. Unfortunately the bug fixes are severe enough that the two ABIs cannot be mixed.

To "mix" ABIs means to take a binary that was imports one ABI, and link it against a library that exports another. Doing this will usually cause a crash or link failure. Theoretically, linking two C++ binaries indirectly (eg via a C library) is safe, but in practice due to an apparent bug in GCC this is not the case.

To tell a binary compiled with the GCC 3.2/3.3 ABI apart from a 3.4/4.0 ABI binary, look at which version of libstdc++.so it links against. Older binaries use .so.5, newer binaries use .so.6. According to the GCC documentation these two standard libraries can be mixed in the same ELF image, but unfortunately template inlines are given GLOBAL WEAK scope by GCC which can cause symbolic collisions (see earlier) so this is not in fact safe. You should only have one copy of libstdc++.so linked into a process at any one time, for maximum safety.