我什么时候应该在CMake中用$ {...}包装变量?

时间:2014-09-12 13:20:47

标签: cmake

我想知道为什么CMake中的变量经常用美元符号和大括号括起来。例如,我看到了这个电话in a CMake tutorial

include_directories(${PROJECT_BINARY_DIR})

但是从我的尝试来看,这也是做同样的事情。

include_directories(PROJECT_BINARY_DIR)

何时需要${...}包裹,这是什么意思?为什么变量经常包含在内,即使它没有任何区别?

1 个答案:

答案 0 :(得分:19)

引用the CMake documentation

  

变量引用的格式为${variable_name},并进行评估   在引用的参数或不带引号的参数中。变量引用   由变量的值替换,或由空字符串if替换   该变量未设置。

换句话说,写PROJECT_BINARY_DIR字面意思是字符串“PROJECT_BINARY_DIR”。将其封装在${...}中会为您提供变量的内容,名称为PROJECT_BINARY_DIR。

考虑:

set(FOO "Hello there!")
message(FOO)     # prints FOO
message(${FOO})  # prints Hello there!

正如您可能已经猜到的那样,include_directories(PROJECT_BINARY_DIR)只是尝试将名称PROJECT_BINARY_DIR的子目录添加到包含目录中。在大多数构建系统中,如果不存在这样的目录,它将完全忽略该命令,这可能会让您觉得它按预期工作。

一个流行的混淆来源于if()不需要显式解除引用变量的事实:

set(FOO TRUE)
if(FOO)
    message("Foo was set!")
endif()

再次the documentation explains this behavior

  

if(<constant>)

     

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

     

if(<variable>)

     

如果变量定义为不是假常量的值,则为true。否则就错了。 (注意宏参数不是变量。)

特别是,人们可以提出一些奇怪的例子:

unset(BLA)
set(FOO "BLA")
if(FOO)
    message("if(<variable>): True")
else()
    message("if(<variable>): False")
endif()
if(${FOO})
    message("if(<constant>): True")
else()
    message("if(<constant>): False")
endif()

将在变量大小写中使用TRUE分支,在常量大小写中使用FALSE分支。这是因为在常量情况下,CMake将寻找变量BLA来执行检查(未定义,因此我们最终进入FALSE分支)。