Skip to content
Snippets Groups Projects
Verified Commit 1046a61c authored by Craig Scott's avatar Craig Scott
Browse files

Help: clean up and clarify block() and return()

parent 7c52e9e9
No related branches found
No related tags found
1 merge request!7872Help: clean up and clarify block() and return()
Pipeline #305883 waiting for manual action
......@@ -7,14 +7,14 @@ Evaluate a group of commands with a dedicated variable and/or policy scope.
.. code-block:: cmake
block([SCOPE_FOR (POLICIES|VARIABLES)] [PROPAGATE <var-name>...])
block([SCOPE_FOR [POLICIES] [VARIABLES] ] [PROPAGATE <var-name>...])
<commands>
endblock()
All commands between ``block()`` and the matching :command:`endblock` are
recorded without being invoked. Once the :command:`endblock` is evaluated, the
recorded list of commands is invoked inside the requested scopes, and, finally,
the scopes created by ``block()`` command are removed.
recorded list of commands is invoked inside the requested scopes, then the
scopes created by the ``block()`` command are removed.
``SCOPE_FOR``
Specify which scopes must be created.
......@@ -33,28 +33,29 @@ the scopes created by ``block()`` command are removed.
block(SCOPE_FOR VARIABLES POLICIES)
``PROPAGATE``
When a variable scope is created by :command:`block` command, this option
set or unset the specified variables in the parent scope. This is equivalent
to :command:`set(PARENT_SCOPE)` or :command:`unset(PARENT_SCOPE)` commands.
When a variable scope is created by the :command:`block` command, this
option sets or unsets the specified variables in the parent scope. This is
equivalent to :command:`set(PARENT_SCOPE)` or :command:`unset(PARENT_SCOPE)`
commands.
.. code-block:: cmake
set(VAR1 "INIT1")
set(VAR2 "INIT2")
set(var1 "INIT1")
set(var2 "INIT2")
block(PROPAGATE VAR1 VAR2)
set(VAR1 "VALUE1")
unset(VAR2)
block(PROPAGATE var1 var2)
set(var1 "VALUE1")
unset(var2)
endblock()
# here, VAR1 holds value VALUE1 and VAR2 is unset
# Now var1 holds VALUE1, and var2 is unset
This option is only allowed when a variable scope is created. An error will
be raised in the other cases.
When the ``block`` is local to a :command:`foreach` or :command:`while`
command, the commands :command:`break` and :command:`continue` can be used
inside this block.
When the ``block()`` is inside a :command:`foreach` or :command:`while`
command, the :command:`break` and :command:`continue` commands can be used
inside the block.
.. code-block:: cmake
......
......@@ -9,8 +9,8 @@ Continue to the top of enclosing foreach or while loop.
continue()
The ``continue`` command allows a cmake script to abort the rest of a block
in a :command:`foreach` or :command:`while` loop, and start at the top of
the next iteration.
The ``continue()`` command allows a cmake script to abort the rest of the
current iteration of a :command:`foreach` or :command:`while` loop, and start
at the top of the next iteration.
See also the :command:`break` command.
......@@ -7,46 +7,83 @@ Return from a file, directory or function.
return([PROPAGATE <var-name>...])
Returns from a file, directory or function. When this command is
encountered in an included file (via :command:`include` or
When this command is encountered in an included file (via :command:`include` or
:command:`find_package`), it causes processing of the current file to stop
and control is returned to the including file. If it is encountered in a
file which is not included by another file, e.g. a ``CMakeLists.txt``,
file which is not included by another file, e.g. a ``CMakeLists.txt``,
deferred calls scheduled by :command:`cmake_language(DEFER)` are invoked and
control is returned to the parent directory if there is one. If return is
called in a function, control is returned to the caller of the function.
control is returned to the parent directory if there is one.
If ``return()`` is called in a function, control is returned to the caller
of that function. Note that a :command:`macro`, unlike a :command:`function`,
is expanded in place and therefore cannot handle ``return()``.
Policy :policy:`CMP0140` controls the behavior regarding the arguments of the
command. All arguments are ignored unless that policy is set to ``NEW``.
``PROPAGATE``
.. versionadded:: 3.25
This option set or unset the specified variables in the parent directory or
This option sets or unsets the specified variables in the parent directory or
function caller scope. This is equivalent to :command:`set(PARENT_SCOPE)` or
:command:`unset(PARENT_SCOPE)` commands.
:command:`unset(PARENT_SCOPE)` commands, except for the way it interacts
with the :command:`block` command, as described below.
The option ``PROPAGATE`` can be very useful in conjunction with the
:command:`block` command because the :command:`return` will cross over
various scopes created by the :command:`block` commands.
The ``PROPAGATE`` option can be very useful in conjunction with the
:command:`block` command. A :command:`return` will propagate the
specified variables through any enclosing block scopes created by the
:command:`block` commands. Inside a function, this ensures the variables
are propagated to the function's caller, regardless of any blocks within
the function. If not inside a function, it ensures the variables are
propagated to the parent file or directory scope. For example:
.. code-block:: cmake
:caption: CMakeLists.txt
cmake_version_required(VERSION 3.25)
project(example)
set(var1 "top-value")
block(SCOPE_FOR VARIABLES)
add_subdirectory(subDir)
# var1 has the value "block-nested"
endblock()
function(MULTI_SCOPES RESULT_VARIABLE)
# var1 has the value "top-value"
.. code-block:: cmake
:caption: subDir/CMakeLists.txt
function(multi_scopes result_var1 result_var2)
block(SCOPE_FOR VARIABLES)
# here set(PARENT_SCOPE) is not usable because it will not set the
# variable in the caller scope but in the parent scope of the block()
set(${RESULT_VARIABLE} "new-value")
return(PROPAGATE ${RESULT_VARIABLE})
# This would only propagate out of the immediate block, not to
# the caller of the function.
#set(${result_var1} "new-value" PARENT_SCOPE)
#unset(${result_var2} PARENT_SCOPE)
# This propagates the variables through the enclosing block and
# out to the caller of the function.
set(${result_var1} "new-value")
unset(${result_var2})
return(PROPAGATE ${result_var1} ${result_var2})
endblock()
endfunction()
set(MY_VAR "initial-value")
multi_scopes(MY_VAR)
# here MY_VAR will holds "new-value"
set(var1 "some-value")
set(var2 "another-value")
Policy :policy:`CMP0140` controls the behavior regarding the arguments of the
command.
multi_scopes(var1 var2)
# Now var1 will hold "new-value" and var2 will be unset
Note that a :command:`macro <macro>`, unlike a :command:`function <function>`,
is expanded in place and therefore cannot handle ``return()``.
block(SCOPE_FOR VARIABLES)
# This return() will set var1 in the directory scope that included us
# via add_subdirectory(). The surrounding block() here does not limit
# propagation to the current file, but the block() in the parent
# directory scope does prevent propagation going any further.
set(var1 "block-nested")
return(PROPAGATE var1)
endblock()
See Also
^^^^^^^^
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment