| CMP0200 |
| ------- |
| |
| .. versionadded:: 4.2 |
| |
| Location and configuration selection for imported targets is more consistent. |
| |
| The way CMake historically selected the configuration to use for imported |
| targets prioritized selection based on location properties for a candidate |
| configuration and only considered :prop_tgt:`IMPORTED_CONFIGURATIONS` as a |
| fallback. This could result in incorrect configuration selection especially |
| for ``INTERFACE`` libraries. |
| |
| CMake 4.2 and above consider :prop_tgt:`IMPORTED_CONFIGURATIONS` to be a |
| definitive list of available configurations, regardless of whether a |
| configuration specific location is provided for the library. Additionally, |
| CMake will respect non-configuration-specific locations when a configuration |
| specific location is not specified. |
| |
| This policy provides compatibility with projects that rely on the historical |
| behavior. The policy setting applies to targets and is recorded at the point |
| an imported target is created. Accordingly, imported packages may override the |
| policy set by the consumer for targets they create. In particular, targets |
| imported from |CPS| packages always use the ``NEW`` behavior. |
| |
| The ``OLD`` behavior for this policy is to retain the historic behavior. |
| The ``NEW`` behavior prioritizes selection based on the advertised list of |
| available configurations. Both behaviors are described in detail below. |
| |
| .. |INTRODUCED_IN_CMAKE_VERSION| replace:: 4.2 |
| .. |WARNS_OR_DOES_NOT_WARN| replace:: warns |
| .. include:: include/STANDARD_ADVICE.rst |
| |
| .. include:: include/DEPRECATED.rst |
| |
| Mapped configuration selection |
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| |
| If :prop_tgt:`MAP_IMPORTED_CONFIG_<CONFIG>` (where ``<CONFIG>`` is the |
| configuration of the consuming target) is set on an imported target, CMake |
| would historically select from that list the first configuration which provides |
| a configuration-specific location. If no such configuration exists, CMake |
| would selects the consuming target's configuration, if the imported target is |
| an ``INTERFACE`` library. Otherwise, CMake considers the target as not having |
| a suitable configuration. |
| |
| For ``INTERFACE`` libraries which do not provide a location, this results in |
| CMake always selecting the consuming target's configuration and effectively |
| ignoring :prop_tgt:`MAP_IMPORTED_CONFIG_<CONFIG>`. This behavior is not |
| consistent with configuration selection for imported targets which provide a |
| location. |
| |
| Under the ``NEW`` behavior, CMake selects the first configuration from the |
| mapping which appears in :prop_tgt:`IMPORTED_CONFIGURATIONS`. If |
| :prop_tgt:`IMPORTED_CONFIGURATIONS` is not set, CMake selects the first |
| configuration from the mapping which is "usable". For non-``INTERFACE`` |
| libraries, "usable" means that a location (either configuration-specific or |
| configuration-agnostic) is available. ``INTERFACE`` libraries are always |
| considered "usable". |
| |
| If no match is found, CMake considers the target as not having a suitable |
| configuration. |
| |
| Non-mapped configuration selection |
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| |
| If :prop_tgt:`MAP_IMPORTED_CONFIG_<CONFIG>` is *not* set, CMake would |
| historically select the first configuration which provides a location out of |
| the following: |
| |
| - The consuming target's configuration, or |
| |
| - The empty configuration, or |
| |
| - The list of configurations in :prop_tgt:`IMPORTED_CONFIGURATIONS`. |
| |
| As an implementation artifact, this results in CMake selecting the *last* |
| configuration in :prop_tgt:`IMPORTED_CONFIGURATIONS` for ``INTERFACE`` |
| libraries which do not provide a location. Again, this behavior is not |
| consistent with configuration selection for imported targets which provide a |
| location. |
| |
| Under the ``NEW`` behavior, if :prop_tgt:`IMPORTED_CONFIGURATIONS` is set, |
| CMake will select the consuming target's configuration if present therein, |
| otherwise CMake will select the first imported configuration. If |
| :prop_tgt:`IMPORTED_CONFIGURATIONS` is *not* set, CMake will select the |
| consuming target's configuration if it is "usable" (as defined in the previous |
| section); otherwise, CMake considers the target as not having a suitable |
| configuration. |
| |
| Examples |
| ^^^^^^^^ |
| |
| Consider the following imported library: |
| |
| .. code-block:: cmake |
| |
| add_library(test INTERFACE IMPORTED) |
| set_target_properties(test PROPERTIES |
| IMPORTED_CONFIGURATIONS "RELEASE;DEBUG" |
| INTERFACE_COMPILE_DEFINITIONS "$<$<CONFIG:debug>:DEBUG>" |
| ) |
| |
| Under the ``OLD`` policy, CMake will select the ``DEBUG`` configuration of |
| ``test`` (and thus define the symbol ``DEBUG``) for any target linking to |
| ``test``, because CMake does not consider any configuration "valid", and, as |
| an implementation artifact, the last configuration considered is accepted. |
| |
| Under the ``NEW`` policy, the ``RELEASE`` configuration will be selected |
| if the consuming project is built in any configuration other than ``Debug`` |
| (keeping in mind that configuration matching is case-insensitive). This is |
| because ``DEBUG`` will be preferred if the consumer's configuration is also |
| ``DEBUG``, but ``RELEASE`` will be preferred otherwise because it appears |
| first in :prop_tgt:`IMPORTED_CONFIGURATIONS`, and its appearance therein makes |
| it a "valid" configuration for an ``INTERFACE`` library. |
| |
| .. |CPS| replace:: Common Package Specification |