mirror of
https://github.com/Detanup01/gbe_fork.git
synced 2024-11-28 21:54:00 +08:00
460 lines
16 KiB
ReStructuredText
460 lines
16 KiB
ReStructuredText
|
if
|
||
|
--
|
||
|
|
||
|
Conditionally execute a group of commands.
|
||
|
|
||
|
Synopsis
|
||
|
^^^^^^^^
|
||
|
|
||
|
.. code-block:: cmake
|
||
|
|
||
|
if(<condition>)
|
||
|
<commands>
|
||
|
elseif(<condition>) # optional block, can be repeated
|
||
|
<commands>
|
||
|
else() # optional block
|
||
|
<commands>
|
||
|
endif()
|
||
|
|
||
|
Evaluates the ``condition`` argument of the ``if`` clause according to the
|
||
|
`Condition syntax`_ described below. If the result is true, then the
|
||
|
``commands`` in the ``if`` block are executed.
|
||
|
Otherwise, optional ``elseif`` blocks are processed in the same way.
|
||
|
Finally, if no ``condition`` is true, ``commands`` in the optional ``else``
|
||
|
block are executed.
|
||
|
|
||
|
Per legacy, the :command:`else` and :command:`endif` commands admit
|
||
|
an optional ``<condition>`` argument.
|
||
|
If used, it must be a verbatim
|
||
|
repeat of the argument of the opening
|
||
|
``if`` command.
|
||
|
|
||
|
.. _`Condition Syntax`:
|
||
|
|
||
|
Condition Syntax
|
||
|
^^^^^^^^^^^^^^^^
|
||
|
|
||
|
The following syntax applies to the ``condition`` argument of
|
||
|
the ``if``, ``elseif`` and :command:`while` clauses.
|
||
|
|
||
|
Compound conditions are evaluated in the following order of precedence:
|
||
|
|
||
|
1. `Parentheses`_.
|
||
|
|
||
|
2. Unary tests such as `EXISTS`_, `COMMAND`_, and `DEFINED`_.
|
||
|
|
||
|
3. Binary tests such as `EQUAL`_, `LESS`_, `LESS_EQUAL`_, `GREATER`_,
|
||
|
`GREATER_EQUAL`_, `STREQUAL`_, `STRLESS`_, `STRLESS_EQUAL`_,
|
||
|
`STRGREATER`_, `STRGREATER_EQUAL`_, `VERSION_EQUAL`_, `VERSION_LESS`_,
|
||
|
`VERSION_LESS_EQUAL`_, `VERSION_GREATER`_, `VERSION_GREATER_EQUAL`_,
|
||
|
`PATH_EQUAL`_, and `MATCHES`_.
|
||
|
|
||
|
4. Unary logical operator `NOT`_.
|
||
|
|
||
|
5. Binary logical operators `AND`_ and `OR`_, from left to right,
|
||
|
without any short-circuit.
|
||
|
|
||
|
Basic Expressions
|
||
|
"""""""""""""""""
|
||
|
|
||
|
.. signature:: if(<constant>)
|
||
|
:target: constant
|
||
|
|
||
|
True if the constant is ``1``, ``ON``, ``YES``, ``TRUE``, ``Y``,
|
||
|
or a non-zero number (including floating point numbers).
|
||
|
False if the constant is ``0``, ``OFF``,
|
||
|
``NO``, ``FALSE``, ``N``, ``IGNORE``, ``NOTFOUND``, the empty string,
|
||
|
or ends in the suffix ``-NOTFOUND``. Named boolean constants are
|
||
|
case-insensitive. If the argument is not one of these specific
|
||
|
constants, it is treated as a variable or string (see `Variable Expansion`_
|
||
|
further below) and one of the following two forms applies.
|
||
|
|
||
|
.. signature:: if(<variable>)
|
||
|
:target: variable
|
||
|
|
||
|
True if given a variable that is defined to a value that is not a false
|
||
|
constant. False otherwise, including if the variable is undefined.
|
||
|
Note that macro arguments are not variables.
|
||
|
:ref:`Environment Variables <CMake Language Environment Variables>` also
|
||
|
cannot be tested this way, e.g. ``if(ENV{some_var})`` will always evaluate
|
||
|
to false.
|
||
|
|
||
|
.. signature:: if(<string>)
|
||
|
:target: string
|
||
|
|
||
|
A quoted string always evaluates to false unless:
|
||
|
|
||
|
* The string's value is one of the true constants, or
|
||
|
* Policy :policy:`CMP0054` is not set to ``NEW`` and the string's value
|
||
|
happens to be a variable name that is affected by :policy:`CMP0054`'s
|
||
|
behavior.
|
||
|
|
||
|
Logic Operators
|
||
|
"""""""""""""""
|
||
|
|
||
|
.. signature:: if(NOT <condition>)
|
||
|
|
||
|
True if the condition is not true.
|
||
|
|
||
|
.. signature:: if(<cond1> AND <cond2>)
|
||
|
:target: AND
|
||
|
|
||
|
True if both conditions would be considered true individually.
|
||
|
|
||
|
.. signature:: if(<cond1> OR <cond2>)
|
||
|
:target: OR
|
||
|
|
||
|
True if either condition would be considered true individually.
|
||
|
|
||
|
.. signature:: if((condition) AND (condition OR (condition)))
|
||
|
:target: parentheses
|
||
|
|
||
|
The conditions inside the parenthesis are evaluated first and then
|
||
|
the remaining condition is evaluated as in the other examples.
|
||
|
Where there are nested parenthesis the innermost are evaluated as part
|
||
|
of evaluating the condition that contains them.
|
||
|
|
||
|
Existence Checks
|
||
|
""""""""""""""""
|
||
|
|
||
|
.. signature:: if(COMMAND <command-name>)
|
||
|
|
||
|
True if the given name is a command, macro or function that can be
|
||
|
invoked.
|
||
|
|
||
|
.. signature:: if(POLICY <policy-id>)
|
||
|
|
||
|
True if the given name is an existing policy (of the form ``CMP<NNNN>``).
|
||
|
|
||
|
.. signature:: if(TARGET <target-name>)
|
||
|
|
||
|
True if the given name is an existing logical target name created
|
||
|
by a call to the :command:`add_executable`, :command:`add_library`,
|
||
|
or :command:`add_custom_target` command that has already been invoked
|
||
|
(in any directory).
|
||
|
|
||
|
.. signature:: if(TEST <test-name>)
|
||
|
|
||
|
.. versionadded:: 3.3
|
||
|
|
||
|
True if the given name is an existing test name created by the
|
||
|
:command:`add_test` command.
|
||
|
|
||
|
.. signature:: if(DEFINED <name>|CACHE{<name>}|ENV{<name>})
|
||
|
|
||
|
True if a variable, cache variable or environment variable
|
||
|
with given ``<name>`` is defined. The value of the variable
|
||
|
does not matter. Note the following caveats:
|
||
|
|
||
|
* Macro arguments are not variables.
|
||
|
* It is not possible to test directly whether a `<name>` is a non-cache
|
||
|
variable. The expression ``if(DEFINED someName)`` will evaluate to true
|
||
|
if either a cache or non-cache variable ``someName`` exists. In
|
||
|
comparison, the expression ``if(DEFINED CACHE{someName})`` will only
|
||
|
evaluate to true if a cache variable ``someName`` exists. Both expressions
|
||
|
need to be tested if you need to know whether a non-cache variable exists:
|
||
|
``if(DEFINED someName AND NOT DEFINED CACHE{someName})``.
|
||
|
|
||
|
.. versionadded:: 3.14
|
||
|
Added support for ``CACHE{<name>}`` variables.
|
||
|
|
||
|
.. signature:: if(<variable|string> IN_LIST <variable>)
|
||
|
:target: IN_LIST
|
||
|
|
||
|
.. versionadded:: 3.3
|
||
|
|
||
|
True if the given element is contained in the named list variable.
|
||
|
|
||
|
File Operations
|
||
|
"""""""""""""""
|
||
|
|
||
|
.. signature:: if(EXISTS <path-to-file-or-directory>)
|
||
|
|
||
|
True if the named file or directory exists and is readable. Behavior
|
||
|
is well-defined only for explicit full paths (a leading ``~/`` is not
|
||
|
expanded as a home directory and is considered a relative path).
|
||
|
Resolves symbolic links, i.e. if the named file or directory is a
|
||
|
symbolic link, returns true if the target of the symbolic link exists.
|
||
|
|
||
|
False if the given path is an empty string.
|
||
|
|
||
|
.. signature:: if(<file1> IS_NEWER_THAN <file2>)
|
||
|
:target: IS_NEWER_THAN
|
||
|
|
||
|
True if ``file1`` is newer than ``file2`` or if one of the two files doesn't
|
||
|
exist. Behavior is well-defined only for full paths. If the file
|
||
|
time stamps are exactly the same, an ``IS_NEWER_THAN`` comparison returns
|
||
|
true, so that any dependent build operations will occur in the event
|
||
|
of a tie. This includes the case of passing the same file name for
|
||
|
both file1 and file2.
|
||
|
|
||
|
.. signature:: if(IS_DIRECTORY <path>)
|
||
|
|
||
|
True if ``path`` is a directory. Behavior is well-defined only
|
||
|
for full paths.
|
||
|
|
||
|
False if the given path is an empty string.
|
||
|
|
||
|
.. signature:: if(IS_SYMLINK <path>)
|
||
|
|
||
|
True if the given path is a symbolic link. Behavior is well-defined
|
||
|
only for full paths.
|
||
|
|
||
|
.. signature:: if(IS_ABSOLUTE <path>)
|
||
|
|
||
|
True if the given path is an absolute path. Note the following special
|
||
|
cases:
|
||
|
|
||
|
* An empty ``path`` evaluates to false.
|
||
|
* On Windows hosts, any ``path`` that begins with a drive letter and colon
|
||
|
(e.g. ``C:``), a forward slash or a backslash will evaluate to true.
|
||
|
This means a path like ``C:no\base\dir`` will evaluate to true, even
|
||
|
though the non-drive part of the path is relative.
|
||
|
* On non-Windows hosts, any ``path`` that begins with a tilde (``~``)
|
||
|
evaluates to true.
|
||
|
|
||
|
Comparisons
|
||
|
"""""""""""
|
||
|
|
||
|
.. signature:: if(<variable|string> MATCHES <regex>)
|
||
|
:target: MATCHES
|
||
|
|
||
|
True if the given string or variable's value matches the given regular
|
||
|
expression. See :ref:`Regex Specification` for regex format.
|
||
|
|
||
|
.. versionadded:: 3.9
|
||
|
``()`` groups are captured in :variable:`CMAKE_MATCH_<n>` variables.
|
||
|
|
||
|
.. signature:: if(<variable|string> LESS <variable|string>)
|
||
|
:target: LESS
|
||
|
|
||
|
True if the given string or variable's value is a valid number and less
|
||
|
than that on the right.
|
||
|
|
||
|
.. signature:: if(<variable|string> GREATER <variable|string>)
|
||
|
:target: GREATER
|
||
|
|
||
|
True if the given string or variable's value is a valid number and greater
|
||
|
than that on the right.
|
||
|
|
||
|
.. signature:: if(<variable|string> EQUAL <variable|string>)
|
||
|
:target: EQUAL
|
||
|
|
||
|
True if the given string or variable's value is a valid number and equal
|
||
|
to that on the right.
|
||
|
|
||
|
.. signature:: if(<variable|string> LESS_EQUAL <variable|string>)
|
||
|
:target: LESS_EQUAL
|
||
|
|
||
|
.. versionadded:: 3.7
|
||
|
|
||
|
True if the given string or variable's value is a valid number and less
|
||
|
than or equal to that on the right.
|
||
|
|
||
|
.. signature:: if(<variable|string> GREATER_EQUAL <variable|string>)
|
||
|
:target: GREATER_EQUAL
|
||
|
|
||
|
.. versionadded:: 3.7
|
||
|
|
||
|
True if the given string or variable's value is a valid number and greater
|
||
|
than or equal to that on the right.
|
||
|
|
||
|
.. signature:: if(<variable|string> STRLESS <variable|string>)
|
||
|
:target: STRLESS
|
||
|
|
||
|
True if the given string or variable's value is lexicographically less
|
||
|
than the string or variable on the right.
|
||
|
|
||
|
.. signature:: if(<variable|string> STRGREATER <variable|string>)
|
||
|
:target: STRGREATER
|
||
|
|
||
|
True if the given string or variable's value is lexicographically greater
|
||
|
than the string or variable on the right.
|
||
|
|
||
|
.. signature:: if(<variable|string> STREQUAL <variable|string>)
|
||
|
:target: STREQUAL
|
||
|
|
||
|
True if the given string or variable's value is lexicographically equal
|
||
|
to the string or variable on the right.
|
||
|
|
||
|
.. signature:: if(<variable|string> STRLESS_EQUAL <variable|string>)
|
||
|
:target: STRLESS_EQUAL
|
||
|
|
||
|
.. versionadded:: 3.7
|
||
|
|
||
|
True if the given string or variable's value is lexicographically less
|
||
|
than or equal to the string or variable on the right.
|
||
|
|
||
|
.. signature:: if(<variable|string> STRGREATER_EQUAL <variable|string>)
|
||
|
:target: STRGREATER_EQUAL
|
||
|
|
||
|
.. versionadded:: 3.7
|
||
|
|
||
|
True if the given string or variable's value is lexicographically greater
|
||
|
than or equal to the string or variable on the right.
|
||
|
|
||
|
Version Comparisons
|
||
|
"""""""""""""""""""
|
||
|
|
||
|
.. signature:: if(<variable|string> VERSION_LESS <variable|string>)
|
||
|
:target: VERSION_LESS
|
||
|
|
||
|
Component-wise integer version number comparison (version format is
|
||
|
``major[.minor[.patch[.tweak]]]``, omitted components are treated as zero).
|
||
|
Any non-integer version component or non-integer trailing part of a version
|
||
|
component effectively truncates the string at that point.
|
||
|
|
||
|
.. signature:: if(<variable|string> VERSION_GREATER <variable|string>)
|
||
|
:target: VERSION_GREATER
|
||
|
|
||
|
Component-wise integer version number comparison (version format is
|
||
|
``major[.minor[.patch[.tweak]]]``, omitted components are treated as zero).
|
||
|
Any non-integer version component or non-integer trailing part of a version
|
||
|
component effectively truncates the string at that point.
|
||
|
|
||
|
.. signature:: if(<variable|string> VERSION_EQUAL <variable|string>)
|
||
|
:target: VERSION_EQUAL
|
||
|
|
||
|
Component-wise integer version number comparison (version format is
|
||
|
``major[.minor[.patch[.tweak]]]``, omitted components are treated as zero).
|
||
|
Any non-integer version component or non-integer trailing part of a version
|
||
|
component effectively truncates the string at that point.
|
||
|
|
||
|
.. signature:: if(<variable|string> VERSION_LESS_EQUAL <variable|string>)
|
||
|
:target: VERSION_LESS_EQUAL
|
||
|
|
||
|
.. versionadded:: 3.7
|
||
|
|
||
|
Component-wise integer version number comparison (version format is
|
||
|
``major[.minor[.patch[.tweak]]]``, omitted components are treated as zero).
|
||
|
Any non-integer version component or non-integer trailing part of a version
|
||
|
component effectively truncates the string at that point.
|
||
|
|
||
|
.. signature:: if(<variable|string> VERSION_GREATER_EQUAL <variable|string>)
|
||
|
:target: VERSION_GREATER_EQUAL
|
||
|
|
||
|
.. versionadded:: 3.7
|
||
|
|
||
|
Component-wise integer version number comparison (version format is
|
||
|
``major[.minor[.patch[.tweak]]]``, omitted components are treated as zero).
|
||
|
Any non-integer version component or non-integer trailing part of a version
|
||
|
component effectively truncates the string at that point.
|
||
|
|
||
|
Path Comparisons
|
||
|
""""""""""""""""
|
||
|
|
||
|
.. signature:: if(<variable|string> PATH_EQUAL <variable|string>)
|
||
|
:target: PATH_EQUAL
|
||
|
|
||
|
.. versionadded:: 3.24
|
||
|
|
||
|
Compares the two paths component-by-component. Only if every component of
|
||
|
both paths match will the two paths compare equal. Multiple path separators
|
||
|
are effectively collapsed into a single separator, but note that backslashes
|
||
|
are not converted to forward slashes. No other
|
||
|
:ref:`path normalization <Normalization>` is performed.
|
||
|
|
||
|
Component-wise comparison is superior to string-based comparison due to the
|
||
|
handling of multiple path separators. In the following example, the
|
||
|
expression evaluates to true using ``PATH_EQUAL``, but false with
|
||
|
``STREQUAL``:
|
||
|
|
||
|
.. code-block:: cmake
|
||
|
|
||
|
# comparison is TRUE
|
||
|
if ("/a//b/c" PATH_EQUAL "/a/b/c")
|
||
|
...
|
||
|
endif()
|
||
|
|
||
|
# comparison is FALSE
|
||
|
if ("/a//b/c" STREQUAL "/a/b/c")
|
||
|
...
|
||
|
endif()
|
||
|
|
||
|
See :ref:`cmake_path(COMPARE) <Path COMPARE>` for more details.
|
||
|
|
||
|
Variable Expansion
|
||
|
^^^^^^^^^^^^^^^^^^
|
||
|
|
||
|
The if command was written very early in CMake's history, predating
|
||
|
the ``${}`` variable evaluation syntax, and for convenience evaluates
|
||
|
variables named by its arguments as shown in the above signatures.
|
||
|
Note that normal variable evaluation with ``${}`` applies before the if
|
||
|
command even receives the arguments. Therefore code like
|
||
|
|
||
|
.. code-block:: cmake
|
||
|
|
||
|
set(var1 OFF)
|
||
|
set(var2 "var1")
|
||
|
if(${var2})
|
||
|
|
||
|
appears to the if command as
|
||
|
|
||
|
.. code-block:: cmake
|
||
|
|
||
|
if(var1)
|
||
|
|
||
|
and is evaluated according to the ``if(<variable>)`` case documented
|
||
|
above. The result is ``OFF`` which is false. However, if we remove the
|
||
|
``${}`` from the example then the command sees
|
||
|
|
||
|
.. code-block:: cmake
|
||
|
|
||
|
if(var2)
|
||
|
|
||
|
which is true because ``var2`` is defined to ``var1`` which is not a false
|
||
|
constant.
|
||
|
|
||
|
Automatic evaluation applies in the other cases whenever the
|
||
|
above-documented condition syntax accepts ``<variable|string>``:
|
||
|
|
||
|
* The left hand argument to `MATCHES`_ is first checked to see if it is
|
||
|
a defined variable. If so, the variable's value is used, otherwise the
|
||
|
original value is used.
|
||
|
|
||
|
* If the left hand argument to `MATCHES`_ is missing it returns false
|
||
|
without error
|
||
|
|
||
|
* Both left and right hand arguments to `LESS`_, `GREATER`_, `EQUAL`_,
|
||
|
`LESS_EQUAL`_, and `GREATER_EQUAL`_, are independently tested to see if
|
||
|
they are defined variables. If so, their defined values are used otherwise
|
||
|
the original value is used.
|
||
|
|
||
|
* Both left and right hand arguments to `STRLESS`_, `STRGREATER`_,
|
||
|
`STREQUAL`_, `STRLESS_EQUAL`_, and `STRGREATER_EQUAL`_ are independently
|
||
|
tested to see if they are defined variables. If so, their defined values are
|
||
|
used otherwise the original value is used.
|
||
|
|
||
|
* Both left and right hand arguments to `VERSION_LESS`_,
|
||
|
`VERSION_GREATER`_, `VERSION_EQUAL`_, `VERSION_LESS_EQUAL`_, and
|
||
|
`VERSION_GREATER_EQUAL`_ are independently tested to see if they are defined
|
||
|
variables. If so, their defined values are used otherwise the original value
|
||
|
is used.
|
||
|
|
||
|
* The right hand argument to `NOT`_ is tested to see if it is a boolean
|
||
|
constant. If so, the value is used, otherwise it is assumed to be a
|
||
|
variable and it is dereferenced.
|
||
|
|
||
|
* The left and right hand arguments to `AND`_ and `OR`_ are independently
|
||
|
tested to see if they are boolean constants. If so, they are used as
|
||
|
such, otherwise they are assumed to be variables and are dereferenced.
|
||
|
|
||
|
.. versionchanged:: 3.1
|
||
|
To prevent ambiguity, potential variable or keyword names can be
|
||
|
specified in a :ref:`Quoted Argument` or a :ref:`Bracket Argument`.
|
||
|
A quoted or bracketed variable or keyword will be interpreted as a
|
||
|
string and not dereferenced or interpreted.
|
||
|
See policy :policy:`CMP0054`.
|
||
|
|
||
|
There is no automatic evaluation for environment or cache
|
||
|
:ref:`Variable References`. Their values must be referenced as
|
||
|
``$ENV{<name>}`` or ``$CACHE{<name>}`` wherever the above-documented
|
||
|
condition syntax accepts ``<variable|string>``.
|
||
|
|
||
|
See also
|
||
|
^^^^^^^^
|
||
|
|
||
|
* :command:`else`
|
||
|
* :command:`elseif`
|
||
|
* :command:`endif`
|