Discussion:
C++ binary compatibility between different versions of gcc
H***@uniserv.com
2013-03-04 16:48:06 UTC
Permalink
Hi,

after reading a whole lot of stuff about binary compatibility of gcc and searching the gcc-help archive, too, I am still somewhat confused regarding the C++ binary compatibility between different versions of gcc.

The questions I am trying to answer are these:

1.) My impression is that the whole question of binary compatibility boils down to or is rather a synonym for C++ ABI compatibility (or stability if narrowed down to the question of the binary compatibility of binaries produced by different versions of gcc). Is this correct?

2.) [1] states that starting with GCC 3.2, there is a default C++ ABI (the vendor-neutral C++ ABI) that GCC tries to adhere to. However, there is not a hint of which versions did or did not, or with which versions of GCC an incompatible change of the ABI has happened. [3] indicates then that "It's pretty easy to see when the ABI has changed because we bump the major release number in the soname." of libstdc++.so and as one can figure out looking at [2], this has not happened since libstdc++.so.6.0.0, which came with GCC 3.4.0. From that, I am willing to draw the conclusion that the compiler ABI has been stable since then. Is this correct and is it therefore save to say that a library compiled with GCC 3.4.x can be linked against (dynamically or statically) with GCC 4.y.z, if we assume that all ABI-affecting compiler flags have been the same (esp. -fabi-version=2)? Does the reverse hold, too?

I hope someone can clarify this for me.

Best regards,

Heiko

[1] GCC manual, ch. 9, "Binary Compatibility", http://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Compatibility.html#Compatibility
[2] libstdc++ manual, Appendix B., "ABI Policy and Guidelines", http://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html
[3] gcc-help, "Re: supporting multiple versions of GCC with a single shared object release?", http://gcc.gnu.org/ml/gcc-help/2009-04/msg00199.html
Jonathan Wakely
2013-03-04 18:00:44 UTC
Permalink
Post by H***@uniserv.com
Hi,
after reading a whole lot of stuff about binary compatibility of gcc and searching the gcc-help archive, too, I am still somewhat confused regarding the C++ binary compatibility between different versions of gcc.
1.) My impression is that the whole question of binary compatibility boils down to or is rather a synonym for C++ ABI compatibility (or stability if narrowed down to the question of the binary compatibility of binaries produced by different versions of gcc). Is this correct?
Yes.

There are two parts to that: the platform ABI that the compiler uses
and the ABI of any libraries you use, see
http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C++
for more details. For example, you could add a virtual function to a
library type, which would change the library's ABI even if compiled
with same compiler release.
Post by H***@uniserv.com
2.) [1] states that starting with GCC 3.2, there is a default C++ ABI (the vendor-neutral C++ ABI) that GCC tries to adhere to. However, there is not a hint of which versions did or did not, or with which versions of GCC an incompatible change of the ABI has happened.
The manual for each version tells you the default value for -fabi-version
Post by H***@uniserv.com
[3] indicates then that "It's pretty easy to see when the ABI has changed because we bump the major release number in the soname." of libstdc++.so and as one can figure out looking at [2], this has not happened since libstdc++.so.6.0.0, which came with GCC 3.4.0. From that, I am willing to draw the conclusion that the compiler ABI has been stable since then. Is this correct and is it therefore save to say that a library compiled with GCC 3.4.x can be linked against (dynamically or statically) with GCC 4.y.z, if we assume that all ABI-affecting compiler flags have been the same (esp. -fabi-version=2)?
Yes. (Technically if the object files were compiled with
ABI-compatible GCC versions then what matters at link-time is not
which version of GCC you use to do the link, it's which version of
libstdc++.so you link against, but that is usually determined by the
version of GCC used, unless you specifically force GCC to link to a
different libstdc++.so)
Post by H***@uniserv.com
Does the reverse hold, too?
What is the reverse case? If you are asking whether a library
compiled with GCC 4.x can be linked against using GCC 3.4 the answer
is no, libstdc++.so ABI compatibility only goes backwards, not
forwards.

If any object in your program (or any object in any library it links
to) was compiled with GCC version X then at run-time the program must
be linked to the libstdc++.so from GCC X or later. You cannot compile
with GCC X then use libstdc++.so from GCC X-1 at run-time.
H***@uniserv.com
2013-03-05 10:39:15 UTC
Permalink
Hi Jonathan,

thanks for the definitive answers.
Post by Jonathan Wakely
Post by H***@uniserv.com
2.) [1] states that starting with GCC 3.2, there is a default C++ ABI (the
vendor-neutral C++ ABI) that GCC tries to adhere to. However, there is not
a hint of which versions did or did not, or with which versions of GCC an
incompatible change of the ABI has happened.
The manual for each version tells you the default value for -fabi-version
I noticed that but being confused with the library ABI issue and by some
posts on the internet that seemed to indicate otherwise, I did not
trust it as much as I should have.
Post by Jonathan Wakely
Post by H***@uniserv.com
[3] indicates then that "It's pretty easy to see when the ABI has changed
because we bump the major release number in the soname." of libstdc++.so
and as one can figure out looking at [2], this has not happened since
libstdc++.so.6.0.0, which came with GCC 3.4.0. From that, I am willing to
draw the conclusion that the compiler ABI has been stable since then. Is
this correct and is it therefore save to say that a library compiled with
GCC 3.4.x can be linked against (dynamically or statically) with GCC
4.y.z, if we assume that all ABI-affecting compiler flags have been the
same (esp. -fabi-version=2)?
Yes. (Technically if the object files were compiled with
ABI-compatible GCC versions then what matters at link-time is not
which version of GCC you use to do the link, it's which version of
libstdc++.so you link against, but that is usually determined by the
version of GCC used, unless you specifically force GCC to link to a
different libstdc++.so)
Does this mean that it would be possible to link with any GCC that
supports -fabi-version=2 against any libstdc++.so.6.x.y?
Post by Jonathan Wakely
Post by H***@uniserv.com
Does the reverse hold, too?
What is the reverse case? If you are asking whether a library
compiled with GCC 4.x can be linked against using GCC 3.4 the answer
is no, libstdc++.so ABI compatibility only goes backwards, not
forwards.
If any object in your program (or any object in any library it links
to) was compiled with GCC version X then at run-time the program must
be linked to the libstdc++.so from GCC X or later. You cannot compile
with GCC X then use libstdc++.so from GCC X-1 at run-time.
That was the question, yeah.

Another question comes to my mind here: Let's assume I have two object files
or libraries that have been compiled separately and were compiled with
different versions of GCC thus needing different versions of libstdc++.so
at run-time. Do I read [2], "Multiple ABI Testing", correctly that I should
be able to compile and run a program which uses both libraries provided that
the most current libstdc++.so that any library depends on is present at
run-time?

Heiko
Jonathan Wakely
2013-03-05 11:26:39 UTC
Permalink
Post by H***@uniserv.com
Hi Jonathan,
thanks for the definitive answers.
Post by Jonathan Wakely
Yes. (Technically if the object files were compiled with
ABI-compatible GCC versions then what matters at link-time is not
which version of GCC you use to do the link, it's which version of
libstdc++.so you link against, but that is usually determined by the
version of GCC used, unless you specifically force GCC to link to a
different libstdc++.so)
Does this mean that it would be possible to link with any GCC that
supports -fabi-version=2 against any libstdc++.so.6.x.y?
I'm not sure I understand what you're asking.

GCC doesn't do linking, it just forwards arguments to the linker. The
-fabi-version option is not used at link-time, that only affects
code-generation at compile-time. So in theory you can use *any* gcc
driver to link compatible objects together if you explicitly say which
libstdc++.so to use, because the list of objects and libraries will be
forwarded to the linker, but just using the g++ driver that matches
that libstdc++.so is by far the simplest approach.

Also, you can't link against *any* libstdc++.so.6.x.y, you must link
against a version that is no older than required by any of your
objects. If your program consists of three objects and you compile
foo.o and bar.o with GCC 4.1.2 and baz.o with GCC 4.6.3 then you must
link your program to libstdc++.6.0.16 or later, because baz.o will
depend on the GLIBCXX_3.4.16 version that is only found in
libstdc++.so.6.0.16 and later.

If that doesn't answer your question please be more specific,
providing a concrete example with commands showing what you're asking
about.
Post by H***@uniserv.com
Another question comes to my mind here: Let's assume I have two object files
or libraries that have been compiled separately and were compiled with
different versions of GCC thus needing different versions of libstdc++.so
at run-time. Do I read [2], "Multiple ABI Testing", correctly that I should
be able to compile and run a program which uses both libraries provided that
the most current libstdc++.so that any library depends on is present at
run-time?
The "Multiple ABI Testing" docs refer to using incompatible libraries,
e.g. libstdc++.so.5 and libstdc++.so.6, in the same process. It's hard
to get right, can only be done if no library types (or type_info or
exceptions or polymorphic types) cross library boundaries, and I'm not
sure those docs are 100% accurate. If you just want to link objects
compiled with GCC 4.X with objects compiled with GCC 4.Y then that
section of the docs is not relevant.
H***@uniserv.com
2013-03-05 12:37:51 UTC
Permalink
Post by Jonathan Wakely
Post by H***@uniserv.com
Does this mean that it would be possible to link with any GCC that
supports -fabi-version=2 against any libstdc++.so.6.x.y?
I'm not sure I understand what you're asking.
GCC doesn't do linking, it just forwards arguments to the linker. The
-fabi-version option is not used at link-time, that only affects
code-generation at compile-time. So in theory you can use *any* gcc
driver to link compatible objects together if you explicitly say which
libstdc++.so to use, because the list of objects and libraries will be
forwarded to the linker, but just using the g++ driver that matches
that libstdc++.so is by far the simplest approach.
Also, you can't link against *any* libstdc++.so.6.x.y, you must link
against a version that is no older than required by any of your
objects. If your program consists of three objects and you compile
foo.o and bar.o with GCC 4.1.2 and baz.o with GCC 4.6.3 then you must
link your program to libstdc++.6.0.16 or later, because baz.o will
depend on the GLIBCXX_3.4.16 version that is only found in
libstdc++.so.6.0.16 and later.
If that doesn't answer your question please be more specific,
providing a concrete example with commands showing what you're asking
about.
Despite my unclear wording that is what I wanted to know.
Post by Jonathan Wakely
Post by H***@uniserv.com
Another question comes to my mind here: Let's assume I have two object files
or libraries that have been compiled separately and were compiled with
different versions of GCC thus needing different versions of libstdc++.so
at run-time. Do I read [2], "Multiple ABI Testing", correctly that I should
be able to compile and run a program which uses both libraries provided that
the most current libstdc++.so that any library depends on is present at
run-time?
The "Multiple ABI Testing" docs refer to using incompatible libraries,
e.g. libstdc++.so.5 and libstdc++.so.6, in the same process. It's hard
to get right, can only be done if no library types (or type_info or
exceptions or polymorphic types) cross library boundaries, and I'm not
sure those docs are 100% accurate. If you just want to link objects
compiled with GCC 4.X with objects compiled with GCC 4.Y then that
section of the docs is not relevant.
Thanks for clarifying that for me!

Heiko

Continue reading on narkive:
Loading...