Chromium Embedded Framework documentation
This page explains CEF API versioning.
Contents
The CEF library/framework exports an application binary interface (ABI) that is consumed by client applications. Historically this ABI has been unversioned meaning that any change in CEF major/minor version would require a recompilation of the client application. Given the long release cycles for many client applications this could mean users being stuck at an old/insecure Chromium version for an extended period of time.
To address this and related issues we have introduced the concept of CEF API versioning. API versioning allows applications built for one Stable API version to run with all past and future CEF binaries that also support that version (see “Supported Versions” below).
CEF API versioning has three levels:
Stable API is guaranteed to provide back/forward ABI compatibility and a fixed C/C++ API within a specific (supported) range of binary builds. Developers that wish to update CEF/Chromium separately from the client application should select this option by defining CEF_API_VERSION=XXXYY in their project configuration (see “Number Format” and “Test Coverage” below).
Experimental API provides access to additional/experimental functionality on top of the most recent Stable API version but comes with some limitations:
By default, client applications are built with Experimental API enabled (no explicit CEF_API_VERSION define). The CEF_API_VERSION definition, in combination with certain macros (see “Macros” below), is used to customize the available C/C++ API as seen by the C/C++ compiler. Client applications and libcef_dll_wrapper must be recompiled if the CEF_API_VERSION definition changes.
API versioning does not does not guarantee behavioral compatibility, particularly when moving between major Chromium versions. App developers are advised to perform their own testing before rolling out any particular combination of binaries.
Project contributors use pull requests to propose CEF code changes. Any API changes in pull requests should follow the Implementation guidelines laid out below and use the CEF_EXPERIMENTAL placeholder value in C/C++ header files.
API changes may become Stable (be assigned a version) if explicitly approved by the CEF admin. API approved for Stable can use the CEF_NEXT placeholder value instead of CEF_EXPERIMENTAL in pull requests. This value will be converted to a specific/new CEF API version by the CEF admin prior to upstream merge (see example here).
The CEF library/framework exports a C API that isolates the user from the CEF runtime and code base. The libcef_dll_wrapper project, which is distributed in source code form as part of the binary release, wraps this exported C API in a C++ API that is then linked into the client application. The code for this C/C++ API translation layer is automatically generated by the translator tool.
At runtime the client application reports the configured CEF_API_VERSION to the CEF library/framework via the first call to cef_api_hash (performed internally by libcef_dll_wrapper). This is a global value that modifies the library/framework runtime behavior and cannot be changed after initial configuration. All API surface (enums, structs, etc.) must match the configured API version or otherwise the application will crash with a fatal runtime error.
Each API version has an associated set of API hashes. The version_manager.py tool verifies API hashes at build time by reading and parsing all header files that contribute to the exported C API at that particular version. An API hash mismatch may occur during the cef_create_projects build step if the exported C API for an existing version has changed in an unexpected/unsupported way. This is considered a fatal build error and should be resolved before proceeding (see example here).
The CEF API version number format is XXXZZ where:
XXX is the CEF (and Chromium) major version (e.g. 133)ZZ is an incremental number (e.g. 01, 02, etc) that gets reset to 00 when the CEF major version changes. This becomes the CEF minor version.This format is incremental to work with logical operators and based on the CEF version at which it was first introduced. New version numbers are generated by the version_manager.py tool (see “Usage in Pull Requests” above).
By default, client applications are built with Experimental API enabled (no explicit CEF_API_VERSION define). Client applications can select a Stable API version by defining CEF_API_VERSION=XXXYY in their project configuration (see “Test Coverage” below).
Stable and Experimental API is explicitly tagged in C/C++ header files using CEF versioning macros provided by cef_api_hash.h. API without explicit tags is considered Legacy API (see “Overview” above). In C++ header files, versioning information is additionally included in CEF metadata (the /*--cef(...)--*/ comment). Stable API uses a specific version number and Experimental API uses the CEF_EXPERIMENTAL placeholder (see “Number Format” above).
CEF macros (for C/C++ headers) are as follows:
#if CEF_API_ADDED(XXXYY) surrounds code added in version XXXYY.#if CEF_API_REMOVED(XXXYY) surrounds code removed in version XXXYY.#if CEF_API_RANGE(XXXYY, XXXYZ) surrounds code added in version XXXYY and removed in version XXXYZ.CEF metadata (for classes/methods in C++ headers) is as follows:
added=XXXYY marks classes/methods added in version XXXYY.removed=XXXYY marks classes/methods removed in version XXXYY.added=XXXYY,removed=XXXYZ marks classes/methods added in version XXXYY and removed in version XXXYZ.For example, a C++ header might contain:
#include "include/cef_api_hash.h"
///
/// Client handler.
///
/*--cef(source=client)--*/
class CefClientHandler : public virtual CefBaseRefCounted {
public:
// Other method declarations here...
#if CEF_API_ADDED(13305)
///
/// Callback when something happens. Added in version 13305.
///
/*--cef(added=13305)--*/
virtual void OnSomething() = 0;
#endif
};
The new OnSomething callback will be available with Experimental API versions and Stable API versions >= 13305. It will be unavailable (compiled out) client-side with Stable API versions < 13305. See cef_api_hash.h for additional client-side macros.
The associated CEF library/framework (libcef) implementation might contain:
#include "cef/libcef/common/api_version_util.h"
void CefClientImpl::OnSomething() {
if (CEF_API_IS_ADDED(13305)) {
handler->OnSomething();
} else {
// Default handling
}
}
All API versions are supported on the library/framework side so it’s necessary to check the runtime-configured value. The CEF_API_IS_ADDED macro shown above returns true if the configured value is >= 13305. See api_version_util.h for additional libcef-side macros.
See “Test Coverage” below for additional usage examples.
ABI versioning requires strict guidelines for how API surface is defined and mutated across versions.
Enums:
_NUM_VALUES value at the end._NUM_VALUES (except in cases where the value is explicitly set)._DEPRECATED (or _REMOVED) but not removed.Structs:
size_t size member at the beginning._deprecated (or _removed) but not removed.Member methods:
uintptr_t) to preserve binary compatibility (memory layout) with older versions.OnEvent with different params) but C API should use numbering (e.g. on_event as the original, on_event[2...N] or on_event_[VERSION] as the replacement).Static methods & functions:
CefDoWork with different params) but C API should use numbering (e.g. cef_do_work as the original, cef_do_work[2...N] or cef_do_work_[VERSION] as the replacement).See cef_types.h and “Test Coverage” below for examples.
Test coverage has been added for API version compatibility. CEF sample apps (cefclient, cefsimple, ceftests) can be built with different Stable API versions as follows (see “Number Format” above):
cef_api_version=XXXYY to GN_DEFINES when building CEF/Chromium from source code.-D api_version=XXXYY to the cmake command-line when building with a CEF binary distribution.API version-related unit tests can be run with ceftests --gtest_filter=ApiVersionTest.*.
Examples of API versioning are available at include/test/cef_api_version_test.h (C++ header), libcef/common/test/api_version_test_impl.cc (libcef implementation) and tests/ceftests/api_version_unittest.cc (client implementation). An explanation of the associated C API headers and C++ wrapper code generated by the translator tool can be found here.
API versioning support was added in M133 (January 2025). Newer CEF versions may occasionally drop support for older API versions (see example here). This may occur on a schedule (e.g. annually), or as a result of incompatible Chromium changes breaking existing APIs in irresolvable ways. When this occurs it will be clearly communicated and likely supported by shared installers.