Skip to content

Latest commit

 

History

History
307 lines (223 loc) · 12.7 KB

File metadata and controls

307 lines (223 loc) · 12.7 KB

API and ABI Policy

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.

Versioning Scheme

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.

What Is the Public API?

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 typedef is public.
  • The content of src/kms-message/, a vendored library with its own versioning.
  • The undocumented, incidental behavior of any function.

Header Inclusion

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.

API Stability

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.

ABI Stability

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.

Deprecation Policy

Symbols that need to be removed follow a two-step cycle:

  1. Mark deprecated. Annotate the declaration with BSON_DEPRECATED("…") or BSON_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 the BSON_DEPRECATED macros (there is no MONGOC_DEPRECATED equivalent).
  2. 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.

Adding New Symbols

New public symbols may be added in any minor release. When adding a symbol:

  1. Declare it in the appropriate public header.
  2. For functions, annotate it with MONGOC_EXPORT or BSON_EXPORT.
  3. Add a .rst documentation page in src/libmongoc/doc/ or src/libbson/doc/.
  4. Verify it appears in the ABI compliance report under Added Symbols (see the abi-compliance-check Evergreen 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).

Other Notes

Build configuration compatibility

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.

Pre-release versions

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.

Experimental APIs

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.

Build system integration API

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.