Skip to content

Commit ab24876

Browse files
authored
[C++] Document the Stable ABI Compatibility Policy (#7)
* copy over changes from CXX-2967
1 parent e13d787 commit ab24876

File tree

4 files changed

+586
-80
lines changed

4 files changed

+586
-80
lines changed

snooty.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ intersphinx = [
88
]
99

1010
toc_landing_pages = [
11-
"/installation"
11+
"/installation",
12+
"/api-abi-versioning"
1213
]
1314

1415
sharedinclude_root = "https://raw.githubusercontent.com/10gen/docs-shared/main/"

source/api-abi-versioning.txt

Lines changed: 244 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -7,136 +7,301 @@ API and ABI Versioning
77
.. contents:: On this page
88
:local:
99
:backlinks: none
10-
:depth: 1
10+
:depth: 2
1111
:class: singlecol
1212

1313
.. facet::
1414
:name: genre
1515
:values: reference
1616

17+
.. toctree::
18+
:titlesonly:
19+
:maxdepth: 1
20+
21+
/api-abi-versioning/api-versioning
22+
/api-abi-versioning/abi-versioning
23+
24+
For brevity, this page may describe properties and features as-if they only apply to the bsoncxx library.
25+
Unless stated otherwise, one may assume the properties and features described are similarly applicable to the mongocxx library.
26+
1727
API Versioning
1828
--------------
1929

20-
- We use `semantic versioning <http://semver.org/>`__.
21-
- bsoncxx and mongocxx both define corresponding CMake variables for MAJOR, MINOR, and PATCH.
30+
See :ref:`API Versioning <cpp-api-versioning-policy>`.
2231

2332
ABI Versioning
2433
--------------
2534

26-
- Both bsoncxx and mongocxx both have a single scalar ABI version.
27-
- Only bump ABI version on **incompatible** ABI change (not for ABI additions).
28-
- **We stay on ABI version \_noabi (without bumping for incompatible changes) until ABI is stable.**
35+
See :ref:`ABI Versioning <cpp-abi-versioning-policy>`.
36+
37+
Header File Structure
38+
---------------------
39+
40+
The public header files of the bsoncxx library are organized by ABI namespace:
41+
42+
.. code-block:: cpp
43+
44+
${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/
45+
└── bsoncxx/
46+
├── v_noabi/bsoncxx/
47+
│ └── ...
48+
├── v1/bsoncxx/
49+
│ └── ...
50+
├── v2/bsoncxx/
51+
│ └── ...
52+
└── vN/bsoncxx/
53+
└── ...
2954

30-
Parallel Header Installation
31-
----------------------------
55+
For forward compatibility, a public header file in an ABI namespace directory ``vA`` may include a header file in a *newer* ABI namespace directory ``vB``, where ``A < B``.
56+
Such forward compatibility include directives, when supported, will be explicitly documented.
57+
For any given public API entity, we recommend including its corresponding header
58+
from the *latest* ABI namespace directory whenever available.
3259

33-
- For mongocxx, install all headers to ``$PREFIX/mongocxx/v$ABI/``.
34-
- For bsoncxx, install all headers to ``$PREFIX/bsoncxx/v$ABI/``.
35-
- We install a pkg-config file to shield consumers from this complexity.
60+
.. important::
3661

37-
Sonames and Symlinks
38-
--------------------
62+
For backward compatibility, the ``bsoncxx/v_noabi/`` ABI namespace directory is added to include paths such that ``#include <bsoncxx/example.hpp>`` is equivalent to ``#include <bsoncxx/v_noabi/bsoncxx/example.hpp>``. Relying on this behavior is discouraged: we recommend explicitly including ``#include <bsoncxx/v_noabi/bsoncxx/example.hpp>`` instead.
3963

4064
.. note::
4165

42-
- Below examples are given for libmongocxx, but also apply to libbsoncxx
66+
The stability of an *undocumented* include directive is not supported.
67+
68+
Package files are installed to subdirectories in ``${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/``.
69+
Users are strongly encouraged to use these package files to obtain bsoncxx library header (as well for linking and the setting of compile flags).
70+
Manual configuration of include paths to obtain bsoncxx header files is not recommended.
71+
Package files are described further below.
72+
73+
In all cases, **CMake package config files are the recommended method for importing C++ driver libraries.**
74+
75+
Library Filenames
76+
-----------------
77+
78+
The filename and presence of symlinks depends on the platform and toolchain used to build the library, as well as the library type (shared vs. static).
79+
80+
Shared Libraries
81+
~~~~~~~~~~~~~~~~
82+
83+
.. important::
84+
85+
Shared libraries on Windows when configured with the MSVC toolchain on
86+
Windows are treated differently due to Windows-specific special
87+
considerations. See :ref:`Shared Libraries (MSVC Only) <cpp-shared-lib-msvc>` below.
88+
89+
The "real name" of shared libraries use the following pattern:
90+
91+
.. code-block:: none
92+
93+
lib<basename>.so.<api-version-number>
94+
95+
where:
96+
97+
- ``<basename>`` corresponds to the ``BSONCXX_OUTPUT_BASENAME`` CMake configuration variable (``MONGOCXX_OUTPUT_BASENAME`` for the mongocxx library). By default, this is set to ``bsoncxx`` and ``mongocxx``. The basename of a static library is suffixed with ``-static``.
98+
- ``<api-version-number>`` is the MAJOR, MINOR, and PATCH version for the given build configuration, corresponding to the ``BUILD_VERSION`` CMake configuration variable. (Note: explicitly setting this configuration variable should not be necessary in regular use of the C++ driver.)
99+
- API version number extensions are *not* included in the real name (e.g. the ``-alpha`` in ``1.2.3-alpha``).
100+
101+
Examples of expected library real names include:
102+
103+
.. code-block:: none
104+
105+
libbsoncxx.so.1.0.0
106+
libbsoncxx.so.2.3.4
107+
108+
CMake's ``SOVERSION`` target property and "namelink" behavior is used to also install symlinks to the library directory consistent with the Linux soname convention.
109+
These symlinks include the ABI version number as part of the library soname.
110+
111+
For example, the following lib directory contains the expected library files for a bsoncxx library with API version ``1.2.3`` and ABI version ``10``, where ``a -> b`` indicates ``a`` is a symlink to ``b``:
112+
113+
.. code-block:: none
43114

44-
- DSO refers to Dynamic Shared Object, to use Ulrich Drepper’s terminology
115+
${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/
116+
├── libbsoncxx.so.1.2.3
117+
├── libbsoncxx.so.10 -> libbsoncxx.so.1.2.3
118+
├── libbsoncxx.so -> libbsoncxx.so.10
119+
├── cmake/bsoncxx-1.2.3/
120+
│ ├── bsoncxx-config.cmake
121+
│ └── ...
122+
└── pkgconfig/
123+
└── libbsoncxx.pc
45124

46-
Windows (MSVC only)
47-
~~~~~~~~~~~~~~~~~~~
125+
The name of the CMake package for bsoncxx libraries is controlled by ``BSONCXX_OUTPUT_BASENAME`` (``MONGOCXX_OUTPUT_BASENAME`` for mongocxx libraries).
126+
They should be imported according to CMake's `Config Mode Search Procedure <https://cmake.org/cmake/help/latest/command/find_package.html#config-mode-search-procedure>`__.
127+
For example, assuming the C++ driver was installed to a prefix ``$INSTALLDIR``:
48128

49-
Since version 3.10.0, the physical filename for CXX Driver libraries is different
50-
from other platforms when built with the MSVC toolchain on Windows
51-
(even when the CMake generator is not Visual Studio).
129+
.. code-block:: bash
130+
131+
# The CMake package may be imported via CMAKE_PREFIX_PATH (recommended)...
132+
cmake -S example -B example-build -D CMAKE_PREFIX_PATH="$INSTALLDIR"
133+
134+
# Or via <PackageName>_ROOT (assuming BSONCXX_OUTPUT_NAME=bsoncxx)...
135+
cmake -S example -B example-build -D bsoncxx_ROOT="$INSTALLDIR"
136+
137+
# Or via ``PATHS`` in the ``find_package()`` command... or etc.
138+
# find_package(bsoncxx CONFIG REQUIRED PATHS "$INSTALLDIR")
139+
140+
.. note::
141+
142+
The C Driver is a required dependency for the C++ Driver. The CMake package config
143+
files for the C Driver may also need to be imported using the same (or
144+
similar) approach to satisfy this dependency.
145+
146+
Although the C++ Driver also provides pkg-config files, users are strongly
147+
encouraged to use CMake package config files instead.
148+
149+
The name of the pkg-config file for bsoncxx libraries is also controlled by ``BSONCXX_OUTPUT_NAME`` and follow the pattern ``lib<basename>.pc``.
150+
The ``PKG_CONFIG_PATH`` environment variable may need to be used to augment
151+
pkg-config's search path, e.g.:
152+
153+
.. code-block:: bash
154+
155+
bsoncxx_cflags="$(PKG_CONFIG_PATH="$INSTALLDIR" pkg-config --cflags "libbsoncxx >= 1.2.3")"
156+
bsoncxx_ldflags="$(PKG_CONFIG_PATH="$INSTALLDIR" pkg-config --libs "libbsoncxx >= 1.2.3")"
157+
g++ $bsoncxx_cflags -c example-a.cpp
158+
g++ $bsoncxx_cflags -c example-b.cpp
159+
g++ $bsoncxx_ldflags -o example example-a.o example-b.o
160+
161+
.. _cpp-shared-lib-msvc:
162+
163+
Shared Libraries (MSVC Only)
164+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
165+
166+
Since version 3.10.0, the shared libraries when built with the MSVC toolchain on Windows (even when the CMake generator is not Visual Studio) use a different naming scheme from other platforms.
52167
To restore prior behavior, which is similar to other platforms, set ``ENABLE_ABI_TAG_IN_LIBRARY_FILENAMES=OFF``.
53168

54-
- Physical filename for a DSO is ``mongocxx-$ABI-$TAG.dll``
55-
- Physical filename for a static library is ``mongocxx-static-$TAG.lib``
169+
The name of shared libraries (aka the "output name") use the following pattern (file extension excluded):
56170

57-
Where ``$TAG`` is a triplet of letters indicating:
171+
.. code-block:: none
172+
173+
<basename>-v<abi-version-number>-<abi-tag>
174+
175+
where:
176+
177+
- ``<basename>`` corresponds to the ``BSONCXX_OUTPUT_BASENAME`` CMake configuration variable (``MONGOCXX_OUTPUT_BASENAME`` for the mongocxx library). By default, this is set to ``bsoncxx`` and ``mongocxx``. The basename of a static library is suffixed with ``-static``.
178+
- ``<abi-version-number>`` corresponds to the current ABI version number.
179+
- ``<abi-tag>`` describes known properties that affect the binary compatibility of the shared library.
180+
181+
The ``<abi-tag>`` is a triplet of letters indicating:
58182

59183
- Build Type
60184
- mongoc Link Type
61185
- Polyfill Library
62186

63-
This is followed by a suffix describing the toolset and runtime library used to build the library.
187+
This is followed by a suffix describing the toolset and runtime library used to
188+
build the library. The exact contents of the suffix depend on the build configuration.
64189

65-
Some examples of common DSO filenames expected to be generated include:
190+
Examples of expected library filenames (with a brief description of notable features) include:
66191

67-
- ``mongocxx-v_noabi-rhs-x64-v142-md.dll`` (release build configuration)
68-
- ``mongocxx-v_noabi-dhs-x64-v142-mdd.dll`` (debug build configuration)
69-
- ``mongocxx-v_noabi-rts-x64-v142-md.dll`` (link with mongoc statically)
70-
- ``mongocxx-v_noabi-rhi-x64-v142-md.dll`` (bsoncxx polyfill library)
71-
- ``mongocxx-v_noabi-rhm-x64-v142-md.dll`` (mnmlstc/core polyfill library)
72-
- ``mongocxx-v_noabi-rhb-x64-v142-md.dll`` (Boost polyfill library)
192+
- ``bsoncxx-v_noabi-rhs-x64-v142-md.dll`` (release build configuration)
193+
- ``bsoncxx-v_noabi-dhs-x64-v142-mdd.dll`` (debug build configuration)
194+
- ``bsoncxx-v_noabi-rts-x64-v142-md.dll`` (link with mongoc static libraries)
195+
- ``bsoncxx-v_noabi-rhi-x64-v142-md.dll`` (bsoncxx as polyfill library)
196+
- ``bsoncxx-v_noabi-rhm-x64-v142-md.dll`` (mnmlstc/core as polyfill library)
197+
- ``bsoncxx-v_noabi-rhb-x64-v142-md.dll`` (Boost as polyfill library)
198+
- ``bsoncxx-v1-rhs-x64-v142-md.dll`` (ABI version number 1)
199+
- ``bsoncxx-v2-rhs-x64-v142-md.dll`` (ABI version number 2)
73200

74-
This allows libraries built with different build configurations (and different runtime library requirements) to be built and installed without conflicting with each other.
75201

76-
See references to ``ENABLE_ABI_TAG_IN_LIBRARY_FILENAMES`` and related code in the CMake configuration for more details.
202+
.. note::
203+
204+
This example also applies to the companion ``.lib`` file.
205+
206+
This naming scheme allows the bsoncxx library to be built and installed with
207+
different build configurations (e.g. Debug vs. Release) and different runtime
208+
library requirements (e.g. MultiThreadedDLL vs. MultiThreadedDebugDLL) in
209+
parallel and without conflict. See references to
210+
``ENABLE_ABI_TAG_IN_LIBRARY_FILENAMES`` and related code in the CMake
211+
configuration for more details.
212+
213+
For example, the following install prefix directory contains the expected debug *and* release library files for a bsoncxx library with API version ``1.2.3`` and ABI version ``10`` (the bin directory is included to account for ``.dll`` files):
214+
215+
.. code-block:: none
216+
217+
${CMAKE_INSTALL_PREFIX}/
218+
├── ${CMAKE_INSTALL_BINDIR}/
219+
│ ├── bsoncxx-v10-dhs-x64-v142-mdd.dll
220+
│ └── bsoncxx-v10-rhs-x64-v142-md.dll
221+
└── ${CMAKE_INSTALL_LIBDIR}/
222+
├── bsoncxx-v10-dhs-x64-v142-mdd.lib
223+
├── bsoncxx-v10-rhs-x64-v142-md.lib
224+
├── cmake/bsoncxx-1.2.3/
225+
│ ├── bsoncxx-config.cmake
226+
│ └── ...
227+
└── pkgconfig/
228+
├── libbsoncxx-v10-dhs-x64-v142-mdd.pc
229+
└── libbsoncxx-v10-rhs-x64-v142-md.pc
230+
231+
The CMake package config files are the same as the regular (non-MSVC) shared library behavior described above.
77232

78-
Other Platforms (Linux, MacOS)
79-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
233+
.. note::
234+
235+
CMake automatically handles selection of libraries according to build type, but does not enforce build type consistency when only one build type is installed. Installing *both* Debug and Release configurations on Windows is highly recommended for this reason. (This note only applies to the build type configuration parameter).
80236

81-
- Physical filename for a DSO is ``libmongocxx.so.$MAJOR.$MINOR.$PATCH``
237+
The name of the pkg-config file for C++ Driver libraries is the same as that for the regular (non-MSVC) shared library behavior described above.
238+
However, when ``ENABLE_ABI_TAG_IN_PKGCONFIG_FILENAMES=ON``, the library output name is used as-if it were the basename for pkg-config files.
239+
For example, to obtain flags for the shared library ``bsoncxx-v_noabi-rhs-x64-v142-md.dll``, the pkg-config command may look as follows when ``ENABLE_ABI_TAG_IN_PKGCONFIG_FILENAMES=OFF`` (the default):
82240

83-
.. note::
84-
85-
The physical filename is disconnected from ABI version/soname. This looks a bit strange, but allows multiple versions of the library with the same ABI version to be installed on the same system.
241+
.. code-block:: bash
86242

87-
- soname for a DSO is ``libmongocxx.$ABI``
243+
pkg-config --cflags "libbsoncxx"
88244

89-
We provide a soname symlink that links to the physical DSO. We also
90-
provide a dev symlink that links to the soname symlink of the highest ABI
91-
version of the library installed.
245+
or as follows when ``ENABLE_ABI_TAG_IN_PKGCONFIG_FILENAMES=ON``:
92246

93-
Inline Namespaces
94-
-----------------
247+
.. code-block:: bash
95248

96-
- We provide inline namespace macros for both mongocxx and bsoncxx.
97-
- This allows multiple, ABI incompatible versions of the library to be linked into the same application.
98-
- The name of the namespace is ``v$ABI``. We create them from ABI version to maintain forwards compatibibility.
249+
pkg-config --cflags "libbsoncxx-v_noabi-rhs-x64-v142-md"
99250

100-
Deprecation
101-
-----------
251+
Setting ``ENABLE_ABI_TAG_IN_PKGCONFIG_FILENAMES=ON`` is recommended when
252+
parallel installation of C++ Driver libraries with different build
253+
configurations (e.g. Debug vs. Release) is expected. However, using CMake
254+
package config files instead is most recommended.
102255

103-
Occasionally we will phase features out of use in the driver.
104-
In the release that marks a feature as deprecated we offer several transition options:
256+
Static Libraries
257+
~~~~~~~~~~~~~~~~
105258

106-
1. The original method, marked with ``MONGOCXX_DEPRECATED``. This will raise deprecation warnings when compiled.
107-
#. A variant of the feature suffixed with ``_deprecated``. This will require
108-
only small code changes and will not raise deprecation warnings.
109-
#. A new feature that provides alternate functionality. The new feature may not
110-
be a drop-in replacement for the deprecated feature and switching to it may
111-
require code changes. In the rare case where we remove a feature without replacing it, this third option will not be available.
259+
Static libraries use a simple filename pattern:
112260

113-
In the following release, the original feature marked with ``MONGOCXX_DEPRECATED`` and its
114-
suffixed ``_deprecated`` equivalent will be removed.
261+
.. code-block:: none
115262

116-
.. code-block:: cpp
263+
lib<basename>-static.a
117264

118-
// release 1 with a supported feature
119-
void do_thing();
265+
No API or ABI version information is included in the name of static library
266+
files.
267+
Shared vs. static library selection for CMake package config files is handled
268+
via CMake targets.
269+
Shared vs. static library selection for pkg-config files is handled by adding the ``-static`` suffix to the library basename, e.g. ``lib<basename>-static.pc``.
120270

121-
// release 2 where the feature is deprecated in favor of a new feature
122-
MONGOCXX_DEPRECATED void do_thing();
123-
void do_thing_deprecated();
124-
void do_new_thing();
271+
For example, the following library directory contains the expected shared *and* static library files for a bsoncxx library:
125272

126-
// release 3 where the original feature is removed
127-
void do_new_thing();
273+
.. code-block:: none
128274

129-
In the case of a feature rename we do not offer a suffixed ``_deprecated`` variant,
130-
as one can simply switch to using the new name with the same amount of effort.
275+
${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/
276+
├── libbsoncxx.so.1.2.3
277+
├── libbsoncxx.so.10 -> libbsoncxx.so.1.2.3
278+
├── libbsoncxx.so -> libbsoncxx.so.10
279+
├── libbsoncxx-static.a
280+
├── cmake/bsoncxx-1.2.3/
281+
│ ├── bsoncxx-config.cmake
282+
│ └── ...
283+
└── pkgconfig/
284+
├── libbsoncxx.pc
285+
└── libbsoncxx-static.pc
131286

132-
.. code-block:: cpp
287+
Static Libraries (MSVC Only)
288+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
289+
290+
The name of static libraries use the same pattern as MSVC shared library behavior described above, but uses ``static`` as the ``<abi-version-number>`` and the library output name as-if it were the basename.
133291

134-
// release 1 with a supported feature
135-
void do_thing();
292+
For example, the following install prefix directory contains the expected shared *and* static library files for a bsoncxx library (the bin directory is included to account for ``.dll`` files):
136293

137-
// release 2 where the feature name is renamed
138-
MONGOCXX_DEPRECATED void do_thing();
139-
void do_stuff();
294+
.. code-block:: none
140295

141-
// release 3 where the original feature name is removed
142-
void do_stuff();
296+
${CMAKE_INSTALL_PREFIX}/
297+
├── ${CMAKE_INSTALL_BINDIR}/
298+
│ └── bsoncxx-v10-rhs-x64-v142-md.dll
299+
└── ${CMAKE_INSTALL_LIBDIR}/
300+
├── bsoncxx-v10-rhs-x64-v142-md.lib
301+
├── bsoncxx-static-dhs-x64-v142-mdd.lib
302+
├── cmake/bsoncxx-1.2.3/
303+
│ ├── bsoncxx-config.cmake
304+
│ └── ...
305+
└── pkgconfig/
306+
├── libbsoncxx-v10-rhs-x64-v142-md.pc
307+
└── libbsoncxx-static-rhs-x64-v142-md.pc

0 commit comments

Comments
 (0)