CMake - if() 命令如何处理符号?作为字符串还是作为变量?

smw*_*dia 6 cmake cmake-language

我不确定 CMakeif()命令是否会将条件子句中的符号视为变量字符串文字。所以我做了一些实验。

脚本1.cmake

cmake_minimum_required(VERSION 3.15)

set(XXX "YYY") #<========== HERE!!

if(XXX STREQUAL "XXX")
    message("condition 1 is true") # If reach here, XXX is treated as string
elseif(XXX STREQUAL "YYY")
    message("condition 2 is true") # If reach here, XXX is treated as variable
endif()
Run Code Online (Sandbox Code Playgroud)

输出是:

condition 2 is true
Run Code Online (Sandbox Code Playgroud)

所以我得出结论1

对于条件子句中的符号:

  • 如果之前将符号定义为变量,CMake 会将其视为变量并使用其值进行评估。
  • 如果之前没有将符号定义为变量,CMake 会将其视为字符串。

然后我又做了一个实验。

set(ON "OFF")
if(ON)
    message("condition 3 is true") # If reach here, ON is treated as a constant.
else()
    message("condition 4 is true") # If reach here. ON is treated as a variable.
endif()
Run Code Online (Sandbox Code Playgroud)

输出是:

condition 3 is true
Run Code Online (Sandbox Code Playgroud)

因此,尽管ON明确定义为变量,该if命令仍然把它当作真值的恒定。这与我之前的结论 1直接矛盾。

那么我如何确定 CMake if() 命令会将符号视为字符串或变量?

添加 1 - 11:04 上午 7/11/2019

似乎这种if(constant)形式先于其他形式的if()陈述。(SRC

if(<constant>)
Run Code Online (Sandbox Code Playgroud)

如果常量为 1、ON、YES、TRUE、Y 或非零数,则为真。如果常量为 0、OFF、NO、FALSE、N、IGNORE、NOTFOUND、空字符串或以后缀 -NOTFOUND 结尾,则为 False。命名的布尔常量不区分大小写。如果参数不是这些特定常量之一,则将其视为变量或字符串,并使用以下签名。

所以现在,在应用我的结论 1之前,我必须首先参考上述规则。(这可能是一个答案,但我还不确定。)

tay*_*10r 5

欢迎来到 CMake 符号解释的荒野。

如果符号作为变量存在,则使用变量的值来计算表达式。否则,将改为评估变量的名称(或文字,如您所说)。

${如果添加和}序列,行为会变得更加一致。然后每次评估时都会使用变量的值。如果变量不存在或尚未分配值,则 CMake 使用多个计算结果为“false”的占位符值。这些是您在帖子后半部分提到的价值观。

我相信这样做是为了向后兼容,CMake 对此非常擅长。对于 CMake 所做的大多数奇怪的事情,通常都是以向后兼容性的名义。

至于您在“ON”变量中提到的不一致行为,这可能是由于 CMake 处理命令参数的优先级造成的。我必须弄清楚在符号查找发生之前解析常量。

因此,当谈到了解/预测一个if陈述将如何评估时,我最好的答案是经验。CMake 源代码树和逻辑是一头宏伟而令人讨厌的野兽。

人们一直在讨论添加一种替代语言(一种可能具有函数范式的语言),但这是一项相当艰巨的任务。