2014-09-12 209 views
15

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

include_directories(${PROJECT_BINARY_DIR}) 

但是从我所尝试的,这是做同样的事情。

include_directories(PROJECT_BINARY_DIR) 

什么时候需要打包${...},这是什么意思?为什么变量经常包含这个,即使它没有区别?

回答

14

引用the CMake documentation

可变参考的形式${variable_name}和评价 一个引用参数或无报价参数内。变量参考 被替换为变量的值,或者如果未设置该变量,则通过空字符串取代 。

换句话说,编写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的子目录添加到include目录。在大多数构建系统中,如果不存在这样的目录,则它将简单地忽略该命令,这可能已经诱使您认为它按预期工作。

混乱的流行源来自一个事实,即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, 空字符串,或者以后缀-NOTFOUND结尾,则为False。命名布尔常量 不区分大小写。如果参数不是这些常量中的一个,则它被视为一个变量。

if(<variable>)

如果变量被定义为不是错误的恒定的值

真。否则为假。 (注意宏参数不是变量。)

特别地,人们可以想出像怪异的例子:

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分支中)。

+0

那么像if(SFML_FOUND)'这样的工作如何呢? – danijar 2014-09-12 13:43:13

+2

'if()'是一个特例,因为它对变量和值都起作用。虽然'if(SFML_FOUND)'和'if($ {SFML_FOUND})'可以同时工作,但它们实际上做了不同的事情:检查[if']的文档(http://www.cmake.org/cmake/help /v3.0/command/if.html),并特别注意'if()'和'if()'之间的区别。我会相应地更新答案。 – ComicSansMS 2014-09-12 13:45:56

相关问题