在CMake中if(<string>)中<string>的计算值是多少?

时间:2019-12-21 08:04:09

标签: cmake cmake-language

我的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

1 个答案:

答案 0 :(得分:1)

您正在documentation中的正确位置寻找内容:

  

if(<variable|string>)

     

如果给出的变量定义为不是假常量的值,则为真。否则为假。 (请注意,宏参数不是变量。)

但是,文档没有完成,因为没有明确提到<string>情况。仅包含字符串的CMake if语句的行为与此处描述的变量相比,有不同的表现。字符串文档应为:

  

如果给出的字符串确实匹配真实常量(1ONYESTRUEY或非零),则为真数)。否则为假。

换句话说,与这些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);
}