在CMake中什么时候应该用$ {...}包装变量? [英] When should I wrap variables with ${...} in CMake?

查看:361
本文介绍了在CMake中什么时候应该用$ {...}包装变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道为什么经常变量在CMake包裹一个美元符号和大括号。例如,我在CMake教程中看到了此调用

  include_directories($ {PROJECT_BINARY_DIR})

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

  include_directories(PROJECT_BINARY_DIR )

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

解决方案

引用 CMake文档


变量引用具有 $ {variable_name} 的形式,并且在引用的参数中评价为
,一个无参考的参数。变量引用
由变量的值替换,或者如果
未设置变量,则由空字符串替换。


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



考虑:

 设置(FOOHello there!)
message(FOO) print FOO
message($ {FOO})#prints你好!

您可能已经猜到了, include_directories(PROJECT_BINARY_DIR)只是尝试将名称为PROJECT_BINARY_DIR的子目录添加到include目录中。在大多数构建系统上,如果没有这样的目录存在,它将简单地忽略该命令,这可能欺骗你的印象,它按预期工作。



的混乱来自于 if()不需要显式解引用变量的事实:

  set(FOO TRUE)
if(FOO)
message(Foo was set!)
endif()
/ pre>

再次文档解释此行为


if(< constant>)



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



if(< variable>)



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


特别是,可以想出一些奇怪的例子:

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

这将需要 TRUE 和在常量情况下的 FALSE 分支。这是因为在常数情况下,CMake将寻找一个变量 BLA 来执行检查(这是没有定义的,因此我们最终在FALSE分支)。


I wonder why often variables in CMake are wrapped with a dollar sign and curly brackets. For example, I saw this call in a CMake tutorial.

include_directories(${PROJECT_BINARY_DIR})

But from what I tried, this does the same thing.

include_directories(PROJECT_BINARY_DIR)

When is the wrapping with ${...} needed and what does it mean? Why are variables often wrapped with this even if it makes no difference?

解决方案

Quoting the CMake documentation:

A variable reference has the form ${variable_name} and is evaluated inside a Quoted Argument or an Unquoted Argument. A variable reference is replaced by the value of the variable, or by the empty string if the variable is not set.

In other words, writing PROJECT_BINARY_DIR refers, literally, to the string "PROJECT_BINARY_DIR". Encapsulating it in ${...} gives you the contents of the variable with the name PROJECT_BINARY_DIR.

Consider:

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

As you have probably guessed already, include_directories(PROJECT_BINARY_DIR) simply attempts to add a subdirectory of the name PROJECT_BINARY_DIR to the include directories. On most build systems, if no such directory exists, it will simply ignore the command, which might have tricked you into the impression that it works as expected.

A popular source of confusion comes from the fact that if() does not require explicit dereferencing of variables:

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

Again the documentation explains this behavior:

if(<constant>)

True if the constant is 1, ON, YES, TRUE, Y, or a non-zero number. False if the constant is 0, OFF, NO, FALSE, N, IGNORE, NOTFOUND, the empty string, or ends in the suffix -NOTFOUND. Named boolean constants are case-insensitive. If the argument is not one of these constants, it is treated as a variable.

if(<variable>)

True if the variable is defined to a value that is not a false constant. False otherwise. (Note macro arguments are not variables.)

In particular, one can come up with weird examples like:

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

Which will take the TRUE branch in the variable case, and the FALSE branch in the constant case. This is due to the fact that in the constant case, CMake will go look for a variable BLA to perform the check on (which is not defined, hence we end up in the FALSE branch).

这篇关于在CMake中什么时候应该用$ {...}包装变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆