我的hello.txt
cmake_policy(SET CMP0054 NEW)
set(VAR ON)
# VAR will be treated as a string
if("VAR")
message(TRUE)
else()
message(FALSE)
endif()
# output prints FALSE
从策略CMP0054:
为防止歧义,可以在带引号的引号或括弧式引号中指定潜在的变量或关键字名称。带引号或方括号的变量或关键字将被解释为字符串,而不会被取消引用或解释。请参阅政策CMP0054。
CMake文档没有提及if(<string>)
:
if(<variable|string>)
如果给出的变量定义为不是假常量的值,则为真。否则为假。 (请注意,宏参数不是变量。)
为什么非空字符串的求值为FALSE
?
答案 0 :(得分:1)
您正在documentation中的正确位置寻找内容:
if(<variable|string>)
如果给出的变量定义为不是假常量的值,则为真。否则为假。 (请注意,宏参数不是变量。)
但是,文档没有完成,因为没有明确提到<string>
情况。仅包含字符串的CMake if语句的行为与此处描述的变量相比,有不同的表现。字符串文档应为:
如果给出的字符串确实匹配真实常量(
1
,ON
,YES
,TRUE
,Y
或非零),则为真数)。否则为假。
换句话说,与这些CMake true常量之一不匹配的任何字符串都将计算为False。正如您已经指出的,字符串"VAR"
:
if ("VAR")
message(TRUE)
else()
message(FALSE)
endif()
打印FALSE
。但是,将一个真正的常量作为字符串(例如"y"
):
if ("y")
message(TRUE)
else()
message(FALSE)
endif()
打印TRUE
。
此逻辑可以在名为GetBooleanValue()
的函数中的CMake source code中进行验证:
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);
}