You are looking in the right place in the documentation:
if(<variable|string>)
True if given a variable that is defined to a value that is not a false constant. False otherwise. (Note macro arguments are not variables.)
However, the documentation is not complete, as the <string>
case is not explicitly mentioned. The behavior for CMake if-statements simply containing a string is different than what is described here for variables. The documentation for strings should read:
True if given a string that does matches a true constant (1
, ON
, YES
, TRUE
, Y
, or a non-zero number). False otherwise.
In other words, any string that doesn't match one of these CMake true constants will evaluate to False. As you already pointed out, the string "VAR"
:
if ("VAR")
message(TRUE)
else()
message(FALSE)
endif()
prints FALSE
. However, a true constant as a string (let's say "y"
):
if ("y")
message(TRUE)
else()
message(FALSE)
endif()
prints TRUE
.
This logic is verifiable in the CMake source code in a function called GetBooleanValue()
:
bool cmConditionEvaluator::GetBooleanValue(
cmExpandedCommandArgument& arg) const
{
// Check basic constants.
if (arg == "0") {
return false;
}
if (arg == "1") {
return true;
}
// Check named constants.
if (cmIsOn(arg.GetValue())) {
return true;
}
if (cmIsOff(arg.GetValue())) {
return false;
}
// Check for numbers.
if (!arg.empty()) {
char* end;
double d = strtod(arg.c_str(), &end);
if (*end == '\0') {
// The whole string is a number. Use C conversion to bool.
return static_cast<bool>(d);
}
}
// Check definition.
const char* def = this->GetDefinitionIfUnquoted(arg);
return !cmIsOff(def);
}