summaryrefslogtreecommitdiff
path: root/Help/command/cmake_language.rst
diff options
context:
space:
mode:
Diffstat (limited to 'Help/command/cmake_language.rst')
-rw-r--r--Help/command/cmake_language.rst119
1 files changed, 119 insertions, 0 deletions
diff --git a/Help/command/cmake_language.rst b/Help/command/cmake_language.rst
index 9ce5a6f62a..00e1a69ccd 100644
--- a/Help/command/cmake_language.rst
+++ b/Help/command/cmake_language.rst
@@ -12,6 +12,7 @@ Synopsis
cmake_language(`CALL`_ <command> [<arg>...])
cmake_language(`EVAL`_ CODE <code>...)
+ cmake_language(`DEFER`_ <options>... CALL <command> [<arg>...])
Introduction
^^^^^^^^^^^^
@@ -99,3 +100,121 @@ is equivalent to
)
include(${CMAKE_CURRENT_BINARY_DIR}/eval.cmake)
+
+Deferring Calls
+^^^^^^^^^^^^^^^
+
+.. versionadded:: 3.19
+
+.. _DEFER:
+
+.. code-block:: cmake
+
+ cmake_language(DEFER <options>... CALL <command> [<arg>...])
+
+Schedules a call to the named ``<command>`` with the given arguments (if any)
+to occur at a later time. By default, deferred calls are executed as if
+written at the end of the current directory's ``CMakeLists.txt`` file,
+except that they run even after a :command:`return` call. Variable
+references in arguments are evaluated at the time the deferred call is
+executed.
+
+The options are:
+
+``DIRECTORY <dir>``
+ Schedule the call for the end of the given directory instead of the
+ current directory. The ``<dir>`` may reference either a source
+ directory or its corresponding binary directory. Relative paths are
+ treated as relative to the current source directory.
+
+ The given directory must be known to CMake, being either the top-level
+ directory or one added by :command:`add_subdirectory`. Furthermore,
+ the given directory must not yet be finished processing. This means
+ it can be the current directory or one of its ancestors.
+
+``ID <id>``
+ Specify an identification for the deferred call.
+ The id may not be empty and may not begin in a capital letter ``A-Z``.
+ The id may begin in a ``_`` only if it was generated by another call
+ that used ``ID_VAR`` to get the id.
+
+``ID_VAR <var>``
+ Sepcify a variable in which to store the identification for the
+ deferred call. If ``ID <id>`` is not given, a new identification
+ will be generated starting in a ``_``.
+
+The currently scheduled list of deferred calls may be retrieved:
+
+.. code-block:: cmake
+
+ cmake_language(DEFER [DIRECTORY <dir>] GET_CALL_IDS <var>)
+
+This will store in ``<var>`` a :ref:`Semicolon-separated list <CMake Language
+Lists>` of deferred call ids.
+
+Details of a specific call may be retrieved from its id:
+
+.. code-block:: cmake
+
+ cmake_language(DEFER [DIRECTORY <dir>] GET_CALL <id> <var>)
+
+This will store in ``<var>`` a :ref:`Semicolon-separated list <CMake Language
+Lists>` in which the first element is the name of the command to be
+called, and the remaining elements are its unevaluated arguments (any
+contained ``;`` characters are included literally and cannot be distinguished
+from multiple arguments). If multiple calls are scheduled with the same id,
+this retrieves the first one. If no call is scheduled with the given id,
+this stores an empty string in the variable.
+
+Deferred calls may be canceled by their id:
+
+.. code-block:: cmake
+
+ cmake_language(DEFER [DIRECTORY <dir>] CANCEL_CALL <id>...)
+
+This cancels all deferred calls matching any of the given ids.
+Unknown ids are silently ignored.
+
+Deferred Call Examples
+""""""""""""""""""""""
+
+For example, the code:
+
+.. code-block:: cmake
+
+ cmake_language(DEFER CALL message "${deferred_message}")
+ cmake_language(DEFER ID_VAR id CALL message "Cancelled Message")
+ cmake_language(DEFER CANCEL_CALL ${id})
+ message("Immediate Message")
+ set(deferred_message "Deferred Message")
+
+prints::
+
+ Immediate Message
+ Deferred Message
+
+The ``Cancelled Message`` is never printed because its command is
+cancelled. The ``deferred_message`` variable reference is not evaluated
+until the call site, so it can be set after the deferred call is scheduled.
+
+In order to evaluate variable references immediately when scheduling a
+deferred call, wrap it using ``cmake_language(EVAL)``. However, note that
+arguments will be re-evaluated in the deferred call, though that can be
+avoided by using bracket arguments. For example:
+
+.. code-block:: cmake
+
+ set(deferred_message "Deferred Message 1")
+ set(re_evaluated [[${deferred_message}]])
+ cmake_language(EVAL CODE "
+ cmake_language(DEFER CALL message [[${deferred_message}]])
+ cmake_language(DEFER CALL message \"${re_evaluated}\")
+ ")
+ message("Immediate Message")
+ set(deferred_message "Deferred Message 2")
+
+also prints::
+
+ Immediate Message
+ Deferred Message 1
+ Deferred Message 2