我想知道为什么CMake中的变量经常用美元符号和大括号括起来.例如,我在CMake教程中看到了这个调用.
include_directories(${PROJECT_BINARY_DIR})
Run Code Online (Sandbox Code Playgroud)
但是从我的尝试来看,这也是一样的.
include_directories(PROJECT_BINARY_DIR)
Run Code Online (Sandbox Code Playgroud)
${...}什么时候需要包装,这是什么意思?为什么变量经常包含在内,即使它没有任何区别?
Com*_*sMS 20
引用CMake文档:
甲变量参考的形式
${variable_name}和一个引用参数或无报价参数内进行评价.变量引用将替换为变量的值,如果未设置变量,则替换为空字符串.
换句话说,PROJECT_BINARY_DIR字面意思是指字符串"PROJECT_BINARY_DIR".将其封装${...}为您提供名称为PROJECT_BINARY_DIR的变量的内容.
考虑:
set(FOO "Hello there!")
message(FOO) # prints FOO
message(${FOO}) # prints Hello there!
Run Code Online (Sandbox Code Playgroud)
您可能已经猜到了,include_directories(PROJECT_BINARY_DIR)只需尝试将名称PROJECT_BINARY_DIR的子目录添加到include目录中.在大多数构建系统中,如果不存在这样的目录,它将简单地忽略该命令,这可能会让您感觉它按预期工作.
一个流行的混淆来源于if()不需要显式解除引用变量的事实:
set(FOO TRUE)
if(FOO)
message("Foo was set!")
endif()
Run Code Online (Sandbox Code Playgroud)
if(<constant>)如果常量为1,ON,YES,TRUE,Y或非零数字,则为真.如果常量为0,OFF,NO,FALSE,N,IGNORE,NOTFOUND,空字符串或以后缀-NOTFOUND结尾,则返回false.命名的布尔常量不区分大小写.如果参数不是这些常量之一,则将其视为变量.
if(<variable>)如果变量定义为不是false常量的值,则为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()
Run Code Online (Sandbox Code Playgroud)
这将采用TRUE变量情况下的FALSE分支,以及常数情况下的分支.这是因为在常量情况下,CMake将寻找一个变量BLA来执行检查(未定义,因此我们最终进入FALSE分支).