6

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

Script1.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()

输出是:

condition 2 is true

所以我得出以下结论 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()

输出是:

condition 3 is true

因此,尽管明确定义为变量,该ON命令仍将其视为 TRUE 值的常量。这与我之前的结论 1直接矛盾。if

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

2019 年 7 月 11 日上午 11:04 添加

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

if(<constant>)

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

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

4

1 回答 1

3

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

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

如果添加${and}序列,行为会变得更加一致。然后每次在评估中使用变量的值。如果变量不存在或没有被赋值,那么 CMake 会使用几个占位符值,这些值评估为“假”。这些是您在帖子后半部分提到的价值观。

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

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

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

已经讨论过添加一种替代语言(一种可能具有功能范式的语言),但这是一项相当大的工作。

于 2019-07-11T03:11:16.103 回答