I'm looking to better understand the ABI compatibility of the compiled output from GCC for C++ code, from both a 'standard' Linux installation, but also that of the devtoolset software collection's available across CentOS/Fedora/RHEL.
I'd like to know if any linking/run-time issues would occur in the following scenarios (Given all are built using the same compiler flags):
1. Dynamically Linking
A dynamic library, A, is built using GCC version X, this is dynamically linked by a binary application compiled with GCC version Y.
a) What happens when GCC version Y is a higher version number than GCC version X?
b) What happens when GCC version Y is a lower version number than GCC version X?
2. Static Linking
A static library, A, is built using GCC version X, this is statically linked by a binary application compiled with GCC version Y.
a) What happens when GCC version Y is a higher version number than GCC version X?
b) What happens when GCC version Y is a lower version number than GCC version X?
Having read the GCC ABI Policy Guidelines, given their goal being stated as:
Extending existing, stable ABIs. Versioning gives subsequent releases of library binaries the ability to add new symbols and add functionality, all the while retaining compatibility with the previous releases in the series. Thus, program binaries linked with the initial release of a library binary will still run correctly if the library binary is replaced by carefully-managed subsequent library binaries. This is called forward compatibility.
The reverse (backwards compatibility) is not true. It is not possible to take program binaries linked with the latest version of a library binary in a release series (with additional symbols added), substitute in the initial release of the library binary, and remain link compatible.
From what I can tell the primary concern is around the ABI compatibility of libstdc++.so, meaning that so long as my two versions of GCC do not cross the barrier of noted incompatibility, everything should work.
In other words scenario 1.a) and 2.a) are always acceptable due to forward compatibility.
In scenarios 1.b) and 2.b) this isn't the case, this would only work when I don't cross a boundary of ABI compatibility on libstdc++.so. Meaning my understanding of validity would be:
Library-GCC Linking-GCC Valid?
GCC 3.4.0 GCC 3.3.1 X
GCC 4.7.0 GCC 3.4.0 ✓
GCC 4.7.0 GCC 9.4.0 ✓
RedHat's Software Collections
Following on from this, I would also like to understand the ABI compatibility between versions using the devtoolset software collection. Specifically looking at the devtoolset-8 developer documentation I can see some additional complexity around C++11, C++14 and C++17. I'm specifically interested in C++17.
Using the C++17 language version is experimental and possible in Red Hat Developer Toolset only when all C++ objects compiled with the respective flag have been built using the same major version of GCC. Because later major versions of Red Hat Developer Toolset may use a later major release of GCC, forward compatibility of objects, binary files, and libraries built with the -std=c++17 and -std=gnu++17 options cannot be guaranteed.
From the above quote, following the same scenarios listed above, if I were to compile everything using -std=c++17
, would the following table of linking/run-time compatibility be true for using devtoolset:
Devtoolset-8 Versions
Library Linking Valid?
8.0 8.1 ✓
8.1 8.0 ✓
8.1 9.0 X
Finally, given the following quote from the Red Hat documentation
Using the C++17 language version is experimental and possible in Red Hat Developer Toolset only when all C++ objects compiled with the respective flag have been built using the same major version of GCC.
Would this mean if I were to use devtoolset-8, compiling a binary with -std=c++17
, whilst trying to link against a library (statically or dynamically) either built outside of devtoolset-8, or within devtoolset-8 but without the -std=c++17
flag, this would potentially have linking/run-time issues?