| CMP0219 | |
| ------- | |
| .. versionadded:: 4.4 | |
| :command:`macro` invocations preserve backslashes in arguments. | |
| In CMake 4.3 and below, macro argument references (``${ARGN}``, ``${ARGV}``, | |
| ``${ARGV<n>}``, and named macro arguments) are substituted textually and then | |
| evaluated by the called command. Backslashes in substituted values are | |
| re-evaluated as escape prefixes, and invalid escape sequences (such as | |
| ``\b`` in Windows paths) can cause errors. The same re-evaluation can also | |
| occur for arguments passed to a :command:`variable_watch` callback command. | |
| CMake 4.4 and above prefer to preserve literal backslashes in those macro | |
| argument references. | |
| The ``OLD`` behavior for this policy is to interpret escape sequences in macro | |
| argument references and in arguments passed to ``variable_watch()`` callback | |
| commands. The ``NEW`` behavior is to preserve backslashes in those values | |
| before command invocation. | |
| This policy applies to macro argument references and to arguments passed to | |
| ``variable_watch()`` callback commands. Other variable references keep their | |
| existing behavior. | |
| Mixed Policy Chains | |
| ^^^^^^^^^^^^^^^^^^^ | |
| Whether pre-escaping occurs is determined by the policy setting at each | |
| call site. When a project and its dependencies use different ``CMP0219`` | |
| settings, each macro call in the chain follows the policy where that call | |
| appears. | |
| Consider a project (``CMP0219`` is ``OLD``) that calls a macro from | |
| dependency A (upgraded to | |
| :command:`cmake_minimum_required(VERSION 4.4) <cmake_minimum_required>`, | |
| so ``CMP0219`` is ``NEW``), which in turn forwards arguments to a macro | |
| from dependency B (not yet upgraded, so ``CMP0219`` is ``OLD``): | |
| .. code-block:: cmake | |
| # Dependency B: cmake_minimum_required(VERSION 3.24) | |
| # CMP0219 is OLD inside dependency B. | |
| macro(depB_store var_name) | |
| set(${var_name} "${ARGN}") | |
| endmacro() | |
| # Dependency A: cmake_minimum_required(VERSION 4.4) | |
| # CMP0219 is NEW inside dependency A. | |
| macro(depA_forward var_name) | |
| depB_store(${var_name} ${ARGN}) # call site is NEW -> pre-escapes | |
| endmacro() | |
| # Project: cmake_minimum_required(VERSION 3.24) | |
| # CMP0219 is OLD in the project. | |
| macro(my_wrapper var_name) | |
| depA_forward(${var_name} ${ARGN}) # call site is OLD -> no pre-escaping | |
| endmacro() | |
| In a fully ``OLD`` chain, each macro boundary re-evaluates backslash | |
| escapes, so callers must add extra escaping layers to compensate. | |
| To pass the Windows path ``C:\build\new\temp`` through three ``OLD`` | |
| boundaries, the caller needs eight backslashes per separator: | |
| .. code-block:: cmake | |
| my_wrapper(result "C:\\\\\\\\build\\\\\\\\new\\\\\\\\temp") | |
| message("${result}") # -> C:\build\new\temp | |
| When dependency A upgrades and the middle boundary becomes ``NEW``, | |
| that boundary preserves backslashes instead of consuming a level. | |
| The same input now retains an extra layer: | |
| .. code-block:: cmake | |
| # Same 8x-escaped input through OLD -> NEW -> OLD: | |
| my_wrapper(result "C:\\\\\\\\build\\\\\\\\new\\\\\\\\temp") | |
| message("${result}") # -> C:\\build\\new\\temp (one extra layer) | |
| The caller must then use half the escaping to reach the native path: | |
| .. code-block:: cmake | |
| # Only 4x-escaped input needed for OLD -> NEW -> OLD: | |
| my_wrapper(result "C:\\\\build\\\\new\\\\temp") | |
| message("${result}") # -> C:\build\new\temp | |
| When a dependency updates its :command:`cmake_minimum_required` version | |
| to 4.4 or above, call sites inside that dependency begin pre-escaping. | |
| Callers that previously added extra backslash layers to compensate for | |
| multiple levels of ``OLD`` re-evaluation may then need fewer escape | |
| layers. | |
| Where possible, converting paths to forward slashes with | |
| :command:`cmake_path(CONVERT ... TO_CMAKE_PATH_LIST)` avoids the issue entirely, because | |
| forward slashes require no escaping regardless of the policy setting. | |
| .. |INTRODUCED_IN_CMAKE_VERSION| replace:: 4.4 | |
| .. |WARNS_OR_DOES_NOT_WARN| replace:: warns when backslashes are present | |
| .. include:: include/STANDARD_ADVICE.rst | |
| .. include:: include/DEPRECATED.rst |