mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			576 lines
		
	
	
		
			49 KiB
		
	
	
	
		
			HTML
		
	
	
	
			
		
		
	
	
			576 lines
		
	
	
		
			49 KiB
		
	
	
	
		
			HTML
		
	
	
	
| <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | ||
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ABI Policy and Guidelines</title><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><meta name="keywords" content="C++, ABI, version, dynamic, shared, compatibility" /><meta name="keywords" content="ISO C++, library" /><meta name="keywords" content="ISO C++, runtime, library" /><link rel="home" href="../index.html" title="The GNU C++ Library" /><link rel="up" href="appendix_porting.html" title="Appendix B.  Porting and Maintenance" /><link rel="prev" href="test.html" title="Testing" /><link rel="next" href="api.html" title="API Evolution and Deprecation History" /></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">ABI Policy and Guidelines</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="test.html">Prev</a> </td><th width="60%" align="center">Appendix B. 
 | ||
|   Porting and Maintenance
 | ||
|   
 | ||
| </th><td width="20%" align="right"> <a accesskey="n" href="api.html">Next</a></td></tr></table><hr /></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="appendix.porting.abi"></a>ABI Policy and Guidelines</h2></div></div></div><p>
 | ||
| </p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="abi.cxx_interface"></a>The C++ Interface</h3></div></div></div><p>
 | ||
|   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.
 | ||
| </p><p>
 | ||
|   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.
 | ||
| </p><p>
 | ||
|   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
 | ||
|   <a class="link" href="abi.html#biblio.cxxabi" title="Itanium C++ ABI">Itanium C++ ABI</a>.
 | ||
| </p><p>
 | ||
|  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 class="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 class="code">-fpack-struct</code> and
 | ||
|   <code class="code">-fno-exceptions</code>, but include others: see the complete
 | ||
|   list in the GCC manual under the heading <a class="link" href="http://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code%20Gen%20Options" target="_top">Options
 | ||
|   for Code Generation Conventions</a>.
 | ||
| </p><p>
 | ||
|   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
 | ||
| <a class="link" href="configure.html" title="Configure">here</a>.
 | ||
| </p><p> 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:
 | ||
| </p><p>
 | ||
|   <span class="quote">“<span class="quote">
 | ||
|     library API + compiler ABI = library ABI
 | ||
|   </span>”</span>
 | ||
| </p><p>
 | ||
|  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.
 | ||
| </p><p>
 | ||
|   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.
 | ||
| </p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="abi.versioning"></a>Versioning</h3></div></div></div><p> 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.
 | ||
| </p><div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="abi.versioning.goals"></a>Goals</h4></div></div></div><p>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.
 | ||
| </p><p>
 | ||
| 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.
 | ||
| </p><p>Allows multiple, incompatible ABIs to coexist at the same time.
 | ||
| </p></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="abi.versioning.history"></a>History</h4></div></div></div><p>
 | ||
|  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.
 | ||
| </p><p>
 | ||
|   The following techniques are used:
 | ||
| </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>Release versioning on the libgcc_s.so binary. </p><p>This is implemented via file names and the ELF
 | ||
|     <code class="constant">DT_SONAME</code> mechanism (at least on ELF
 | ||
|     systems). It is versioned as follows:
 | ||
|     </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>GCC 3.x: libgcc_s.so.1</p></li><li class="listitem"><p>GCC 4.x: libgcc_s.so.1</p></li></ul></div><p>For m68k-linux the versions differ as follows: </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>GCC 3.4, GCC 4.x: libgcc_s.so.1
 | ||
|     when configuring <code class="code">--with-sjlj-exceptions</code>, or
 | ||
|     libgcc_s.so.2 </p></li></ul></div><p>For hppa-linux the versions differ as follows: </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>GCC 3.4, GCC 4.[0-1]: either libgcc_s.so.1
 | ||
|     when configuring <code class="code">--with-sjlj-exceptions</code>, or
 | ||
|     libgcc_s.so.2 </p></li><li class="listitem"><p>GCC 4.[2-7]: either libgcc_s.so.3 when configuring
 | ||
|     <code class="code">--with-sjlj-exceptions</code>) or libgcc_s.so.4
 | ||
|     </p></li></ul></div></li><li class="listitem"><p>Symbol versioning on the libgcc_s.so binary.</p><p>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.</p><p>This corresponds to the mapfile: gcc/libgcc-std.ver</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>GCC 3.0.0: GCC_3.0</p></li><li class="listitem"><p>GCC 3.3.0: GCC_3.3</p></li><li class="listitem"><p>GCC 3.3.1: GCC_3.3.1</p></li><li class="listitem"><p>GCC 3.3.2: GCC_3.3.2</p></li><li class="listitem"><p>GCC 3.3.4: GCC_3.3.4</p></li><li class="listitem"><p>GCC 3.4.0: GCC_3.4</p></li><li class="listitem"><p>GCC 3.4.2: GCC_3.4.2</p></li><li class="listitem"><p>GCC 3.4.4: GCC_3.4.4</p></li><li class="listitem"><p>GCC 4.0.0: GCC_4.0.0</p></li><li class="listitem"><p>GCC 4.1.0: GCC_4.1.0</p></li><li class="listitem"><p>GCC 4.2.0: GCC_4.2.0</p></li><li class="listitem"><p>GCC 4.3.0: GCC_4.3.0</p></li><li class="listitem"><p>GCC 4.4.0: GCC_4.4.0</p></li><li class="listitem"><p>GCC 4.5.0: GCC_4.5.0</p></li><li class="listitem"><p>GCC 4.6.0: GCC_4.6.0</p></li><li class="listitem"><p>GCC 4.7.0: GCC_4.7.0</p></li><li class="listitem"><p>GCC 4.8.0: GCC_4.8.0</p></li></ul></div></li><li class="listitem"><p>
 | ||
| 	Release versioning on the libstdc++.so binary, implemented in
 | ||
| 	the same way as the libgcc_s.so binary above. Listed is the
 | ||
| 	filename: <code class="constant">DT_SONAME</code> can be deduced from
 | ||
| 	the filename by removing the last two period-delimited numbers. For
 | ||
| 	example, filename <code class="filename">libstdc++.so.5.0.4</code>
 | ||
| 	corresponds to a <code class="constant">DT_SONAME</code> of
 | ||
| 	<code class="constant">libstdc++.so.5</code>. Binaries with equivalent
 | ||
| 	<code class="constant">DT_SONAME</code>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 <code class="constant">DT_SONAME</code> as the
 | ||
| 	preceding release.
 | ||
|       </p><p>It is versioned as follows:
 | ||
|     </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>GCC 3.0.0: libstdc++.so.3.0.0</p></li><li class="listitem"><p>GCC 3.0.1: libstdc++.so.3.0.1</p></li><li class="listitem"><p>GCC 3.0.2: libstdc++.so.3.0.2</p></li><li class="listitem"><p>GCC 3.0.3: libstdc++.so.3.0.2 (See Note 1)</p></li><li class="listitem"><p>GCC 3.0.4: libstdc++.so.3.0.4</p></li><li class="listitem"><p>GCC 3.1.0: libstdc++.so.4.0.0 <span class="emphasis"><em>(Incompatible with previous)</em></span></p></li><li class="listitem"><p>GCC 3.1.1: libstdc++.so.4.0.1</p></li><li class="listitem"><p>GCC 3.2.0: libstdc++.so.5.0.0 <span class="emphasis"><em>(Incompatible with previous)</em></span></p></li><li class="listitem"><p>GCC 3.2.1: libstdc++.so.5.0.1</p></li><li class="listitem"><p>GCC 3.2.2: libstdc++.so.5.0.2</p></li><li class="listitem"><p>GCC 3.2.3: libstdc++.so.5.0.3 (See Note 2)</p></li><li class="listitem"><p>GCC 3.3.0: libstdc++.so.5.0.4</p></li><li class="listitem"><p>GCC 3.3.1: libstdc++.so.5.0.5</p></li><li class="listitem"><p>GCC 3.4.0: libstdc++.so.6.0.0 <span class="emphasis"><em>(Incompatible with previous)</em></span></p></li><li class="listitem"><p>GCC 3.4.1: libstdc++.so.6.0.1</p></li><li class="listitem"><p>GCC 3.4.2: libstdc++.so.6.0.2</p></li><li class="listitem"><p>GCC 3.4.3: libstdc++.so.6.0.3</p></li><li class="listitem"><p>GCC 4.0.0: libstdc++.so.6.0.4</p></li><li class="listitem"><p>GCC 4.0.1: libstdc++.so.6.0.5</p></li><li class="listitem"><p>GCC 4.0.2: libstdc++.so.6.0.6</p></li><li class="listitem"><p>GCC 4.0.3: libstdc++.so.6.0.7</p></li><li class="listitem"><p>GCC 4.1.0: libstdc++.so.6.0.7</p></li><li class="listitem"><p>GCC 4.1.1: libstdc++.so.6.0.8</p></li><li class="listitem"><p>GCC 4.2.0: libstdc++.so.6.0.9</p></li><li class="listitem"><p>GCC 4.2.1: libstdc++.so.6.0.9 (See Note 3)</p></li><li class="listitem"><p>GCC 4.2.2: libstdc++.so.6.0.9</p></li><li class="listitem"><p>GCC 4.3.0: libstdc++.so.6.0.10</p></li><li class="listitem"><p>GCC 4.4.0: libstdc++.so.6.0.11</p></li><li class="listitem"><p>GCC 4.4.1: libstdc++.so.6.0.12</p></li><li class="listitem"><p>GCC 4.4.2: libstdc++.so.6.0.13</p></li><li class="listitem"><p>GCC 4.5.0: libstdc++.so.6.0.14</p></li><li class="listitem"><p>GCC 4.6.0: libstdc++.so.6.0.15</p></li><li class="listitem"><p>GCC 4.6.1: libstdc++.so.6.0.16</p></li><li class="listitem"><p>GCC 4.7.0: libstdc++.so.6.0.17</p></li><li class="listitem"><p>GCC 4.8.0: libstdc++.so.6.0.18</p></li><li class="listitem"><p>GCC 4.8.3: libstdc++.so.6.0.19</p></li><li class="listitem"><p>GCC 4.9.0: libstdc++.so.6.0.20</p></li><li class="listitem"><p>GCC 5.1.0: libstdc++.so.6.0.21</p></li><li class="listitem"><p>GCC 6.1.0: libstdc++.so.6.0.22</p></li><li class="listitem"><p>GCC 7.1.0: libstdc++.so.6.0.23</p></li><li class="listitem"><p>GCC 7.2.0: libstdc++.so.6.0.24</p></li><li class="listitem"><p>GCC 8.0.0: libstdc++.so.6.0.25</p></li><li class="listitem"><p>GCC 9.0.0: libstdc++.so.6.0.26</p></li></ul></div><p>
 | ||
|       Note 1: Error should be libstdc++.so.3.0.3.
 | ||
|     </p><p>
 | ||
|       Note 2: Not strictly required.
 | ||
|     </p><p>
 | ||
|       Note 3: This release (but not previous or subsequent) has one
 | ||
|       known incompatibility, see <a class="link" href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33678" target="_top">33678</a>
 | ||
|       in the GCC bug database.
 | ||
|     </p></li><li class="listitem"><p>Symbol versioning on the libstdc++.so binary.</p><p>mapfile: libstdc++-v3/config/abi/pre/gnu.ver</p><p>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.
 | ||
|    </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>GCC 3.0.0: (Error, not versioned)</p></li><li class="listitem"><p>GCC 3.0.1: (Error, not versioned)</p></li><li class="listitem"><p>GCC 3.0.2: (Error, not versioned)</p></li><li class="listitem"><p>GCC 3.0.3: (Error, not versioned)</p></li><li class="listitem"><p>GCC 3.0.4: (Error, not versioned)</p></li><li class="listitem"><p>GCC 3.1.0: GLIBCPP_3.1, CXXABI_1</p></li><li class="listitem"><p>GCC 3.1.1: GLIBCPP_3.1, CXXABI_1</p></li><li class="listitem"><p>GCC 3.2.0: GLIBCPP_3.2, CXXABI_1.2</p></li><li class="listitem"><p>GCC 3.2.1: GLIBCPP_3.2.1, CXXABI_1.2</p></li><li class="listitem"><p>GCC 3.2.2: GLIBCPP_3.2.2, CXXABI_1.2</p></li><li class="listitem"><p>GCC 3.2.3: GLIBCPP_3.2.2, CXXABI_1.2</p></li><li class="listitem"><p>GCC 3.3.0: GLIBCPP_3.2.2, CXXABI_1.2.1</p></li><li class="listitem"><p>GCC 3.3.1: GLIBCPP_3.2.3, CXXABI_1.2.1</p></li><li class="listitem"><p>GCC 3.3.2: GLIBCPP_3.2.3, CXXABI_1.2.1</p></li><li class="listitem"><p>GCC 3.3.3: GLIBCPP_3.2.3, CXXABI_1.2.1</p></li><li class="listitem"><p>GCC 3.4.0: GLIBCXX_3.4, CXXABI_1.3</p></li><li class="listitem"><p>GCC 3.4.1: GLIBCXX_3.4.1, CXXABI_1.3</p></li><li class="listitem"><p>GCC 3.4.2: GLIBCXX_3.4.2</p></li><li class="listitem"><p>GCC 3.4.3: GLIBCXX_3.4.3</p></li><li class="listitem"><p>GCC 4.0.0: GLIBCXX_3.4.4, CXXABI_1.3.1</p></li><li class="listitem"><p>GCC 4.0.1: GLIBCXX_3.4.5</p></li><li class="listitem"><p>GCC 4.0.2: GLIBCXX_3.4.6</p></li><li class="listitem"><p>GCC 4.0.3: GLIBCXX_3.4.7</p></li><li class="listitem"><p>GCC 4.1.1: GLIBCXX_3.4.8</p></li><li class="listitem"><p>GCC 4.2.0: GLIBCXX_3.4.9</p></li><li class="listitem"><p>GCC 4.3.0: GLIBCXX_3.4.10, CXXABI_1.3.2</p></li><li class="listitem"><p>GCC 4.4.0: GLIBCXX_3.4.11, CXXABI_1.3.3</p></li><li class="listitem"><p>GCC 4.4.1: GLIBCXX_3.4.12, CXXABI_1.3.3</p></li><li class="listitem"><p>GCC 4.4.2: GLIBCXX_3.4.13, CXXABI_1.3.3</p></li><li class="listitem"><p>GCC 4.5.0: GLIBCXX_3.4.14, CXXABI_1.3.4</p></li><li class="listitem"><p>GCC 4.6.0: GLIBCXX_3.4.15, CXXABI_1.3.5</p></li><li class="listitem"><p>GCC 4.6.1: GLIBCXX_3.4.16, CXXABI_1.3.5</p></li><li class="listitem"><p>GCC 4.7.0: GLIBCXX_3.4.17, CXXABI_1.3.6</p></li><li class="listitem"><p>GCC 4.8.0: GLIBCXX_3.4.18, CXXABI_1.3.7</p></li><li class="listitem"><p>GCC 4.8.3: GLIBCXX_3.4.19, CXXABI_1.3.7</p></li><li class="listitem"><p>GCC 4.9.0: GLIBCXX_3.4.20, CXXABI_1.3.8</p></li><li class="listitem"><p>GCC 5.1.0: GLIBCXX_3.4.21, CXXABI_1.3.9</p></li><li class="listitem"><p>GCC 6.1.0: GLIBCXX_3.4.22, CXXABI_1.3.10</p></li><li class="listitem"><p>GCC 7.1.0: GLIBCXX_3.4.23, CXXABI_1.3.11</p></li><li class="listitem"><p>GCC 7.2.0: GLIBCXX_3.4.24, CXXABI_1.3.11</p></li><li class="listitem"><p>GCC 8.0.0: GLIBCXX_3.4.25, CXXABI_1.3.11</p></li><li class="listitem"><p>GCC 9.0.0: GLIBCXX_3.4.26, CXXABI_1.3.11</p></li></ul></div></li><li class="listitem"><p>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.)
 | ||
|     </p><p>
 | ||
|     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.
 | ||
|     </p><p>
 | ||
|     It is versioned as follows, where 'n' is given by '-fabi-version=n':
 | ||
|     </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>GCC 3.0: 100</p></li><li class="listitem"><p>GCC 3.1: 100 (Error, should be 101)</p></li><li class="listitem"><p>GCC 3.2: 102</p></li><li class="listitem"><p>GCC 3.3: 102</p></li><li class="listitem"><p>GCC 3.4, GCC 4.x: 102 (when n=1)</p></li><li class="listitem"><p>GCC 3.4, GCC 4.x: 1000 + n (when n>1) </p></li><li class="listitem"><p>GCC 3.4, GCC 4.x: 999999 (when n=0)</p></li></ul></div><p></p></li><li class="listitem"><p>Changes to the default compiler option for
 | ||
|     <code class="code">-fabi-version</code>.
 | ||
|     </p><p>
 | ||
|     It is versioned as follows:
 | ||
|     </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>GCC 3.0: (Error, not versioned) </p></li><li class="listitem"><p>GCC 3.1: (Error, not versioned) </p></li><li class="listitem"><p>GCC 3.2: <code class="code">-fabi-version=1</code></p></li><li class="listitem"><p>GCC 3.3: <code class="code">-fabi-version=1</code></p></li><li class="listitem"><p>GCC 3.4, GCC 4.x: <code class="code">-fabi-version=2</code> <span class="emphasis"><em>(Incompatible with previous)</em></span></p></li><li class="listitem"><p>GCC 5 and higher: <code class="code">-fabi-version=0</code> <span class="emphasis"><em>(See GCC manual for meaning)</em></span></p></li></ul></div><p></p></li><li class="listitem"><p><a id="abi.versioning.__GLIBCXX__"></a>Incremental bumping of a library pre-defined macro. For releases
 | ||
|     before 3.4.0, the macro is <span class="symbol">__GLIBCPP__</span>. For later
 | ||
|     releases, it's <span class="symbol">__GLIBCXX__</span>. (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.
 | ||
|     </p><p>
 | ||
|     This macro is defined in the file
 | ||
|     <code class="filename">c++config</code> in the
 | ||
|     <code class="filename">libstdc++-v3/include/bits</code>
 | ||
|     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
 | ||
|     <code class="filename">gcc/DATESTAMP</code>, so for an official release its value
 | ||
|     is the same as the date of the release, which is given in the <a class="link" href="https://gcc.gnu.org/develop.html#timeline" target="_top">GCC Release
 | ||
|     Timeline</a>.
 | ||
|     </p><p>
 | ||
|     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
 | ||
|     <code class="literal">20160603</code> which is greater than the
 | ||
|     <code class="literal">20160427</code> 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 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.
 | ||
|     </p><p>
 | ||
|     It is versioned as follows:
 | ||
|     </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>GCC 3.0.0: <code class="literal">20010615</code></p></li><li class="listitem"><p>GCC 3.0.1: <code class="literal">20010819</code></p></li><li class="listitem"><p>GCC 3.0.2: <code class="literal">20011023</code></p></li><li class="listitem"><p>GCC 3.0.3: <code class="literal">20011220</code></p></li><li class="listitem"><p>GCC 3.0.4: <code class="literal">20020220</code></p></li><li class="listitem"><p>GCC 3.1.0: <code class="literal">20020514</code></p></li><li class="listitem"><p>GCC 3.1.1: <code class="literal">20020725</code></p></li><li class="listitem"><p>GCC 3.2.0: <code class="literal">20020814</code></p></li><li class="listitem"><p>GCC 3.2.1: <code class="literal">20021119</code></p></li><li class="listitem"><p>GCC 3.2.2: <code class="literal">20030205</code></p></li><li class="listitem"><p>GCC 3.2.3: <code class="literal">20030422</code></p></li><li class="listitem"><p>GCC 3.3.0: <code class="literal">20030513</code></p></li><li class="listitem"><p>GCC 3.3.1: <code class="literal">20030804</code></p></li><li class="listitem"><p>GCC 3.3.2: <code class="literal">20031016</code></p></li><li class="listitem"><p>GCC 3.3.3: <code class="literal">20040214</code></p></li><li class="listitem"><p>GCC 3.4.0: <code class="literal">20040419</code></p></li><li class="listitem"><p>GCC 3.4.1: <code class="literal">20040701</code></p></li><li class="listitem"><p>GCC 3.4.2: <code class="literal">20040906</code></p></li><li class="listitem"><p>GCC 3.4.3: <code class="literal">20041105</code></p></li><li class="listitem"><p>GCC 3.4.4: <code class="literal">20050519</code></p></li><li class="listitem"><p>GCC 3.4.5: <code class="literal">20051201</code></p></li><li class="listitem"><p>GCC 3.4.6: <code class="literal">20060306</code></p></li><li class="listitem"><p>GCC 4.0.0: <code class="literal">20050421</code></p></li><li class="listitem"><p>GCC 4.0.1: <code class="literal">20050707</code></p></li><li class="listitem"><p>GCC 4.0.2: <code class="literal">20050921</code></p></li><li class="listitem"><p>GCC 4.0.3: <code class="literal">20060309</code></p></li><li class="listitem"><p>
 | ||
|       GCC 4.1.0 and later: the GCC release date, as shown in the
 | ||
|       <a class="link" href="https://gcc.gnu.org/develop.html#timeline" target="_top">GCC
 | ||
|       Release Timeline</a>
 | ||
|     </p></li></ul></div><p></p></li><li class="listitem"><p>
 | ||
|     Since GCC 7, incremental bumping of a library pre-defined macro,
 | ||
|     <span class="symbol">_GLIBCXX_RELEASE</span>. 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 <span class="symbol">__GNUC__</span>.
 | ||
|     This macro can be used when libstdc++ is used with a non-GNU
 | ||
|     compiler where <span class="symbol">__GNUC__</span> is not defined, or has a
 | ||
|     different value that doesn't correspond to the libstdc++ version.
 | ||
|     </p><p>
 | ||
|     This macro is defined in the file
 | ||
|     <code class="filename">c++config</code> in the
 | ||
|     <code class="filename">libstdc++-v3/include/bits</code>
 | ||
|     directory and is generated automatically by autoconf as part of the
 | ||
|     configure-time generation of
 | ||
|     <code class="filename">config.h</code> and subsequently
 | ||
|     <code class="filename"><bits/c++config.h></code>.
 | ||
|     </p></li><li class="listitem"><p>
 | ||
|     Historically, incremental bumping of a library pre-defined macro,
 | ||
|     <span class="symbol">_GLIBCPP_VERSION</span>. 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 <span class="symbol">_GLIBCXX_VERSION</span>),
 | ||
|     and is not defined in 4.0.0 and higher.
 | ||
|     </p><p>
 | ||
|     This macro is defined in the same file as
 | ||
|     <span class="symbol">_GLIBCXX_RELEASE</span>, described above.
 | ||
|     </p><p>
 | ||
|     It is versioned as follows:
 | ||
|     </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>GCC 3.0.0: <code class="literal">"3.0.0"</code></p></li><li class="listitem"><p>GCC 3.0.1: <code class="literal">"3.0.0"</code> (Error, should be <code class="literal">"3.0.1"</code>)</p></li><li class="listitem"><p>GCC 3.0.2: <code class="literal">"3.0.0"</code> (Error, should be <code class="literal">"3.0.2"</code>)</p></li><li class="listitem"><p>GCC 3.0.3: <code class="literal">"3.0.0"</code> (Error, should be <code class="literal">"3.0.3"</code>)</p></li><li class="listitem"><p>GCC 3.0.4: <code class="literal">"3.0.0"</code> (Error, should be <code class="literal">"3.0.4"</code>)</p></li><li class="listitem"><p>GCC 3.1.0: <code class="literal">"3.1.0"</code></p></li><li class="listitem"><p>GCC 3.1.1: <code class="literal">"3.1.1"</code></p></li><li class="listitem"><p>GCC 3.2.0: <code class="literal">"3.2"</code></p></li><li class="listitem"><p>GCC 3.2.1: <code class="literal">"3.2.1"</code></p></li><li class="listitem"><p>GCC 3.2.2: <code class="literal">"3.2.2"</code></p></li><li class="listitem"><p>GCC 3.2.3: <code class="literal">"3.2.3"</code></p></li><li class="listitem"><p>GCC 3.3.0: <code class="literal">"3.3"</code></p></li><li class="listitem"><p>GCC 3.3.1: <code class="literal">"3.3.1"</code></p></li><li class="listitem"><p>GCC 3.3.2: <code class="literal">"3.3.2"</code></p></li><li class="listitem"><p>GCC 3.3.3: <code class="literal">"3.3.3"</code></p></li><li class="listitem"><p>GCC 3.4: <code class="literal">"version-unused"</code></p></li><li class="listitem"><p>GCC 4 and later: not defined</p></li></ul></div><p></p></li><li class="listitem"><p>
 | ||
|     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.
 | ||
|     </p><p>
 | ||
|     All C++ includes are installed in
 | ||
|     <code class="filename">include/c++</code>, 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).
 | ||
|     </p><p>
 | ||
|     C++ includes are versioned as follows:
 | ||
|     </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>GCC 3.0.0: include/g++-v3</p></li><li class="listitem"><p>GCC 3.0.1: include/g++-v3</p></li><li class="listitem"><p>GCC 3.0.2: include/g++-v3</p></li><li class="listitem"><p>GCC 3.0.3: include/g++-v3</p></li><li class="listitem"><p>GCC 3.0.4: include/g++-v3</p></li><li class="listitem"><p>GCC 3.1.0: include/g++-v3</p></li><li class="listitem"><p>GCC 3.1.1: include/c++/3.1.1</p></li><li class="listitem"><p>GCC 3.2.0: include/c++/3.2</p></li><li class="listitem"><p>GCC 3.2.1: include/c++/3.2.1</p></li><li class="listitem"><p>GCC 3.2.2: include/c++/3.2.2</p></li><li class="listitem"><p>GCC 3.2.3: include/c++/3.2.3</p></li><li class="listitem"><p>GCC 3.3.0: include/c++/3.3</p></li><li class="listitem"><p>GCC 3.3.1: include/c++/3.3.1</p></li><li class="listitem"><p>GCC 3.3.2: include/c++/3.3.2</p></li><li class="listitem"><p>GCC 3.3.3: include/c++/3.3.3</p></li><li class="listitem"><p>GCC 3.4.x: include/c++/3.4.x</p></li><li class="listitem"><p>GCC 4.x.y: include/c++/4.x.y</p></li><li class="listitem"><p>GCC 5.x.0: include/c++/5.x.0</p></li><li class="listitem"><p>GCC 6.x.0: include/c++/6.x.0</p></li><li class="listitem"><p>GCC 7.x.0: include/c++/7.x.0</p></li><li class="listitem"><p>GCC 8.x.0: include/c++/8.x.0</p></li></ul></div><p></p></li></ol></div><p>
 | ||
|   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.
 | ||
| </p></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="abi.versioning.prereq"></a>Prerequisites</h4></div></div></div><p>
 | ||
|       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.
 | ||
|     </p><p>
 | ||
|       On top of all that, an additional constraint: libstdc++ did not
 | ||
|       attempt to version symbols (or age gracefully, really) until
 | ||
|       version 3.1.0.
 | ||
|     </p><p>
 | ||
|       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.
 | ||
|     </p></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="abi.versioning.config"></a>Configuring</h4></div></div></div><p>
 | ||
|       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.
 | ||
|     </p><p>
 | ||
|       For more information on configure options, including ABI
 | ||
|       impacts, see:
 | ||
|       <a class="link" href="configure.html" title="Configure">here</a>
 | ||
|     </p><p>
 | ||
|       There is one flag that explicitly deals with symbol versioning:
 | ||
|       --enable-symvers.
 | ||
|     </p><p>
 | ||
|       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.
 | ||
|     </p></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="abi.versioning.active"></a>Checking Active</h4></div></div></div><p>
 | ||
|       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):
 | ||
|     </p><pre class="screen">
 | ||
| <code class="computeroutput">
 | ||
|   checking versioning on shared library symbols... gnu
 | ||
| </code>
 | ||
| </pre><p>
 | ||
|   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.
 | ||
| </p><p>
 | ||
|   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:
 | ||
| </p><pre class="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
 | ||
| </pre><p>
 | ||
| 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:
 | ||
| </p><p>
 | ||
|    <code class="code">U _ZNSt8ios_base4InitC1Ev@@GLIBCXX_3.4</code>
 | ||
| </p><p>
 | ||
| On Solaris 2, you can use <code class="code">pvs -r</code> instead:
 | ||
| </p><pre class="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);
 | ||
| </pre><p>
 | ||
| <code class="code">ldd -v</code> works too, but is very verbose.
 | ||
| </p></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="abi.changes_allowed"></a>Allowed Changes</h3></div></div></div><p>
 | ||
| The following will cause the library minor version number to
 | ||
| increase, say from "libstdc++.so.3.0.4" to "libstdc++.so.3.0.5".
 | ||
| </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>Adding an exported global or static data member</p></li><li class="listitem"><p>Adding an exported function, static or non-virtual member function</p></li><li class="listitem"><p>Adding an exported symbol or symbols by additional instantiations</p></li></ol></div><p>
 | ||
| Other allowed changes are possible.
 | ||
| </p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="abi.changes_no"></a>Prohibited Changes</h3></div></div></div><p>
 | ||
| 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".
 | ||
| </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>Changes in the gcc/g++ compiler ABI</p></li><li class="listitem"><p>Changing size of an exported symbol</p></li><li class="listitem"><p>Changing alignment of an exported symbol</p></li><li class="listitem"><p>Changing the layout of an exported symbol</p></li><li class="listitem"><p>Changing mangling on an exported symbol</p></li><li class="listitem"><p>Deleting an exported symbol</p></li><li class="listitem"><p>Changing the inheritance properties of a type by adding or removing
 | ||
|     base classes</p></li><li class="listitem"><p>
 | ||
|   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.
 | ||
| </p></li><li class="listitem"><p> 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 <a class="link" href="https://itanium-cxx-abi.github.io/cxx-abi/abi.html#calls" target="_top">Function
 | ||
| Calling Conventions and APIs</a>
 | ||
|  of the C++ ABI documentation for further details.
 | ||
| </p></li></ol></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="abi.impl"></a>Implementation</h3></div></div></div><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>
 | ||
|      Separation of interface and implementation
 | ||
|    </p><p>
 | ||
|      This is accomplished by two techniques that separate the API from
 | ||
|      the ABI: forcing undefined references to link against a library
 | ||
|      binary for definitions.
 | ||
|    </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">Include files have declarations, source files have defines</span></dt><dd><p>
 | ||
| 	For non-templatized types, such as much of <code class="code">class
 | ||
| 	locale</code>, the appropriate standard C++ include, say
 | ||
| 	<code class="code">locale</code>, can contain full declarations, while
 | ||
| 	various source files (say <code class="code"> locale.cc, locale_init.cc,
 | ||
| 	localename.cc</code>) contain definitions.
 | ||
|       </p></dd><dt><span class="term">Extern template on required types</span></dt><dd><p>
 | ||
|        For parts of the standard that have an explicit list of
 | ||
|        required instantiations, the GNU extension syntax <code class="code"> extern
 | ||
|        template </code> can be used to control where template
 | ||
|        definitions reside. By marking required instantiations as
 | ||
|        <code class="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 class="code">
 | ||
|        char</code> and <code class="code"> wchar_t</code> instantiations, and
 | ||
|        includes <code class="code"> basic_string</code>, the locale facets, and the
 | ||
|        types in <code class="code"> iostreams</code>.
 | ||
|      </p></dd></dl></div><p>
 | ||
|    In addition, these techniques have the additional benefit that they
 | ||
|    reduce binary size, which can increase runtime performance.
 | ||
|  </p></li><li class="listitem"><p>
 | ||
|      Namespaces linking symbol definitions to export mapfiles
 | ||
|    </p><p>
 | ||
|      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.
 | ||
|    </p><p>The following namespaces are transformed by the mapfile:</p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="code">namespace std</code></span></dt><dd><p> Defaults to exporting all symbols in label
 | ||
| <code class="code">GLIBCXX</code> that do not begin with an underscore, i.e.,
 | ||
| <code class="code">__test_func</code> would not be exported by default. Select
 | ||
| exceptional symbols are allowed to be visible.</p></dd><dt><span class="term"><code class="code">namespace __gnu_cxx</code></span></dt><dd><p> Defaults to not exporting any symbols in label
 | ||
| <code class="code">GLIBCXX</code>, select items are allowed to be visible.</p></dd><dt><span class="term"><code class="code">namespace __gnu_internal</code></span></dt><dd><p> Defaults to not exported, no items are allowed to be visible.</p></dd><dt><span class="term"><code class="code">namespace __cxxabiv1</code>, aliased to <code class="code"> namespace abi</code></span></dt><dd><p> Defaults to not exporting any symbols in label
 | ||
| <code class="code">CXXABI</code>, select items are allowed to be visible.</p></dd></dl></div><p>
 | ||
| </p></li><li class="listitem"><p>Freezing the API</p><p>Disallowed changes, as above, are not made on a stable release
 | ||
| branch. Enforcement tends to be less strict with GNU extensions that
 | ||
| standard includes.</p></li></ol></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="abi.testing"></a>Testing</h3></div></div></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="abi.testing.single"></a>Single ABI Testing</h4></div></div></div><p>
 | ||
|       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.
 | ||
|     </p><p>
 | ||
|       Testing the C++ compiler ABI can be done various ways.
 | ||
|     </p><p>
 | ||
|       One.  Intel ABI checker.
 | ||
|     </p><p>
 | ||
| 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.
 | ||
| </p><p>
 | ||
| Three.
 | ||
| Involves using the vlad.consistency test framework. This has also been
 | ||
| discussed on the gcc mailing lists.
 | ||
| </p><p>
 | ||
| Testing the C++ library ABI can also be done various ways.
 | ||
| </p><p>
 | ||
| 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)
 | ||
| </p><p>
 | ||
| Details on how to set this kind of test up can be found here:
 | ||
| http://gcc.gnu.org/ml/gcc/2002-08/msg00142.html
 | ||
| </p><p>
 | ||
| Two.
 | ||
| Use the 'make check-abi' rule in the libstdc++ Makefile.
 | ||
| </p><p>
 | ||
| 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 <span class="emphasis"><em>default</em></span>
 | ||
| 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.
 | ||
| </p><p>
 | ||
| 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.
 | ||
| </p><p>
 | ||
| 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.
 | ||
| </p><p>
 | ||
| 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.)
 | ||
| </p><p>
 | ||
| Perhaps there are other C++ ABI checkers. If so, please notify
 | ||
| us. We'd like to know about them!
 | ||
| </p></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="abi.testing.multi"></a>Multiple ABI Testing</h4></div></div></div><p>
 | ||
| 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.
 | ||
| </p><p> As above, libone is constructed as follows: </p><pre class="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
 | ||
| </pre><p> And, libtwo is constructed as follows: </p><pre class="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
 | ||
| </pre><p> ...with the resulting libraries looking like </p><pre class="screen">
 | ||
| <code class="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)
 | ||
| </code>
 | ||
| </pre><p>
 | ||
|   Then, the "C" compiler is used to compile a source file that uses
 | ||
|   functions from each library.
 | ||
| </p><pre class="programlisting">
 | ||
| gcc test.c -g -O2 -L. -lone -ltwo /usr/lib/libstdc++.so.5 /usr/lib/libstdc++.so.6
 | ||
| </pre><p>
 | ||
|   Which gives the expected:
 | ||
| </p><pre class="screen">
 | ||
| <code class="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)
 | ||
| </code>
 | ||
| </pre><p>
 | ||
|   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.
 | ||
| </p></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="abi.issues"></a>Outstanding Issues</h3></div></div></div><p>
 | ||
|   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.
 | ||
| </p><p>
 | ||
|   For more background on this issue, see these bugzilla entries:
 | ||
| </p><p>
 | ||
| <a class="link" href="http://gcc.gnu.org/PR24660" target="_top">24660: versioning weak symbols in libstdc++</a>
 | ||
| </p><p>
 | ||
| <a class="link" href="http://gcc.gnu.org/PR19664" target="_top">19664: libstdc++ headers should have pop/push of the visibility around the declarations</a>
 | ||
| </p></div><div class="bibliography"><div class="titlepage"><div><div><h3 class="title"><a id="abi.biblio"></a>Bibliography</h3></div></div></div><div class="biblioentry"><a id="biblio.abicheck"></a><p>[biblio.abicheck] <span class="title"><em>
 | ||
| 	<a class="link" href="http://abicheck.sourceforge.net" target="_top">
 | ||
| 	  ABIcheck
 | ||
| 	</a>
 | ||
|       </em>. </span></p></div><div class="biblioentry"><a id="biblio.cxxabi"></a><p>[biblio.cxxabi] <span class="title"><em>
 | ||
| 	<a class="link" href="https://itanium-cxx-abi.github.io/cxx-abi/" target="_top">
 | ||
| 	  Itanium C++ ABI
 | ||
| 	</a>
 | ||
|       </em>. </span></p></div><div class="biblioentry"><a id="id-1.3.6.3.6.10.4"></a><p><span class="title"><em>
 | ||
| 	<a class="link" href="https://software.intel.com/en-us/articles/intel-compilers-for-linux-compatibility-with-gnu-compilers" target="_top">
 | ||
| 	Intel Compilers for Linux: Compatibility with GNU Compilers
 | ||
| 	</a>
 | ||
|       </em>. </span></p></div><div class="biblioentry"><a id="id-1.3.6.3.6.10.5"></a><p><span class="title"><em>
 | ||
| 	<a class="link" href="https://docs.oracle.com/cd/E23824_01/html/819-0690/index.html" target="_top">
 | ||
| 	Linker and Libraries Guide (document 819-0690)
 | ||
| 	</a>
 | ||
|       </em>. </span></p></div><div class="biblioentry"><a id="id-1.3.6.3.6.10.6"></a><p><span class="title"><em>
 | ||
| 	<a class="link" href="https://docs.oracle.com/cd/E19422-01/819-3689/" target="_top">
 | ||
|       Sun Studio 11: C++ Migration Guide (document 819-3689)
 | ||
| 	</a>
 | ||
|       </em>. </span></p></div><div class="biblioentry"><a id="id-1.3.6.3.6.10.7"></a><p><span class="title"><em>
 | ||
| 	<a class="link" href="https://www.akkadia.org/drepper/dsohowto.pdf" target="_top">
 | ||
|       How to Write Shared Libraries
 | ||
| 	</a>
 | ||
|       </em>. </span><span class="author"><span class="firstname">Ulrich</span> <span class="surname">Drepper</span>. </span></p></div><div class="biblioentry"><a id="id-1.3.6.3.6.10.8"></a><p><span class="title"><em>
 | ||
| 	<a class="link" href="http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ihi0036b/index.html" target="_top">
 | ||
|       C++ ABI for the ARM Architecture
 | ||
| 	</a>
 | ||
|       </em>. </span></p></div><div class="biblioentry"><a id="id-1.3.6.3.6.10.9"></a><p><span class="title"><em>
 | ||
| 	<a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1976.html" target="_top">
 | ||
|       Dynamic Shared Objects: Survey and Issues
 | ||
| 	</a>
 | ||
|       </em>. </span><span class="subtitle">
 | ||
|       ISO C++ J16/06-0046
 | ||
|     . </span><span class="author"><span class="firstname">Benjamin</span> <span class="surname">Kosnik</span>. </span></p></div><div class="biblioentry"><a id="id-1.3.6.3.6.10.10"></a><p><span class="title"><em>
 | ||
| 	<a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2013.html" target="_top">
 | ||
| 	Versioning With Namespaces
 | ||
| 	</a>
 | ||
|       </em>. </span><span class="subtitle">
 | ||
|       ISO C++ J16/06-0083
 | ||
|     . </span><span class="author"><span class="firstname">Benjamin</span> <span class="surname">Kosnik</span>. </span></p></div><div class="biblioentry"><a id="id-1.3.6.3.6.10.11"></a><p><span class="title"><em>
 | ||
| 	<a class="link" href="http://syrcose.ispras.ru/2009/files/02_paper.pdf" target="_top">
 | ||
|       Binary Compatibility of Shared Libraries Implemented in C++
 | ||
|       on GNU/Linux Systems
 | ||
| 	</a>
 | ||
|       </em>. </span><span class="subtitle">
 | ||
|       SYRCoSE 2009
 | ||
|     . </span><span class="author"><span class="firstname">Pavel</span> <span class="surname">Shved</span>. </span><span class="author"><span class="firstname">Denis</span> <span class="surname">Silakov</span>. </span></p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="test.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="appendix_porting.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="api.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Testing </td><td width="20%" align="center"><a accesskey="h" href="../index.html">Home</a></td><td width="40%" align="right" valign="top"> API Evolution and Deprecation History</td></tr></table></div></body></html> |