You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
228 lines
6.4 KiB
228 lines
6.4 KiB
cmake_language
|
|
--------------
|
|
|
|
.. versionadded:: 3.18
|
|
|
|
Call meta-operations on CMake commands.
|
|
|
|
Synopsis
|
|
^^^^^^^^
|
|
|
|
.. parsed-literal::
|
|
|
|
cmake_language(`CALL`_ <command> [<arg>...])
|
|
cmake_language(`EVAL`_ CODE <code>...)
|
|
cmake_language(`DEFER`_ <options>... CALL <command> [<arg>...])
|
|
|
|
Introduction
|
|
^^^^^^^^^^^^
|
|
|
|
This command will call meta-operations on built-in CMake commands or
|
|
those created via the :command:`macro` or :command:`function` commands.
|
|
|
|
``cmake_language`` does not introduce a new variable or policy scope.
|
|
|
|
Calling Commands
|
|
^^^^^^^^^^^^^^^^
|
|
|
|
.. _CALL:
|
|
|
|
.. code-block:: cmake
|
|
|
|
cmake_language(CALL <command> [<arg>...])
|
|
|
|
Calls the named ``<command>`` with the given arguments (if any).
|
|
For example, the code:
|
|
|
|
.. code-block:: cmake
|
|
|
|
set(message_command "message")
|
|
cmake_language(CALL ${message_command} STATUS "Hello World!")
|
|
|
|
is equivalent to
|
|
|
|
.. code-block:: cmake
|
|
|
|
message(STATUS "Hello World!")
|
|
|
|
.. note::
|
|
To ensure consistency of the code, the following commands are not allowed:
|
|
|
|
* ``if`` / ``elseif`` / ``else`` / ``endif``
|
|
* ``while`` / ``endwhile``
|
|
* ``foreach`` / ``endforeach``
|
|
* ``function`` / ``endfunction``
|
|
* ``macro`` / ``endmacro``
|
|
|
|
Evaluating Code
|
|
^^^^^^^^^^^^^^^
|
|
|
|
.. _EVAL:
|
|
|
|
.. code-block:: cmake
|
|
|
|
cmake_language(EVAL CODE <code>...)
|
|
|
|
Evaluates the ``<code>...`` as CMake code.
|
|
|
|
For example, the code:
|
|
|
|
.. code-block:: cmake
|
|
|
|
set(A TRUE)
|
|
set(B TRUE)
|
|
set(C TRUE)
|
|
set(condition "(A AND B) OR C")
|
|
|
|
cmake_language(EVAL CODE "
|
|
if (${condition})
|
|
message(STATUS TRUE)
|
|
else()
|
|
message(STATUS FALSE)
|
|
endif()"
|
|
)
|
|
|
|
is equivalent to
|
|
|
|
.. code-block:: cmake
|
|
|
|
set(A TRUE)
|
|
set(B TRUE)
|
|
set(C TRUE)
|
|
set(condition "(A AND B) OR C")
|
|
|
|
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/eval.cmake "
|
|
if (${condition})
|
|
message(STATUS TRUE)
|
|
else()
|
|
message(STATUS FALSE)
|
|
endif()"
|
|
)
|
|
|
|
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 with a capital letter ``A-Z``.
|
|
The ``<id>`` may begin with an underscore (``_``) only if it was generated
|
|
automatically by an earlier call that used ``ID_VAR`` to get the id.
|
|
|
|
``ID_VAR <var>``
|
|
Specify a variable in which to store the identification for the
|
|
deferred call. If ``ID <id>`` is not given, a new identification
|
|
will be generated and the generated id will start with an underscore (``_``).
|
|
|
|
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. The ids are for the directory scope in which
|
|
the calls have been deferred to (i.e. where they will be executed), which can
|
|
be different to the scope in which they were created. The ``DIRECTORY``
|
|
option can be used to specify the scope for which to retrieve the call ids.
|
|
If that option is not given, the call ids for the current directory scope will
|
|
be returned.
|
|
|
|
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 in
|
|
the specified ``DIRECTORY`` scope (or the current directory scope if no
|
|
``DIRECTORY`` option is given), 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 in the specified
|
|
``DIRECTORY`` scope (or the current directory scope if no ``DIRECTORY`` option
|
|
is given). 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 "Canceled 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
|
|
canceled. 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
|