1
0

CMP0200.rst 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. CMP0200
  2. -------
  3. .. versionadded:: 4.2
  4. Location and configuration selection for imported targets is more consistent.
  5. The way CMake historically selected the configuration to use for imported
  6. targets prioritized selection based on location properties for a candidate
  7. configuration and only considered :prop_tgt:`IMPORTED_CONFIGURATIONS` as a
  8. fallback. This could result in incorrect configuration selection especially
  9. for ``INTERFACE`` libraries.
  10. CMake 4.2 and above consider :prop_tgt:`IMPORTED_CONFIGURATIONS` to be a
  11. definitive list of available configurations, regardless of whether a
  12. configuration specific location is provided for the library. Additionally,
  13. CMake will respect non-configuration-specific locations when a configuration
  14. specific location is not specified.
  15. This policy provides compatibility with projects that rely on the historical
  16. behavior. The policy setting applies to targets and is recorded at the point
  17. an imported target is created. Accordingly, imported packages may override the
  18. policy set by the consumer for targets they create. In particular, targets
  19. imported from |CPS| packages always use the ``NEW`` behavior.
  20. The ``OLD`` behavior for this policy is to retain the historic behavior.
  21. The ``NEW`` behavior prioritizes selection based on the advertised list of
  22. available configurations. Both behaviors are described in detail below.
  23. .. |INTRODUCED_IN_CMAKE_VERSION| replace:: 4.2
  24. .. |WARNS_OR_DOES_NOT_WARN| replace:: warns
  25. .. include:: include/STANDARD_ADVICE.rst
  26. .. include:: include/DEPRECATED.rst
  27. Mapped configuration selection
  28. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  29. If :prop_tgt:`MAP_IMPORTED_CONFIG_<CONFIG>` (where ``<CONFIG>`` is the
  30. configuration of the consuming target) is set on an imported target, CMake
  31. would historically select from that list the first configuration which provides
  32. a configuration-specific location. If no such configuration exists, CMake
  33. would selects the consuming target's configuration, if the imported target is
  34. an ``INTERFACE`` library. Otherwise, CMake considers the target as not having
  35. a suitable configuration.
  36. For ``INTERFACE`` libraries which do not provide a location, this results in
  37. CMake always selecting the consuming target's configuration and effectively
  38. ignoring :prop_tgt:`MAP_IMPORTED_CONFIG_<CONFIG>`. This behavior is not
  39. consistent with configuration selection for imported targets which provide a
  40. location.
  41. Under the ``NEW`` behavior, CMake selects the first configuration from the
  42. mapping which appears in :prop_tgt:`IMPORTED_CONFIGURATIONS`. If
  43. :prop_tgt:`IMPORTED_CONFIGURATIONS` is not set, CMake selects the first
  44. configuration from the mapping which is "usable". For non-``INTERFACE``
  45. libraries, "usable" means that a location (either configuration-specific or
  46. configuration-agnostic) is available. ``INTERFACE`` libraries are always
  47. considered "usable".
  48. If no match is found, CMake considers the target as not having a suitable
  49. configuration.
  50. Non-mapped configuration selection
  51. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  52. If :prop_tgt:`MAP_IMPORTED_CONFIG_<CONFIG>` is *not* set, CMake would
  53. historically select the first configuration which provides a location out of
  54. the following:
  55. - The consuming target's configuration, or
  56. - The empty configuration, or
  57. - The list of configurations in :prop_tgt:`IMPORTED_CONFIGURATIONS`.
  58. As an implementation artifact, this results in CMake selecting the *last*
  59. configuration in :prop_tgt:`IMPORTED_CONFIGURATIONS` for ``INTERFACE``
  60. libraries which do not provide a location. Again, this behavior is not
  61. consistent with configuration selection for imported targets which provide a
  62. location.
  63. Under the ``NEW`` behavior, if :prop_tgt:`IMPORTED_CONFIGURATIONS` is set,
  64. CMake will select the consuming target's configuration if present therein,
  65. otherwise CMake will select the first imported configuration. If
  66. :prop_tgt:`IMPORTED_CONFIGURATIONS` is *not* set, CMake will select the
  67. consuming target's configuration if it is "usable" (as defined in the previous
  68. section); otherwise, CMake considers the target as not having a suitable
  69. configuration.
  70. Examples
  71. ^^^^^^^^
  72. Consider the following imported library:
  73. .. code-block:: cmake
  74. add_library(test INTERFACE IMPORTED)
  75. set_target_properties(test PROPERTIES
  76. IMPORTED_CONFIGURATIONS "RELEASE;DEBUG"
  77. INTERFACE_COMPILE_DEFINITIONS "$<$<CONFIG:debug>:DEBUG>"
  78. )
  79. Under the ``OLD`` policy, CMake will select the ``DEBUG`` configuration of
  80. ``test`` (and thus define the symbol ``DEBUG``) for any target linking to
  81. ``test``, because CMake does not consider any configuration "valid", and, as
  82. an implementation artifact, the last configuration considered is accepted.
  83. Under the ``NEW`` policy, the ``RELEASE`` configuration will be selected
  84. if the consuming project is built in any configuration other than ``Debug``
  85. (keeping in mind that configuration matching is case-insensitive). This is
  86. because ``DEBUG`` will be preferred if the consumer's configuration is also
  87. ``DEBUG``, but ``RELEASE`` will be preferred otherwise because it appears
  88. first in :prop_tgt:`IMPORTED_CONFIGURATIONS`, and its appearance therein makes
  89. it a "valid" configuration for an ``INTERFACE`` library.
  90. .. |CPS| replace:: Common Package Specification