diff options
Diffstat (limited to 'Help/command/cmake_language.rst')
-rw-r--r-- | Help/command/cmake_language.rst | 119 |
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 |