[Documentation] the documentation for the if() command is not clear
https://cmake.org/cmake/help/latest/command/if.html#basic-expressions
The section in question is copied below:
Basic Expressions
if(<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.
if(<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. Environment Variables also cannot be tested this way, e.g. if(ENV{some_var}) will always evaluate to false.
if(<string>)
A quoted string always evaluates to false unless:
The string's value is one of the true constants, or
Policy CMP0054 is not set to NEW and the string's value happens to be a variable name that is affected by CMP0054's behavior.
The way this reads to me, and other people on my team, is that a variable, in the sense of something defined by set(VarNameHere blahblah)
is evaluated differently in if(VarNameHere)
than if(blahblah)
and if("blahblah")
.
The original source of the confusion was determining how cmake determines the result of querying target properties, where a not-found property has the result variable set to "PROPERTY_NAME-NOTFOUND". Our understanding is that because the result variable is a variable, the rules from the if(<constant>)
block do not apply.
The documentation would be substantially less confusing if it were not written in terms of the type of thing passed into the if()
function, but instead written in terms of the value.
Something like
Basic Expressions
Constant values referred to in the below sections:
- True constants
- 1, ON, YES, TRUE, Y, or a non-zero number (including floating point numbers)
- False constants
- 0, OFF, NO, FALSE, N, IGNORE, NOTFOUND, the empty string, or any string character sequence that ends in the suffix -NOTFOUND. This includes strings that could be interpreted as lists, if the last item in the list ends in -NOTFOUND.
The constants above are case-insensitive. ON is the same as oN and On. FALSE is the same as FaLsE and fAlSe. A string character sequence ending in -NOTFOUND is the same as a string character sequence ending in -NoTFoUnD.
if(<constant>)
- One of the True or False constants listed above, without quotation marks, written directly into the `if()` command's argument. A False constant results in the if() command's body being skipped. A true constant results in the body being evaluated.
- If the item provided to the if() command is not one of the True or False constants in the section above, then the item is evaluated as if it were a cmake variable, and the value held by that variable is evaluated as described below.
if(<variable>)
- False if the variable is not defined.
- True if given a variable that is not undefined, and is defined to any value that is *not* a False constant per the listing of False constants above, including variables which hold string character sequence ending in -NOTFOUND. The list of True constants is not relevant to determining if a variable is a True variable. Only that the value held by the variable is *NOT* a False constant.
- False otherwise.
- Note that macro arguments are not variables.
- Environment Variables also cannot be tested this way, e.g. if(ENV{some_var}) will always evaluate to false.
if(<string>)
A quoted string always evaluates to false unless:
- The string's value is one of the true constants
- Policy CMP0054 is not set to NEW and the string's value happens to be a variable name that is affected by CMP0054's behavior.
if(<Environment variable>)
- if(ENV{some_var}): Always false
- if(${ENV{some_var}}): See if(<string>)
Note that if(MY_VAR) and if(${MY_VAR}) are not the same.
- if(MY_VAR) is evaluated as if(<variable>).
- if(${MY_VAR}) is evaluated as if(<string>)