1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
|
CMP0199
-------
.. versionadded:: 4.2
:genex:`$<CONFIG:cfgs>` does not match mapped configurations that are not
selected.
Historically, when a :genex:`$<CONFIG:cfgs>` generator expression appeared in
the properties of an imported target, it would match (that is, evaluate to
``1``) if any of the ``cfgs`` matched *any* of the following:
1. The selected configuration of the imported target being consumed.
2. The configuration of the consuming target.
3. *Any* of the configurations in the :prop_tgt:`MAP_IMPORTED_CONFIG_<CONFIG>`
of the imported target being consumed
(where ``<CONFIG>`` is the configuration of the consuming target),
*whether or not such configurations are valid for the imported target*.
This can result in expressions which are intended to be mutually exclusive
being concurrently evaluated. This can be especially problematic if the value
of a compile definition is intended to be determined by the configuration, as
this lack of exclusivity could result in redefinition.
CMake 4.2 and above prefer to consider *only* the configuration of the
consuming target and (when applicable) the selected configuration of the
imported target; that is, (2) and (1) in the above list. Unfortunately,
because users rely on both of these, this policy is not able to fully prevent
multiple unique ``$<CONFIG:cfg>`` expressions from matching concurrently.
This policy provides compatibility with projects that rely on the historical
behavior. The ``OLD`` behavior for this policy is to retain the historic
behavior as described above. The ``NEW`` behavior is to consider only the
configurations of the consuming and consumed targets.
.. note::
This policy only applies to generator expressions being evaluated as part of
the usage requirements of imported targets which are not imported from |CPS|
packages.
For non-imported targets, both the historic and ongoing behavior is to
consider only the configuration of the consuming target. (The selected
configuration of a non-imported target is always the active build
configuration, which is necessarily the same as the consuming target's
configuration.)
For targets imported from |CPS| packages, **only** the configuration of the
consumed imported target is considered, regardless of the policy setting.
.. |INTRODUCED_IN_CMAKE_VERSION| replace:: 4.2
.. |WARNS_OR_DOES_NOT_WARN| replace:: warns
.. include:: include/STANDARD_ADVICE.rst
.. include:: include/DEPRECATED.rst
Examples
^^^^^^^^
Consider the following imported libraries:
.. code-block:: cmake
add_library(test1 INTERFACE IMPORTED)
set_target_properties(test1 PROPERTIES
IMPORTED_CONFIGURATIONS "DEBUG"
INTERFACE_COMPILE_DEFINITIONS
"$<$<CONFIG:debug>:DEBUG>;$<$<CONFIG:release>:RELEASE>"
)
add_library(test2 INTERFACE IMPORTED)
set_target_properties(test2 PROPERTIES
IMPORTED_CONFIGURATIONS "TEST"
INTERFACE_COMPILE_DEFINITIONS
"$<$<CONFIG:debug>:DEBUG>;$<$<CONFIG:example>:EXAMPLE>;$<$<CONFIG:test>:TEST>"
MAP_IMPORTED_CONFIG_RELEASE "DEBUG;EXAMPLE;TEST"
)
Assume that the consuming project is built in the ``Release`` configuration.
A consumer of ``test1`` will see both ``DEBUG`` and ``RELEASE`` defined,
regardless of the policy setting; ``$<CONFIG:debug>`` evaluates to ``1``
because the selected configuration of ``test1`` is ``DEBUG``, and
``$<CONFIG:release>`` evaluates to ``1`` because the consumer's configuration
is ``Release`` (keeping in mind that configuration matching is
case-insensitive).
Under the ``OLD`` policy, a consumer of ``test2`` would see all of ``DEBUG``,
``EXAMPLE`` and ``TEST`` defined; ``$<CONFIG:debug>``, ``$<CONFIG:example>``
and ``$<CONFIG:test>`` all evaluate to ``1`` because all of these
configurations appear in ``MAP_IMPORTED_CONFIG_RELEASE``.
Under the ``NEW`` policy, a consumer of ``test2`` will see only ``TEST``
defined.
.. |CPS| replace:: Common Package Specification
|