CMP0199.rst 3.8 KB

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