This page describes the stability guarantees that the C driver project makes about its public API and ABI across releases, how deprecation works, and what is explicitly not covered by these guarantees.
Note
This policy applies to both libmongoc and libbson.
The C libraries use a <major>.<minor>.<patch> versioning scheme that is
based on Semantic Versioning. Prerelease and development
versions include a suffix to indicate that the contents of the libraries are
unstable and subject to change.
- A major version indicates overall breaking changes. Different major versions offer no compatibility guarantees in their API and ABI.
- A minor version indicates the addition of new APIs and features to the libraries, or possible deprecation of APIs. Programs written against earlier minor versions should continue to compile and link with a newer minor version with minimal or no changes.
- A patch version (also known as the "micro" version at some locations in the source code) indicates bugfixes and tweaks and will not deprecate or add any major features to libraries. Programs written against earlier patch versions should compile and link against newer patch versions with no changes unless security considerations require API or ABI changes.
The public API consists of:
- Every entity (function, type, macro, constant) declared in a public header (a header that is installed alongside the library), except for those noted below.
- The documented behavior of any API function or macro.
The following are not part of the public API and carry no stability guarantee:
- Anything under
src/common/(the internal shared utility library). - Symbols prefixed with an underscore or otherwise documented as internal or experimental.
- The layout of any struct whose definition lives in a private header, even when
the opaque
typedefis public. - The content of
src/kms-message/, a vendored library with its own versioning. - The undocumented, incidental behavior of any function.
All library header #include directives should use the bson/ or
mongoc/ directory prefix. Including unqualified header filenames by
modifying the header search paths is unsupported.
Header files that have the bson/bson-* or mongoc/mongoc-* (with the
hyphen) prefix should never be included directly, despite being part of the
public API. Only their contents are part of the public API, not the filename or
the physical location of the entities contained within. The content of these
headers may be moved in any version, or those headers may be removed entirely.
Instead, users should include the umbrella headers
<bson/bson.h>/<mongoc/mongoc.h> or they may directly include one of the
headers without the bson- or mongoc- prefix in its filename.
By default, libbson and libmongoc headers are not installed as direct children of the platform's default header include-search-path directory, and live in a subdirectory that is qualified by the library version. Users should never use this intermediate directory in their include directives, and should rely on CMake or pkg-config to set the appropriate flags to update their include-search-path to find the relevant headers in this versioned subdirectory.
Within a major version series, the project makes the following guarantees:
- No removal of public symbols — functions, types, macros, and constants present in a release remain available in all subsequent releases within the same major version.
- No rename of a public symbol without providing a compatibility alias for the original name.
- No incompatible signature changes — the parameter and return types of public functions do not change in ways that require callers to be updated. Note that type-qualifiers may be added or removed from parameter or return types in ways that do not affect existing callers.
- No change in documented contract — the observable behavior, preconditions, postconditions, and error semantics of a public function do not change in a way that causes a previously-correct caller to misbehave.
- No change in the values of public constants or enum members in a way that alters the semantics of existing programs.
As a result, a program that compiles cleanly against version X.Y.Z is
expected to compile and link without modification against any later X.Y'.Z'
release in the same major series, provided the program only uses the public API.
Within a minor release, new public symbols may be added (see :ref:`api-abi-policy.additions`). Within a patch release, no new public symbols are introduced and existing behavior changes only to correct bugs or security issues.
Deprecation (see :ref:`api-abi-policy.deprecation`) is the only mechanism by which a public symbol can eventually be removed; removal only occurs at a major release boundary. Until a symbol is actually removed it remains fully functional — not merely a stub.
Bug fixes and behavior
A change that corrects a function's behavior to match its documented contract is not an API break, even if some callers relied on the erroneous behavior. Undocumented or incorrect behavior carries no stability guarantee.
Macros
The observable behavior of a public macro is stable within a major version series. The specific token sequence of a macro's expansion is not guaranteed and may change between releases — for example, to replace a function-like macro with an inline function or to add internal casts. Code that depends on a specific expansion rather than on the macro's documented behavior is unsupported.
Note
Whether an API function is implemented as a preprocessor macro is an implementation detail unless documented otherwise. Relying on whether an API function name is a macro is not supported.
Do not attempt to take the address of an API function or perform an #ifdef
on an API function name, unless such an operation is said to be supported in
the documentation.
Error codes
New error codes and domain values may be introduced in any minor release. Callers should handle unknown error codes gracefully rather than treating the set of possible values as exhaustive.
Except in the case of security patches, the project guarantees the following within a major version series:
- No removal of exported symbols, and no change to an exported symbol's link name.
- No signature changes to exported functions (parameter types, return type, calling convention), except for the possible addition of type-qualifiers to pointer parameters or removal of type-qualifiers from pointer return types.
- No breaking changes to the size or layout of any completely-defined struct reachable in the public API, even if the contents of that struct are not themselves part of the API. Where feasible, structs are kept opaque (accessed only through accessor functions) to preserve this freedom.
As a result, a program compiled against version X.Y.Z is expected to load
and run correctly against any later X.Y'.Z' shared library, provided the
program only uses the public API.
Additionally, the soname of a built dynamic library is part of the ABI and
guaranteed stable within a major version. The soname of the resulting
libraries includes the major version of the library, preventing collisions
between major versions. The CMake SOVERSION property of resulting dynamic
library artifacts is always equivalent to the major API version of the library.
(The soname and SOVERSION are not applicable to Windows DLLs.)
In the uncommon case that a security patch requires breaking any of the above guarantees, it will be noted in the release notes for the corresponding version.
Exported symbols
The BSON_EXPORT and MONGOC_EXPORT macros are used to add appropriate
attributes to external-linkage symbols that are visible in a dynamic library
build. The presence of such symbols in a built artifact is part of the ABI of
that artifact.
Incomplete types
Many types (e.g. mongoc_client_t) are intentionally incomplete in the public
API and are only passed/returned by address. Callers should never rely on the
size, alignment, or fields of such a type. Adding, removing, or rearranging the
content of such types is not an ABI break.
Public aggregate types
A small number of structs expose their fields in public headers as part of their
public API (e.g. bson_iter_t). Changes to these structs are ABI breaks
and are therefore prohibited within a major version series.
Compilation settings
Certain preprocessor macros and CMake configure-time build parameters may affect the ABI of the resulting build. When possible, programs should not attempt to combine translation units together that are not compiled with the same set of preprocessor definitions.
Users should not manually define preprocessor macros during their compilation that could affect the content of the exposed library APIs. Instead, users should rely on the CMake imported targets or pkg-config definitions to set the appropriate compile/link settings for their program.
Note
The project runs an ABI compliance check in CI (the abi-compliance-check
Evergreen task) that compares the current branch against the most recent
stable release. Any unexpected breakage should be caught before merge.
Symbols that need to be removed follow a two-step cycle:
- Mark deprecated. Annotate the declaration with
BSON_DEPRECATED("…")orBSON_DEPRECATED_FOR(replacement)and update the documentation to note the deprecation and its replacement. This is a non-breaking change that may land in any minor release. mongoc also uses theBSON_DEPRECATEDmacros (there is noMONGOC_DEPRECATEDequivalent). - Remove. The symbol is removed no earlier than the next major release after it was deprecated, giving users at least one full major-version cycle to migrate.
A deprecated symbol must remain present and functional (not just a stub) until it is removed.
New public symbols may be added in any minor release. When adding a symbol:
- Declare it in the appropriate public header.
- For functions, annotate it with
MONGOC_EXPORTorBSON_EXPORT. - Add a
.rstdocumentation page insrc/libmongoc/doc/orsrc/libbson/doc/. - Verify it appears in the ABI compliance report under Added Symbols (see
the
abi-compliance-checkEvergreen task artifact).
Adding new symbols is not an ABI break. However, a new symbol that clashes
with a name a downstream project already defines privately can cause linker
confusion; prefer descriptive, namespaced names (mongoc_ or bson_
prefix).
The build parameters that affect the API/ABI of built artifacts are themselves subject to the same stability guarantees as the C API, and follow the same deprecation policy.
The C API and ABI guarantees only hold within the same build configuration. Attempting to mix build configurations is unsupported, as build settings may affect the API or ABI of the resulting artifacts.
Any release with a pre-release label (e.g. 2.0.0-alpha1) carries no
stability guarantee. Any changes that are part of a prerelease may be removed
or modified without notice between pre-release versions.
APIs that are documented as experimental may change or be removed in any release, including patch releases, regardless of the usual policy. Such APIs will be clearly marked in the documentation.
The CMake config-file packages are the recommended way to import the project.
The CMake targets (mongoc::shared, bson::static, etc.) and the
properties they expose are considered public and follow the same versioning
rules as the C API. However, the internal CMake helper modules under
build/cmake/ are not public and may change without notice.
The pkg-config files are also supported for building against the libraries, and will ensure that the compilation settings match the ABI of the corresponding binaries.