| <section xmlns="http://docbook.org/ns/docbook" version="5.0" |
| xml:id="appendix.porting.abi" xreflabel="abi"> |
| <?dbhtml filename="abi.html"?> |
| |
| <info><title>ABI Policy and Guidelines</title> |
| <keywordset> |
| <keyword>C++</keyword> |
| <keyword>ABI</keyword> |
| <keyword>version</keyword> |
| <keyword>dynamic</keyword> |
| <keyword>shared</keyword> |
| <keyword>compatibility</keyword> |
| </keywordset> |
| </info> |
| |
| |
| |
| <para> |
| </para> |
| |
| <section xml:id="abi.cxx_interface"><info><title>The C++ Interface</title></info> |
| |
| |
| <para> |
| C++ applications often depend on specific language support |
| routines, say for throwing exceptions, or catching exceptions, and |
| perhaps also depend on features in the C++ Standard Library. |
| </para> |
| |
| <para> |
| The C++ Standard Library has many include files, types defined in |
| those include files, specific named functions, and other |
| behavior. The text of these behaviors, as written in source include |
| files, is called the Application Programing Interface, or API. |
| </para> |
| |
| <para> |
| Furthermore, C++ source that is compiled into object files is |
| transformed by the compiler: it arranges objects with specific |
| alignment and in a particular layout, mangling names according to a |
| well-defined algorithm, has specific arrangements for the support of |
| virtual functions, etc. These details are defined as the compiler |
| Application Binary Interface, or ABI. From GCC version 3 onwards the |
| GNU C++ compiler uses an industry-standard C++ ABI, the |
| <link linkend="biblio.cxxabi">Itanium C++ ABI</link>. |
| </para> |
| |
| <para> |
| The GNU C++ compiler, g++, has a compiler command line option to |
| switch between various different C++ ABIs. This explicit version |
| switch is the flag <code>-fabi-version</code>. In addition, some |
| g++ command line options may change the ABI as a side-effect of |
| use. Such flags include <code>-fpack-struct</code> and |
| <code>-fno-exceptions</code>, but include others: see the complete |
| list in the GCC manual under the heading <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code%20Gen%20Options">Options |
| for Code Generation Conventions</link>. |
| </para> |
| |
| <para> |
| The configure options used when building a specific libstdc++ |
| version may also impact the resulting library ABI. The available |
| configure options, and their impact on the library ABI, are |
| documented |
| <link linkend="manual.intro.setup.configure">here</link>. |
| </para> |
| |
| <para> Putting all of these ideas together results in the C++ Standard |
| Library ABI, which is the compilation of a given library API by a |
| given compiler ABI. In a nutshell: |
| </para> |
| |
| <para> |
| <quote> |
| library API + compiler ABI = library ABI |
| </quote> |
| </para> |
| |
| <para> |
| The library ABI is mostly of interest for end-users who have |
| unresolved symbols and are linking dynamically to the C++ Standard |
| library, and who thus must be careful to compile their application |
| with a compiler that is compatible with the available C++ Standard |
| library binary. In this case, compatible is defined with the equation |
| above: given an application compiled with a given compiler ABI and |
| library API, it will work correctly with a Standard C++ Library |
| created with the same constraints. |
| </para> |
| |
| <para> |
| To use a specific version of the C++ ABI, one must use a |
| corresponding GNU C++ toolchain (i.e., g++ and libstdc++) that |
| implements the C++ ABI in question. |
| </para> |
| |
| </section> |
| |
| <section xml:id="abi.versioning"><info><title>Versioning</title></info> |
| |
| |
| <para> The C++ interface has evolved throughout the history of the GNU |
| C++ toolchain. With each release, various details have been changed so |
| as to give distinct versions to the C++ interface. |
| </para> |
| |
| <section xml:id="abi.versioning.goals"><info><title>Goals</title></info> |
| |
| |
| <para>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. |
| </para> |
| <para> |
| 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. |
| </para> |
| |
| <para>Allows multiple, incompatible ABIs to coexist at the same time. |
| </para> |
| </section> |
| |
| <section xml:id="abi.versioning.history"><info><title>History</title></info> |
| |
| |
| <para> |
| How can this complexity be managed? What does C++ versioning mean? |
| Because library and compiler changes often make binaries compiled |
| with one version of the GNU tools incompatible with binaries |
| compiled with other (either newer or older) versions of the same GNU |
| tools, specific techniques are used to make managing this complexity |
| easier. |
| </para> |
| |
| <para> |
| The following techniques are used: |
| </para> |
| |
| <orderedlist> |
| |
| <listitem><para>Release versioning on the libgcc_s.so binary. </para> |
| |
| <para>This is implemented via file names and the ELF |
| <constant>DT_SONAME</constant> mechanism (at least on ELF |
| systems). It is versioned as follows: |
| </para> |
| |
| <itemizedlist> |
| <listitem><para>GCC 3.x: libgcc_s.so.1</para></listitem> |
| <listitem><para>GCC 4.x: libgcc_s.so.1</para></listitem> |
| </itemizedlist> |
| |
| <para>For m68k-linux the versions differ as follows: </para> |
| |
| <itemizedlist> |
| <listitem><para>GCC 3.4, GCC 4.x: libgcc_s.so.1 |
| when configuring <code>--with-sjlj-exceptions</code>, or |
| libgcc_s.so.2 </para> </listitem> |
| </itemizedlist> |
| |
| <para>For hppa-linux the versions differ as follows: </para> |
| |
| <itemizedlist> |
| <listitem><para>GCC 3.4, GCC 4.[0-1]: either libgcc_s.so.1 |
| when configuring <code>--with-sjlj-exceptions</code>, or |
| libgcc_s.so.2 </para> </listitem> |
| <listitem><para>GCC 4.[2-7]: either libgcc_s.so.3 when configuring |
| <code>--with-sjlj-exceptions</code>) or libgcc_s.so.4 |
| </para> </listitem> |
| </itemizedlist> |
| |
| </listitem> |
| |
| <listitem><para>Symbol versioning on the libgcc_s.so binary.</para> |
| |
| <para>It is versioned with the following labels and version |
| definitions, where the version definition is the maximum for a |
| particular release. Labels are cumulative. If a particular release |
| is not listed, it has the same version labels as the preceding |
| release.</para> |
| |
| <para>This corresponds to the mapfile: gcc/libgcc-std.ver</para> |
| <itemizedlist> |
| <listitem><para>GCC 3.0.0: GCC_3.0</para></listitem> |
| <listitem><para>GCC 3.3.0: GCC_3.3</para></listitem> |
| <listitem><para>GCC 3.3.1: GCC_3.3.1</para></listitem> |
| <listitem><para>GCC 3.3.2: GCC_3.3.2</para></listitem> |
| <listitem><para>GCC 3.3.4: GCC_3.3.4</para></listitem> |
| <listitem><para>GCC 3.4.0: GCC_3.4</para></listitem> |
| <listitem><para>GCC 3.4.2: GCC_3.4.2</para></listitem> |
| <listitem><para>GCC 3.4.4: GCC_3.4.4</para></listitem> |
| <listitem><para>GCC 4.0.0: GCC_4.0.0</para></listitem> |
| <listitem><para>GCC 4.1.0: GCC_4.1.0</para></listitem> |
| <listitem><para>GCC 4.2.0: GCC_4.2.0</para></listitem> |
| <listitem><para>GCC 4.3.0: GCC_4.3.0</para></listitem> |
| <listitem><para>GCC 4.4.0: GCC_4.4.0</para></listitem> |
| <listitem><para>GCC 4.5.0: GCC_4.5.0</para></listitem> |
| <listitem><para>GCC 4.6.0: GCC_4.6.0</para></listitem> |
| <listitem><para>GCC 4.7.0: GCC_4.7.0</para></listitem> |
| <listitem><para>GCC 4.8.0: GCC_4.8.0</para></listitem> |
| </itemizedlist> |
| </listitem> |
| |
| <listitem> |
| <para> |
| Release versioning on the libstdc++.so binary, implemented in |
| the same way as the libgcc_s.so binary above. Listed is the |
| filename: <constant>DT_SONAME</constant> can be deduced from |
| the filename by removing the last two period-delimited numbers. For |
| example, filename <filename>libstdc++.so.5.0.4</filename> |
| corresponds to a <constant>DT_SONAME</constant> of |
| <constant>libstdc++.so.5</constant>. Binaries with equivalent |
| <constant>DT_SONAME</constant>s are forward-compatibile: in |
| the table below, releases incompatible with the previous |
| one are explicitly noted. |
| If a particular release is not listed, its libstdc++.so binary |
| has the same filename and <constant>DT_SONAME</constant> as the |
| preceding release. |
| </para> |
| |
| <para>It is versioned as follows: |
| </para> |
| <itemizedlist> |
| <listitem><para>GCC 3.0.0: libstdc++.so.3.0.0</para></listitem> |
| <listitem><para>GCC 3.0.1: libstdc++.so.3.0.1</para></listitem> |
| <listitem><para>GCC 3.0.2: libstdc++.so.3.0.2</para></listitem> |
| <listitem><para>GCC 3.0.3: libstdc++.so.3.0.2 (See Note 1)</para></listitem> |
| <listitem><para>GCC 3.0.4: libstdc++.so.3.0.4</para></listitem> |
| <listitem><para>GCC 3.1.0: libstdc++.so.4.0.0 <emphasis>(Incompatible with previous)</emphasis></para></listitem> |
| <listitem><para>GCC 3.1.1: libstdc++.so.4.0.1</para></listitem> |
| <listitem><para>GCC 3.2.0: libstdc++.so.5.0.0 <emphasis>(Incompatible with previous)</emphasis></para></listitem> |
| <listitem><para>GCC 3.2.1: libstdc++.so.5.0.1</para></listitem> |
| <listitem><para>GCC 3.2.2: libstdc++.so.5.0.2</para></listitem> |
| <listitem><para>GCC 3.2.3: libstdc++.so.5.0.3 (See Note 2)</para></listitem> |
| <listitem><para>GCC 3.3.0: libstdc++.so.5.0.4</para></listitem> |
| <listitem><para>GCC 3.3.1: libstdc++.so.5.0.5</para></listitem> |
| <listitem><para>GCC 3.4.0: libstdc++.so.6.0.0 <emphasis>(Incompatible with previous)</emphasis></para></listitem> |
| <listitem><para>GCC 3.4.1: libstdc++.so.6.0.1</para></listitem> |
| <listitem><para>GCC 3.4.2: libstdc++.so.6.0.2</para></listitem> |
| <listitem><para>GCC 3.4.3: libstdc++.so.6.0.3</para></listitem> |
| <listitem><para>GCC 4.0.0: libstdc++.so.6.0.4</para></listitem> |
| <listitem><para>GCC 4.0.1: libstdc++.so.6.0.5</para></listitem> |
| <listitem><para>GCC 4.0.2: libstdc++.so.6.0.6</para></listitem> |
| <listitem><para>GCC 4.0.3: libstdc++.so.6.0.7</para></listitem> |
| <listitem><para>GCC 4.1.0: libstdc++.so.6.0.7</para></listitem> |
| <listitem><para>GCC 4.1.1: libstdc++.so.6.0.8</para></listitem> |
| <listitem><para>GCC 4.2.0: libstdc++.so.6.0.9</para></listitem> |
| <listitem><para>GCC 4.2.1: libstdc++.so.6.0.9 (See Note 3)</para></listitem> |
| <listitem><para>GCC 4.2.2: libstdc++.so.6.0.9</para></listitem> |
| <listitem><para>GCC 4.3.0: libstdc++.so.6.0.10</para></listitem> |
| <listitem><para>GCC 4.4.0: libstdc++.so.6.0.11</para></listitem> |
| <listitem><para>GCC 4.4.1: libstdc++.so.6.0.12</para></listitem> |
| <listitem><para>GCC 4.4.2: libstdc++.so.6.0.13</para></listitem> |
| <listitem><para>GCC 4.5.0: libstdc++.so.6.0.14</para></listitem> |
| <listitem><para>GCC 4.6.0: libstdc++.so.6.0.15</para></listitem> |
| <listitem><para>GCC 4.6.1: libstdc++.so.6.0.16</para></listitem> |
| <listitem><para>GCC 4.7.0: libstdc++.so.6.0.17</para></listitem> |
| <listitem><para>GCC 4.8.0: libstdc++.so.6.0.18</para></listitem> |
| <listitem><para>GCC 4.8.3: libstdc++.so.6.0.19</para></listitem> |
| <listitem><para>GCC 4.9.0: libstdc++.so.6.0.20</para></listitem> |
| <listitem><para>GCC 5.1.0: libstdc++.so.6.0.21</para></listitem> |
| <listitem><para>GCC 6.1.0: libstdc++.so.6.0.22</para></listitem> |
| <listitem><para>GCC 7.1.0: libstdc++.so.6.0.23</para></listitem> |
| <listitem><para>GCC 7.2.0: libstdc++.so.6.0.24</para></listitem> |
| <listitem><para>GCC 8.1.0: libstdc++.so.6.0.25</para></listitem> |
| <listitem><para>GCC 9.1.0: libstdc++.so.6.0.26</para></listitem> |
| <listitem><para>GCC 9.2.0: libstdc++.so.6.0.27</para></listitem> |
| <listitem><para>GCC 9.3.0: libstdc++.so.6.0.28</para></listitem> |
| <listitem><para>GCC 10.1.0: libstdc++.so.6.0.28</para></listitem> |
| <listitem><para>GCC 11.1.0: libstdc++.so.6.0.29</para></listitem> |
| </itemizedlist> |
| <para> |
| Note 1: Error should be libstdc++.so.3.0.3. |
| </para> |
| <para> |
| Note 2: Not strictly required. |
| </para> |
| <para> |
| Note 3: This release (but not previous or subsequent) has one |
| known incompatibility, see <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33678">33678</link> |
| in the GCC bug database. |
| </para> |
| </listitem> |
| |
| <listitem><para>Symbol versioning on the libstdc++.so binary.</para> |
| |
| <para>mapfile: libstdc++-v3/config/abi/pre/gnu.ver</para> |
| <para>It is versioned with the following labels and version |
| definitions, where the version definition is the maximum for a |
| particular release. Note, only symbols which are newly introduced |
| will use the maximum version definition. Thus, for release series |
| with the same label, but incremented version definitions, the later |
| release has both versions. (An example of this would be the |
| GCC 3.2.1 release, which has GLIBCPP_3.2.1 for new symbols and |
| GLIBCPP_3.2 for symbols that were introduced in the GCC 3.2.0 |
| release.) If a particular release is not listed, it has the same |
| version labels as the preceding release. |
| </para> |
| <itemizedlist> |
| <listitem><para>GCC 3.0.0: (Error, not versioned)</para></listitem> |
| <listitem><para>GCC 3.0.1: (Error, not versioned)</para></listitem> |
| <listitem><para>GCC 3.0.2: (Error, not versioned)</para></listitem> |
| <listitem><para>GCC 3.0.3: (Error, not versioned)</para></listitem> |
| <listitem><para>GCC 3.0.4: (Error, not versioned)</para></listitem> |
| <listitem><para>GCC 3.1.0: GLIBCPP_3.1, CXXABI_1</para></listitem> |
| <listitem><para>GCC 3.1.1: GLIBCPP_3.1, CXXABI_1</para></listitem> |
| <listitem><para>GCC 3.2.0: GLIBCPP_3.2, CXXABI_1.2</para></listitem> |
| <listitem><para>GCC 3.2.1: GLIBCPP_3.2.1, CXXABI_1.2</para></listitem> |
| <listitem><para>GCC 3.2.2: GLIBCPP_3.2.2, CXXABI_1.2</para></listitem> |
| <listitem><para>GCC 3.2.3: GLIBCPP_3.2.2, CXXABI_1.2</para></listitem> |
| <listitem><para>GCC 3.3.0: GLIBCPP_3.2.2, CXXABI_1.2.1</para></listitem> |
| <listitem><para>GCC 3.3.1: GLIBCPP_3.2.3, CXXABI_1.2.1</para></listitem> |
| <listitem><para>GCC 3.3.2: GLIBCPP_3.2.3, CXXABI_1.2.1</para></listitem> |
| <listitem><para>GCC 3.3.3: GLIBCPP_3.2.3, CXXABI_1.2.1</para></listitem> |
| <listitem><para>GCC 3.4.0: GLIBCXX_3.4, CXXABI_1.3</para></listitem> |
| <listitem><para>GCC 3.4.1: GLIBCXX_3.4.1, CXXABI_1.3</para></listitem> |
| <listitem><para>GCC 3.4.2: GLIBCXX_3.4.2</para></listitem> |
| <listitem><para>GCC 3.4.3: GLIBCXX_3.4.3</para></listitem> |
| <listitem><para>GCC 4.0.0: GLIBCXX_3.4.4, CXXABI_1.3.1</para></listitem> |
| <listitem><para>GCC 4.0.1: GLIBCXX_3.4.5</para></listitem> |
| <listitem><para>GCC 4.0.2: GLIBCXX_3.4.6</para></listitem> |
| <listitem><para>GCC 4.0.3: GLIBCXX_3.4.7</para></listitem> |
| <listitem><para>GCC 4.1.1: GLIBCXX_3.4.8</para></listitem> |
| <listitem><para>GCC 4.2.0: GLIBCXX_3.4.9</para></listitem> |
| <listitem><para>GCC 4.3.0: GLIBCXX_3.4.10, CXXABI_1.3.2</para></listitem> |
| <listitem><para>GCC 4.4.0: GLIBCXX_3.4.11, CXXABI_1.3.3</para></listitem> |
| <listitem><para>GCC 4.4.1: GLIBCXX_3.4.12, CXXABI_1.3.3</para></listitem> |
| <listitem><para>GCC 4.4.2: GLIBCXX_3.4.13, CXXABI_1.3.3</para></listitem> |
| <listitem><para>GCC 4.5.0: GLIBCXX_3.4.14, CXXABI_1.3.4</para></listitem> |
| <listitem><para>GCC 4.6.0: GLIBCXX_3.4.15, CXXABI_1.3.5</para></listitem> |
| <listitem><para>GCC 4.6.1: GLIBCXX_3.4.16, CXXABI_1.3.5</para></listitem> |
| <listitem><para>GCC 4.7.0: GLIBCXX_3.4.17, CXXABI_1.3.6</para></listitem> |
| <listitem><para>GCC 4.8.0: GLIBCXX_3.4.18, CXXABI_1.3.7</para></listitem> |
| <listitem><para>GCC 4.8.3: GLIBCXX_3.4.19, CXXABI_1.3.7</para></listitem> |
| <listitem><para>GCC 4.9.0: GLIBCXX_3.4.20, CXXABI_1.3.8</para></listitem> |
| <listitem><para>GCC 5.1.0: GLIBCXX_3.4.21, CXXABI_1.3.9</para></listitem> |
| <listitem><para>GCC 6.1.0: GLIBCXX_3.4.22, CXXABI_1.3.10</para></listitem> |
| <listitem><para>GCC 7.1.0: GLIBCXX_3.4.23, CXXABI_1.3.11</para></listitem> |
| <listitem><para>GCC 7.2.0: GLIBCXX_3.4.24, CXXABI_1.3.11</para></listitem> |
| <listitem><para>GCC 8.1.0: GLIBCXX_3.4.25, CXXABI_1.3.11</para></listitem> |
| <listitem><para>GCC 9.1.0: GLIBCXX_3.4.26, CXXABI_1.3.12</para></listitem> |
| <listitem><para>GCC 9.2.0: GLIBCXX_3.4.27, CXXABI_1.3.12</para></listitem> |
| <listitem><para>GCC 9.3.0: GLIBCXX_3.4.28, CXXABI_1.3.12</para></listitem> |
| <listitem><para>GCC 10.1.0: GLIBCXX_3.4.28, CXXABI_1.3.12</para></listitem> |
| <listitem><para>GCC 11.1.0: GLIBCXX_3.4.29, CXXABI_1.3.13</para></listitem> |
| |
| </itemizedlist> |
| </listitem> |
| |
| <listitem> |
| <para>Incremental bumping of a compiler pre-defined macro, |
| __GXX_ABI_VERSION. This macro is defined as the version of the |
| compiler v3 ABI, with g++ 3.0 being version 100. This macro will |
| be automatically defined whenever g++ is used (the curious can |
| test this by invoking g++ with the '-v' flag.) |
| </para> |
| |
| <para> |
| This macro was defined in the file "lang-specs.h" in the gcc/cp directory. |
| Later versions defined it in "c-common.c" in the gcc directory, and from |
| G++ 3.4 it is defined in c-cppbuiltin.c and its value determined by the |
| '-fabi-version' command line option. |
| </para> |
| |
| <para> |
| It is versioned as follows, where 'n' is given by '-fabi-version=n': |
| </para> |
| <itemizedlist> |
| <listitem><para>GCC 3.0: 100</para></listitem> |
| <listitem><para>GCC 3.1: 100 (Error, should be 101)</para></listitem> |
| <listitem><para>GCC 3.2: 102</para></listitem> |
| <listitem><para>GCC 3.3: 102</para></listitem> |
| <listitem><para>GCC 3.4, GCC 4.x: 102 (when n=1)</para></listitem> |
| <listitem><para>GCC 3.4, GCC 4.x: 1000 + n (when n>1) </para></listitem> |
| <listitem><para>GCC 3.4, GCC 4.x: 999999 (when n=0)</para></listitem> |
| </itemizedlist> |
| <para/> |
| </listitem> |
| |
| <listitem> |
| <para>Changes to the default compiler option for |
| <code>-fabi-version</code>. |
| </para> |
| <para> |
| It is versioned as follows: |
| </para> |
| <itemizedlist> |
| <listitem><para>GCC 3.0: (Error, not versioned) </para></listitem> |
| <listitem><para>GCC 3.1: (Error, not versioned) </para></listitem> |
| <listitem><para>GCC 3.2: <code>-fabi-version=1</code></para></listitem> |
| <listitem><para>GCC 3.3: <code>-fabi-version=1</code></para></listitem> |
| <listitem><para>GCC 3.4, GCC 4.x: <code>-fabi-version=2</code> <emphasis>(Incompatible with previous)</emphasis></para></listitem> |
| <listitem><para>GCC 5 and higher: <code>-fabi-version=0</code> <emphasis>(See GCC manual for meaning)</emphasis></para></listitem> |
| </itemizedlist> |
| <para/> |
| </listitem> |
| |
| <listitem xml:id="abi.versioning.__GLIBCXX__"> |
| <para>Incremental bumping of a library pre-defined macro. For releases |
| before 3.4.0, the macro is <symbol>__GLIBCPP__</symbol>. For later |
| releases, it's <symbol>__GLIBCXX__</symbol>. (The libstdc++ project |
| generously changed from CPP to CXX throughout its source to allow the |
| "C" pre-processor the CPP macro namespace.) These macros are defined |
| as the date the library was released, in compressed ISO date format, |
| as an integer constant. |
| </para> |
| |
| <para> |
| This macro is defined in the file |
| <filename class="headerfile">c++config</filename> in the |
| <filename class="directory">libstdc++-v3/include/bits</filename> |
| directory. Up to GCC 4.1.0, it was |
| changed every night by an automated script. Since GCC 4.1.0 it is set |
| during configuration to the same value as |
| <filename>gcc/DATESTAMP</filename>, so for an official release its value |
| is the same as the date of the release, which is given in the <link |
| xmlns:xlink="http://www.w3.org/1999/xlink" |
| xlink:href="https://gcc.gnu.org/develop.html#timeline">GCC Release |
| Timeline</link>. |
| </para> |
| |
| <para> |
| This macro can be used in code to detect whether the C++ Standard Library |
| implementation in use is libstdc++, but is not useful for detecting the |
| libstdc++ version, nor whether particular features are supported. |
| The macro value might be a date after a feature was added to the |
| development trunk, but the release could be from an older branch without |
| the feature. For example, in the 5.4.0 release the macro has the value |
| <literal>20160603</literal> which is greater than the |
| <literal>20160427</literal> value of the macro in the 6.1.0 release, |
| but there are features supported in the 6.1.0 release that are not |
| supported in the 5.4.0 release. |
| You also can't test for the exact values listed below to try and |
| identify a release, because a snapshot taken from the gcc-5-branch on |
| 2016-04-27 would have the same value for the macro as the 6.1.0 release |
| despite being a different version. |
| Many GNU/Linux distributions build their GCC packages from snapshots, so |
| the macro can have dates that don't correspond to official releases. |
| </para> |
| |
| <para> |
| It is versioned as follows: |
| </para> |
| <itemizedlist> |
| <listitem><para>GCC 3.0.0: <literal>20010615</literal></para></listitem> |
| <listitem><para>GCC 3.0.1: <literal>20010819</literal></para></listitem> |
| <listitem><para>GCC 3.0.2: <literal>20011023</literal></para></listitem> |
| <listitem><para>GCC 3.0.3: <literal>20011220</literal></para></listitem> |
| <listitem><para>GCC 3.0.4: <literal>20020220</literal></para></listitem> |
| <listitem><para>GCC 3.1.0: <literal>20020514</literal></para></listitem> |
| <listitem><para>GCC 3.1.1: <literal>20020725</literal></para></listitem> |
| <listitem><para>GCC 3.2.0: <literal>20020814</literal></para></listitem> |
| <listitem><para>GCC 3.2.1: <literal>20021119</literal></para></listitem> |
| <listitem><para>GCC 3.2.2: <literal>20030205</literal></para></listitem> |
| <listitem><para>GCC 3.2.3: <literal>20030422</literal></para></listitem> |
| <listitem><para>GCC 3.3.0: <literal>20030513</literal></para></listitem> |
| <listitem><para>GCC 3.3.1: <literal>20030804</literal></para></listitem> |
| <listitem><para>GCC 3.3.2: <literal>20031016</literal></para></listitem> |
| <listitem><para>GCC 3.3.3: <literal>20040214</literal></para></listitem> |
| <listitem><para>GCC 3.4.0: <literal>20040419</literal></para></listitem> |
| <listitem><para>GCC 3.4.1: <literal>20040701</literal></para></listitem> |
| <listitem><para>GCC 3.4.2: <literal>20040906</literal></para></listitem> |
| <listitem><para>GCC 3.4.3: <literal>20041105</literal></para></listitem> |
| <listitem><para>GCC 3.4.4: <literal>20050519</literal></para></listitem> |
| <listitem><para>GCC 3.4.5: <literal>20051201</literal></para></listitem> |
| <listitem><para>GCC 3.4.6: <literal>20060306</literal></para></listitem> |
| <listitem><para>GCC 4.0.0: <literal>20050421</literal></para></listitem> |
| <listitem><para>GCC 4.0.1: <literal>20050707</literal></para></listitem> |
| <listitem><para>GCC 4.0.2: <literal>20050921</literal></para></listitem> |
| <listitem><para>GCC 4.0.3: <literal>20060309</literal></para></listitem> |
| <listitem><para> |
| GCC 4.1.0 and later: the GCC release date, as shown in the |
| <link xmlns:xlink="http://www.w3.org/1999/xlink" |
| xlink:href="https://gcc.gnu.org/develop.html#timeline">GCC |
| Release Timeline</link> |
| </para></listitem> |
| </itemizedlist> |
| <para/> |
| </listitem> |
| |
| <listitem> |
| <para> |
| Since GCC 7, incremental bumping of a library pre-defined macro, |
| <symbol>_GLIBCXX_RELEASE</symbol>. This macro is defined to the GCC |
| major version that the libstdc++ headers belong to, as an integer constant. |
| When compiling with GCC it has the same value as GCC's pre-defined |
| macro <symbol>__GNUC__</symbol>. |
| This macro can be used when libstdc++ is used with a non-GNU |
| compiler where <symbol>__GNUC__</symbol> is not defined, or has a |
| different value that doesn't correspond to the libstdc++ version. |
| </para> |
| |
| <para> |
| This macro is defined in the file |
| <filename class="headerfile">c++config</filename> in the |
| <filename class="directory">libstdc++-v3/include/bits</filename> |
| directory and is generated automatically by autoconf as part of the |
| configure-time generation of |
| <filename class="headerfile">config.h</filename> and subsequently |
| <filename class="headerfile"><bits/c++config.h></filename>. |
| </para> |
| </listitem> |
| |
| <listitem> |
| <para> |
| Historically, incremental bumping of a library pre-defined macro, |
| <symbol>_GLIBCPP_VERSION</symbol>. This macro was defined as the |
| released version of the library, as a string literal. This was only |
| implemented in GCC 3.1.0 releases and higher, and was deprecated in |
| 3.4.x (where it was called <symbol>_GLIBCXX_VERSION</symbol>), |
| and is not defined in 4.0.0 and higher. |
| </para> |
| |
| <para> |
| This macro is defined in the same file as |
| <symbol>_GLIBCXX_RELEASE</symbol>, described above. |
| </para> |
| |
| <para> |
| It is versioned as follows: |
| </para> |
| <itemizedlist> |
| <listitem><para>GCC 3.0.0: <literal>"3.0.0"</literal></para></listitem> |
| <listitem><para>GCC 3.0.1: <literal>"3.0.0"</literal> (Error, should be <literal>"3.0.1"</literal>)</para></listitem> |
| <listitem><para>GCC 3.0.2: <literal>"3.0.0"</literal> (Error, should be <literal>"3.0.2"</literal>)</para></listitem> |
| <listitem><para>GCC 3.0.3: <literal>"3.0.0"</literal> (Error, should be <literal>"3.0.3"</literal>)</para></listitem> |
| <listitem><para>GCC 3.0.4: <literal>"3.0.0"</literal> (Error, should be <literal>"3.0.4"</literal>)</para></listitem> |
| <listitem><para>GCC 3.1.0: <literal>"3.1.0"</literal></para></listitem> |
| <listitem><para>GCC 3.1.1: <literal>"3.1.1"</literal></para></listitem> |
| <listitem><para>GCC 3.2.0: <literal>"3.2"</literal></para></listitem> |
| <listitem><para>GCC 3.2.1: <literal>"3.2.1"</literal></para></listitem> |
| <listitem><para>GCC 3.2.2: <literal>"3.2.2"</literal></para></listitem> |
| <listitem><para>GCC 3.2.3: <literal>"3.2.3"</literal></para></listitem> |
| <listitem><para>GCC 3.3.0: <literal>"3.3"</literal></para></listitem> |
| <listitem><para>GCC 3.3.1: <literal>"3.3.1"</literal></para></listitem> |
| <listitem><para>GCC 3.3.2: <literal>"3.3.2"</literal></para></listitem> |
| <listitem><para>GCC 3.3.3: <literal>"3.3.3"</literal></para></listitem> |
| <listitem><para>GCC 3.4: <literal>"version-unused"</literal></para></listitem> |
| <listitem><para>GCC 4 and later: not defined</para></listitem> |
| </itemizedlist> |
| <para/> |
| </listitem> |
| |
| <listitem> |
| <para> |
| Matching each specific C++ compiler release to a specific set of |
| C++ include files. This is only implemented in GCC 3.1.1 releases |
| and higher. |
| </para> |
| <para> |
| All C++ includes are installed in |
| <filename class="directory">include/c++</filename>, then nested in a |
| directory hierarchy corresponding to the C++ compiler's released |
| version. This version corresponds to the variable "gcc_version" in |
| "libstdc++-v3/acinclude.m4," and more details can be found in that |
| file's macro GLIBCXX_CONFIGURE (GLIBCPP_CONFIGURE before GCC 3.4.0). |
| </para> |
| <para> |
| C++ includes are versioned as follows: |
| </para> |
| <itemizedlist> |
| <listitem><para>GCC 3.0.0: include/g++-v3</para></listitem> |
| <listitem><para>GCC 3.0.1: include/g++-v3</para></listitem> |
| <listitem><para>GCC 3.0.2: include/g++-v3</para></listitem> |
| <listitem><para>GCC 3.0.3: include/g++-v3</para></listitem> |
| <listitem><para>GCC 3.0.4: include/g++-v3</para></listitem> |
| <listitem><para>GCC 3.1.0: include/g++-v3</para></listitem> |
| <listitem><para>GCC 3.1.1: include/c++/3.1.1</para></listitem> |
| <listitem><para>GCC 3.2.0: include/c++/3.2</para></listitem> |
| <listitem><para>GCC 3.2.1: include/c++/3.2.1</para></listitem> |
| <listitem><para>GCC 3.2.2: include/c++/3.2.2</para></listitem> |
| <listitem><para>GCC 3.2.3: include/c++/3.2.3</para></listitem> |
| <listitem><para>GCC 3.3.0: include/c++/3.3</para></listitem> |
| <listitem><para>GCC 3.3.1: include/c++/3.3.1</para></listitem> |
| <listitem><para>GCC 3.3.2: include/c++/3.3.2</para></listitem> |
| <listitem><para>GCC 3.3.3: include/c++/3.3.3</para></listitem> |
| <listitem><para>GCC 3.4.x: include/c++/3.4.x</para></listitem> |
| <listitem><para>GCC 4.x.y: include/c++/4.x.y</para></listitem> |
| <listitem><para>GCC 5.1.0: include/c++/5.1.0</para></listitem> |
| <listitem> |
| <para>GCC x.y.0: include/c++/x.y.0 (for releases after GCC 5.1.0)</para> |
| </listitem> |
| </itemizedlist> |
| <para/> |
| </listitem> |
| </orderedlist> |
| |
| <para> |
| Taken together, these techniques can accurately specify interface |
| and implementation changes in the GNU C++ tools themselves. Used |
| properly, they allow both the GNU C++ tools implementation, and |
| programs using them, an evolving yet controlled development that |
| maintains backward compatibility. |
| </para> |
| |
| |
| </section> |
| |
| <section xml:id="abi.versioning.prereq"><info><title>Prerequisites</title></info> |
| |
| <para> |
| Minimum environment that supports a versioned ABI: A supported |
| dynamic linker, a GNU linker of sufficient vintage to understand |
| demangled C++ name globbing (ld) or the Sun linker, a shared |
| executable compiled |
| with g++, and shared libraries (libgcc_s, libstdc++) compiled by |
| a compiler (g++) with a compatible ABI. Phew. |
| </para> |
| |
| <para> |
| On top of all that, an additional constraint: libstdc++ did not |
| attempt to version symbols (or age gracefully, really) until |
| version 3.1.0. |
| </para> |
| |
| <para> |
| Most modern GNU/Linux and BSD versions, particularly ones using |
| GCC 3.1 and later, will meet the |
| requirements above, as does Solaris 2.5 and up. |
| </para> |
| </section> |
| |
| <section xml:id="abi.versioning.config"><info><title>Configuring</title></info> |
| |
| |
| <para> |
| It turns out that most of the configure options that change |
| default behavior will impact the mangled names of exported |
| symbols, and thus impact versioning and compatibility. |
| </para> |
| |
| <para> |
| For more information on configure options, including ABI |
| impacts, see: |
| <link linkend="manual.intro.setup.configure">here</link> |
| </para> |
| |
| <para> |
| There is one flag that explicitly deals with symbol versioning: |
| --enable-symvers. |
| </para> |
| |
| <para> |
| In particular, libstdc++-v3/acinclude.m4 has a macro called |
| GLIBCXX_ENABLE_SYMVERS that defaults to yes (or the argument |
| passed in via --enable-symvers=foo). At that point, the macro |
| attempts to make sure that all the requirement for symbol |
| versioning are in place. For more information, please consult |
| acinclude.m4. |
| </para> |
| </section> |
| |
| <section xml:id="abi.versioning.active"><info><title>Checking Active</title></info> |
| |
| |
| <para> |
| When the GNU C++ library is being built with symbol versioning |
| on, you should see the following at configure time for |
| libstdc++ (showing either 'gnu' or another of the supported styles): |
| </para> |
| |
| <screen> |
| <computeroutput> |
| checking versioning on shared library symbols... gnu |
| </computeroutput> |
| </screen> |
| |
| <para> |
| If you don't see this line in the configure output, or if this line |
| appears but the last word is 'no', then you are out of luck. |
| </para> |
| |
| <para> |
| If the compiler is pre-installed, a quick way to test is to compile |
| the following (or any) simple C++ file and link it to the shared |
| libstdc++ library: |
| </para> |
| |
| <programlisting> |
| #include <iostream> |
| |
| int main() |
| { std::cout << "hello" << std::endl; return 0; } |
| |
| %g++ hello.cc -o hello.out |
| |
| %ldd hello.out |
| libstdc++.so.5 => /usr/lib/libstdc++.so.5 (0x00764000) |
| libm.so.6 => /lib/tls/libm.so.6 (0x004a8000) |
| libgcc_s.so.1 => /mnt/hd/bld/gcc/gcc/libgcc_s.so.1 (0x40016000) |
| libc.so.6 => /lib/tls/libc.so.6 (0x0036d000) |
| /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x00355000) |
| |
| %nm hello.out |
| </programlisting> |
| |
| <para> |
| If you see symbols in the resulting output with "GLIBCXX_3" as part |
| of the name, then the executable is versioned. Here's an example: |
| </para> |
| |
| <para> |
| <code>U _ZNSt8ios_base4InitC1Ev@@GLIBCXX_3.4</code> |
| </para> |
| |
| <para> |
| On Solaris 2, you can use <code>pvs -r</code> instead: |
| </para> |
| |
| <programlisting> |
| %g++ hello.cc -o hello.out |
| |
| %pvs -r hello.out |
| libstdc++.so.6 (GLIBCXX_3.4, GLIBCXX_3.4.12); |
| libgcc_s.so.1 (GCC_3.0); |
| libc.so.1 (SUNWprivate_1.1, SYSVABI_1.3); |
| </programlisting> |
| |
| <para> |
| <code>ldd -v</code> works too, but is very verbose. |
| </para> |
| |
| </section> |
| </section> |
| |
| <section xml:id="abi.changes_allowed"><info><title>Allowed Changes</title></info> |
| |
| |
| <para> |
| The following will cause the library minor version number to |
| increase, say from "libstdc++.so.3.0.4" to "libstdc++.so.3.0.5". |
| </para> |
| <orderedlist> |
| <listitem><para>Adding an exported global or static data member</para></listitem> |
| <listitem><para>Adding an exported function, static or non-virtual member function</para></listitem> |
| <listitem><para>Adding an exported symbol or symbols by additional instantiations</para></listitem> |
| </orderedlist> |
| <para> |
| Other allowed changes are possible. |
| </para> |
| |
| </section> |
| |
| <section xml:id="abi.changes_no"><info><title>Prohibited Changes</title></info> |
| |
| |
| <para> |
| The following non-exhaustive list will cause the library major version |
| number to increase, say from "libstdc++.so.3.0.4" to |
| "libstdc++.so.4.0.0". |
| </para> |
| |
| <orderedlist> |
| <listitem><para>Changes in the gcc/g++ compiler ABI</para></listitem> |
| <listitem><para>Changing size of an exported symbol</para></listitem> |
| <listitem><para>Changing alignment of an exported symbol</para></listitem> |
| <listitem><para>Changing the layout of an exported symbol</para></listitem> |
| <listitem><para>Changing mangling on an exported symbol</para></listitem> |
| <listitem><para>Deleting an exported symbol</para></listitem> |
| <listitem><para>Changing the inheritance properties of a type by adding or removing |
| base classes</para></listitem> |
| <listitem><para> |
| Changing the size, alignment, or layout of types |
| specified in the C++ standard. These may not necessarily be |
| instantiated or otherwise exported in the library binary, and |
| include all the required locale facets, as well as things like |
| std::basic_streambuf, et al. |
| </para></listitem> |
| |
| <listitem><para> Adding an explicit copy constructor or destructor to a |
| class that would otherwise have implicit versions. This will change |
| the way the compiler deals with this class in by-value return |
| statements or parameters: instead of passing instances of this |
| class in registers, the compiler will be forced to use memory. See the |
| section on <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://itanium-cxx-abi.github.io/cxx-abi/abi.html#calls">Function |
| Calling Conventions and APIs</link> |
| of the C++ ABI documentation for further details. |
| </para></listitem> |
| |
| </orderedlist> |
| |
| </section> |
| |
| |
| |
| <section xml:id="abi.impl"><info><title>Implementation</title></info> |
| |
| |
| <orderedlist> |
| <listitem> |
| <para> |
| Separation of interface and implementation |
| </para> |
| <para> |
| This is accomplished by two techniques that separate the API from |
| the ABI: forcing undefined references to link against a library |
| binary for definitions. |
| </para> |
| |
| <variablelist> |
| <varlistentry> |
| <term>Include files have declarations, source files have defines</term> |
| |
| <listitem> |
| <para> |
| For non-templatized types, such as much of <code>class |
| locale</code>, the appropriate standard C++ include, say |
| <code>locale</code>, can contain full declarations, while |
| various source files (say <code> locale.cc, locale_init.cc, |
| localename.cc</code>) contain definitions. |
| </para> |
| </listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term>Extern template on required types</term> |
| |
| <listitem> |
| <para> |
| For parts of the standard that have an explicit list of |
| required instantiations, the GNU extension syntax <code> extern |
| template </code> can be used to control where template |
| definitions reside. By marking required instantiations as |
| <code> extern template </code> in include files, and providing |
| explicit instantiations in the appropriate instantiation files, |
| non-inlined template functions can be versioned. This technique |
| is mostly used on parts of the standard that require <code> |
| char</code> and <code> wchar_t</code> instantiations, and |
| includes <code> basic_string</code>, the locale facets, and the |
| types in <code> iostreams</code>. |
| </para> |
| </listitem> |
| </varlistentry> |
| |
| </variablelist> |
| |
| <para> |
| In addition, these techniques have the additional benefit that they |
| reduce binary size, which can increase runtime performance. |
| </para> |
| </listitem> |
| |
| <listitem> |
| <para> |
| Namespaces linking symbol definitions to export mapfiles |
| </para> |
| <para> |
| All symbols in the shared library binary are processed by a |
| linker script at build time that either allows or disallows |
| external linkage. Because of this, some symbols, regardless of |
| normal C/C++ linkage, are not visible. Symbols that are internal |
| have several appealing characteristics: by not exporting the |
| symbols, there are no relocations when the shared library is |
| started and thus this makes for faster runtime loading |
| performance by the underlying dynamic loading mechanism. In |
| addition, they have the possibility of changing without impacting |
| ABI compatibility. |
| </para> |
| |
| <para>The following namespaces are transformed by the mapfile:</para> |
| |
| <variablelist> |
| |
| <varlistentry> |
| <term><code>namespace std</code></term> |
| <listitem><para> Defaults to exporting all symbols in label |
| <code>GLIBCXX</code> that do not begin with an underscore, i.e., |
| <code>__test_func</code> would not be exported by default. Select |
| exceptional symbols are allowed to be visible.</para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><code>namespace __gnu_cxx</code></term> |
| <listitem><para> Defaults to not exporting any symbols in label |
| <code>GLIBCXX</code>, select items are allowed to be visible.</para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><code>namespace __gnu_internal</code></term> |
| <listitem><para> Defaults to not exported, no items are allowed to be visible.</para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><code>namespace __cxxabiv1</code>, aliased to <code> namespace abi</code></term> |
| <listitem><para> Defaults to not exporting any symbols in label |
| <code>CXXABI</code>, select items are allowed to be visible.</para></listitem> |
| </varlistentry> |
| |
| </variablelist> |
| <para> |
| </para> |
| </listitem> |
| |
| <listitem><para>Freezing the API</para> |
| <para>Disallowed changes, as above, are not made on a stable release |
| branch. Enforcement tends to be less strict with GNU extensions that |
| standard includes.</para> |
| </listitem> |
| </orderedlist> |
| |
| </section> |
| |
| <section xml:id="abi.testing"><info><title>Testing</title></info> |
| |
| |
| <section xml:id="abi.testing.single"><info><title>Single ABI Testing</title></info> |
| |
| |
| <para> |
| Testing for GNU C++ ABI changes is composed of two distinct |
| areas: testing the C++ compiler (g++) for compiler changes, and |
| testing the C++ library (libstdc++) for library changes. |
| </para> |
| |
| <para> |
| Testing the C++ compiler ABI can be done various ways. |
| </para> |
| |
| <para> |
| One. Intel ABI checker. |
| </para> |
| |
| <para> |
| Two. |
| The second is yet unreleased, but has been announced on the gcc |
| mailing list. It is yet unspecified if these tools will be freely |
| available, and able to be included in a GNU project. Please contact |
| Mark Mitchell (mark@codesourcery.com) for more details, and current |
| status. |
| </para> |
| |
| <para> |
| Three. |
| Involves using the vlad.consistency test framework. This has also been |
| discussed on the gcc mailing lists. |
| </para> |
| |
| <para> |
| Testing the C++ library ABI can also be done various ways. |
| </para> |
| |
| <para> |
| One. |
| (Brendan Kehoe, Jeff Law suggestion to run 'make check-c++' two ways, |
| one with a new compiler and an old library, and the other with an old |
| compiler and a new library, and look for testsuite regressions) |
| </para> |
| |
| <para> |
| Details on how to set this kind of test up can be found here: |
| http://gcc.gnu.org/ml/gcc/2002-08/msg00142.html |
| </para> |
| |
| <para> |
| Two. |
| Use the 'make check-abi' rule in the libstdc++ Makefile. |
| </para> |
| |
| <para> |
| This is a proactive check of the library ABI. Currently, exported symbol |
| names that are either weak or defined are checked against a last known |
| good baseline. Currently, this baseline is keyed off of 3.4.0 |
| binaries, as this was the last time the .so number was incremented. In |
| addition, all exported names are demangled, and the exported objects |
| are checked to make sure they are the same size as the same object in |
| the baseline. |
| |
| Notice that each baseline is relative to a <emphasis>default</emphasis> |
| configured library and compiler: in particular, if options such as |
| --enable-clocale, or --with-cpu, in case of multilibs, are used at |
| configure time, the check may fail, either because of substantive |
| differences or because of limitations of the current checking |
| machinery. |
| </para> |
| |
| <para> |
| This dataset is insufficient, yet a start. Also needed is a |
| comprehensive check for all user-visible types part of the standard |
| library for sizeof() and alignof() changes. |
| </para> |
| |
| <para> |
| Verifying compatible layouts of objects is not even attempted. It |
| should be possible to use sizeof, alignof, and offsetof to compute |
| offsets for each structure and type in the standard library, saving to |
| another datafile. Then, compute this in a similar way for new |
| binaries, and look for differences. |
| </para> |
| |
| <para> |
| Another approach might be to use the -fdump-class-hierarchy flag to |
| get information. However, currently this approach gives insufficient |
| data for use in library testing, as class data members, their offsets, |
| and other detailed data is not displayed with this flag. |
| (See PR g++/7470 on how this was used to find bugs.) |
| </para> |
| |
| <para> |
| Perhaps there are other C++ ABI checkers. If so, please notify |
| us. We'd like to know about them! |
| </para> |
| |
| </section> |
| <section xml:id="abi.testing.multi"><info><title>Multiple ABI Testing</title></info> |
| |
| <para> |
| A "C" application, dynamically linked to two shared libraries, liba, |
| libb. The dependent library liba is a C++ shared library compiled with |
| GCC 3.3, and uses io, exceptions, locale, etc. The dependent library |
| libb is a C++ shared library compiled with GCC 3.4, and also uses io, |
| exceptions, locale, etc. |
| </para> |
| |
| <para> As above, libone is constructed as follows: </para> |
| <programlisting> |
| %$bld/H-x86-gcc-3.4.0/bin/g++ -fPIC -DPIC -c a.cc |
| |
| %$bld/H-x86-gcc-3.4.0/bin/g++ -shared -Wl,-soname -Wl,libone.so.1 -Wl,-O1 -Wl,-z,defs a.o -o libone.so.1.0.0 |
| |
| %ln -s libone.so.1.0.0 libone.so |
| |
| %$bld/H-x86-gcc-3.4.0/bin/g++ -c a.cc |
| |
| %ar cru libone.a a.o |
| </programlisting> |
| |
| <para> And, libtwo is constructed as follows: </para> |
| |
| <programlisting> |
| %$bld/H-x86-gcc-3.3.3/bin/g++ -fPIC -DPIC -c b.cc |
| |
| %$bld/H-x86-gcc-3.3.3/bin/g++ -shared -Wl,-soname -Wl,libtwo.so.1 -Wl,-O1 -Wl,-z,defs b.o -o libtwo.so.1.0.0 |
| |
| %ln -s libtwo.so.1.0.0 libtwo.so |
| |
| %$bld/H-x86-gcc-3.3.3/bin/g++ -c b.cc |
| |
| %ar cru libtwo.a b.o |
| </programlisting> |
| |
| <para> ...with the resulting libraries looking like </para> |
| |
| <screen> |
| <computeroutput> |
| %ldd libone.so.1.0.0 |
| libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x40016000) |
| libm.so.6 => /lib/tls/libm.so.6 (0x400fa000) |
| libgcc_s.so.1 => /mnt/hd/bld/gcc/gcc/libgcc_s.so.1 (0x4011c000) |
| libc.so.6 => /lib/tls/libc.so.6 (0x40125000) |
| /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x00355000) |
| |
| %ldd libtwo.so.1.0.0 |
| libstdc++.so.5 => /usr/lib/libstdc++.so.5 (0x40027000) |
| libm.so.6 => /lib/tls/libm.so.6 (0x400e1000) |
| libgcc_s.so.1 => /mnt/hd/bld/gcc/gcc/libgcc_s.so.1 (0x40103000) |
| libc.so.6 => /lib/tls/libc.so.6 (0x4010c000) |
| /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x00355000) |
| </computeroutput> |
| </screen> |
| |
| <para> |
| Then, the "C" compiler is used to compile a source file that uses |
| functions from each library. |
| </para> |
| <programlisting> |
| gcc test.c -g -O2 -L. -lone -ltwo /usr/lib/libstdc++.so.5 /usr/lib/libstdc++.so.6 |
| </programlisting> |
| |
| <para> |
| Which gives the expected: |
| </para> |
| |
| <screen> |
| <computeroutput> |
| %ldd a.out |
| libstdc++.so.5 => /usr/lib/libstdc++.so.5 (0x00764000) |
| libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x40015000) |
| libc.so.6 => /lib/tls/libc.so.6 (0x0036d000) |
| libm.so.6 => /lib/tls/libm.so.6 (0x004a8000) |
| libgcc_s.so.1 => /mnt/hd/bld/gcc/gcc/libgcc_s.so.1 (0x400e5000) |
| /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x00355000) |
| </computeroutput> |
| </screen> |
| |
| <para> |
| This resulting binary, when executed, will be able to safely use |
| code from both liba, and the dependent libstdc++.so.6, and libb, |
| with the dependent libstdc++.so.5. |
| </para> |
| </section> |
| </section> |
| |
| <section xml:id="abi.issues"><info><title>Outstanding Issues</title></info> |
| |
| |
| <para> |
| Some features in the C++ language make versioning especially |
| difficult. In particular, compiler generated constructs such as |
| implicit instantiations for templates, typeinfo information, and |
| virtual tables all may cause ABI leakage across shared library |
| boundaries. Because of this, mixing C++ ABIs is not recommended at |
| this time. |
| </para> |
| |
| <para> |
| For more background on this issue, see these bugzilla entries: |
| </para> |
| |
| <para> |
| <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://gcc.gnu.org/PR24660">24660: versioning weak symbols in libstdc++</link> |
| </para> |
| |
| <para> |
| <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://gcc.gnu.org/PR19664">19664: libstdc++ headers should have pop/push of the visibility around the declarations</link> |
| </para> |
| |
| </section> |
| |
| <bibliography xml:id="abi.biblio"><info><title>Bibliography</title></info> |
| |
| <biblioentry xml:id="biblio.abicheck"> |
| <title> |
| <link xmlns:xlink="http://www.w3.org/1999/xlink" |
| xlink:href="http://abicheck.sourceforge.net"> |
| ABIcheck |
| </link> |
| </title> |
| </biblioentry> |
| |
| <biblioentry xml:id="biblio.cxxabi"> |
| <title> |
| <link xmlns:xlink="http://www.w3.org/1999/xlink" |
| xlink:href="https://itanium-cxx-abi.github.io/cxx-abi/"> |
| Itanium C++ ABI |
| </link> |
| </title> |
| </biblioentry> |
| |
| <biblioentry> |
| <title> |
| <link xmlns:xlink="http://www.w3.org/1999/xlink" |
| xlink:href="https://docs.oracle.com/cd/E23824_01/html/819-0690/index.html"> |
| Linker and Libraries Guide (document 819-0690) |
| </link> |
| </title> |
| </biblioentry> |
| |
| |
| <biblioentry> |
| <title> |
| <link xmlns:xlink="http://www.w3.org/1999/xlink" |
| xlink:href="https://docs.oracle.com/cd/E19422-01/819-3689/"> |
| Sun Studio 11: C++ Migration Guide (document 819-3689) |
| </link> |
| </title> |
| </biblioentry> |
| |
| <biblioentry> |
| <title> |
| <link xmlns:xlink="http://www.w3.org/1999/xlink" |
| xlink:href="https://www.akkadia.org/drepper/dsohowto.pdf"> |
| How to Write Shared Libraries |
| </link> |
| </title> |
| |
| <author> |
| <personname> |
| <firstname>Ulrich</firstname><surname>Drepper</surname> |
| </personname> |
| </author> |
| </biblioentry> |
| |
| <biblioentry> |
| <title> |
| <link xmlns:xlink="http://www.w3.org/1999/xlink" |
| xlink:href="https://developer.arm.com/documentation/ihi0036/latest/"> |
| C++ ABI for the ARM Architecture |
| </link> |
| </title> |
| </biblioentry> |
| |
| <biblioentry> |
| <title> |
| <link xmlns:xlink="http://www.w3.org/1999/xlink" |
| xlink:href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1976.html"> |
| Dynamic Shared Objects: Survey and Issues |
| </link> |
| </title> |
| |
| <subtitle> |
| ISO C++ J16/06-0046 |
| </subtitle> |
| <author><personname><firstname>Benjamin</firstname><surname>Kosnik</surname></personname></author> |
| </biblioentry> |
| |
| <biblioentry> |
| <title> |
| <link xmlns:xlink="http://www.w3.org/1999/xlink" |
| xlink:href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2013.html"> |
| Versioning With Namespaces |
| </link> |
| </title> |
| <subtitle> |
| ISO C++ J16/06-0083 |
| </subtitle> |
| <author><personname><firstname>Benjamin</firstname><surname>Kosnik</surname></personname></author> |
| </biblioentry> |
| |
| <biblioentry> |
| <title> |
| <link xmlns:xlink="http://www.w3.org/1999/xlink" |
| xlink:href="http://syrcose.ispras.ru/2009/files/02_paper.pdf"> |
| Binary Compatibility of Shared Libraries Implemented in C++ |
| on GNU/Linux Systems |
| </link> |
| </title> |
| |
| <subtitle> |
| SYRCoSE 2009 |
| </subtitle> |
| <author><personname><firstname>Pavel</firstname><surname>Shved</surname></personname></author> |
| <author><personname><firstname>Denis</firstname><surname>Silakov</surname></personname></author> |
| </biblioentry> |
| </bibliography> |
| |
| </section> |