c++modules: document BMI compatibility changes

This commit is contained in:
Vito Gamberini
2026-06-02 16:28:13 -04:00
parent bfba7f68af
commit 2049419196
2 changed files with 35 additions and 22 deletions

View File

@@ -518,26 +518,34 @@ then ensure that the build graph executes correctly. This means that, while
all sources may get scanned, only modules that are actually used will be
generated.
The first step CMake performs is to generate a :term:`synthetic target` for
each unique usage of a module-providing target. These targets are based on
other targets, but provide only :term:`BMI` files for other targets rather
than object files. This is because the compatibility of :term:`BMI` files is
extremely narrow and cannot be shared between arbitrary ``import`` instances.
Due to the internal workings of toolchains, there can generally only be a
single set of settings for a variety of flags for any one compilation,
including :term:`BMI` files for imported modules. As an example, the C++
standard in use needs to be consistent across all modules, but there are many
settings which may cause incompatibilities.
The first step CMake performs is to generate any
:term:`synthetic targets <synthetic target>` needed for a module-providing
target. These targets are based on the module provider, but produce only
:term:`BMI` files for consumers rather than object files. This is necessary
because the compatibility of :term:`BMI` files is extremely narrow and cannot be
shared between arbitrary ``import`` instances.
.. note::
Due to the internal workings of toolchains, there can generally only be a single
set of settings for a variety of flags for any one compilation, including
:term:`BMI` files for imported modules. As an example, the C++ standard in
use needs to be consistent across all modules imported to a given translation
unit, mixing standards will cause incompatibilities.
CMake currently assumes that all usages are compatible and will only create
one set of :term:`BMIs <BMI>` for each target. This may cause build
failures where multiple :term:`BMI` files are required, but CMake only
provides one set. See `CMake Issue 25916`_ for progress on removing this
assumption.
.. versionadded:: 4.4
.. _`CMake Issue 25916`: https://gitlab.kitware.com/cmake/cmake/-/issues/25916
Prior to CMake 4.4, CMake assumed all usages were compatible and would only
create one set of :term:`BMIs <BMI>` for each module-providing target. This
could cause build failures due to incompatible :term:`BMI` usage.
In CMake 4.4 and later, CMake attempts to determine :term:`BMI`
compatibility on a target-by-target basis and will generate
:term:`synthetic targets <synthetic target>` to provide compatible
:term:`BMIs <BMI>` for consumers.
The generated :term:`synthetic target` has a mix of properties from both
the provider of the module and the consumer. :prop_tgt:`COMPILE_FEATURES` and
:prop_tgt:`COMPILE_OPTIONS` are adopted from the consumer, while all other
relevant properties are inherited from the provider.
Once all of the :term:`synthetic targets <synthetic target>` are created,
CMake looks at each target that has any source that might use C++ modules and
@@ -662,11 +670,6 @@ command to find imported modules during compilation. Because CMake only
provides the locations of modules that are discovered by the :term:`scan`
command, any modules missed by it will not be provided to the compilation.
It is possible for toolchains to reject the :term:`BMI` file that CMake
provides to a compilation as incompatible. This is because CMake assumes that
all usages are compatible at the moment. See `CMake Issue 25916`_ for
progress on removing this assumption.
Install
^^^^^^^

View File

@@ -0,0 +1,10 @@
cxx-modules-bmi-compatibility
-----------------------------
* Targets which provide ``PUBLIC`` or ``INTERFACE``-scoped ``CXX_MODULES``
:ref:`file sets <File Sets>` will now generate
:term:`synthetic targets <synthetic target>` when linked to by
:term:`BMI`-incompatible consuming targets. These synthetic targets adopt
the :prop_tgt:`COMPILE_FEATURES` and :prop_tgt:`COMPILE_OPTIONS`
from the consumer, while all other relevant properties are inherited from the
provider.