我什么时候应该引用CMake变量? [英] When should I quote CMake variables?
问题描述
我是第一次编写CMake宏,我很难理解变量的工作方式.最具体地说,${a}
似乎与"${a}"
的含义不同.
I am writing CMake macros for the first time, and I have a hard time understanding how variables work. Most specifically, ${a}
seems to have a different meaning than "${a}"
.
例如此处: 将列表传递给CMake宏
For example here: Passing a list to a CMake macro
我不知道何时应该添加引号以及更重要的基本原则.
I fail to understand when I am supposed to add quotes, and what are the bigger underlying principles.
推荐答案
CMake的两个原则必须牢记:
Two principles of CMake you have to keep in mind:
- CMake是一种脚本语言,变量展开后会评估参数
- CMake区分普通字符串和列表变量(带有分号分隔符的字符串)
示例
-
set(_my_text "A B C")
和message("${_my_text}")
将给出A B C
-
set(_my_list A B C)
和message("${_my_list}")
将给出A;B;C
-
set(_my_list "A" "B" "C")
和message("${_my_list}")
将给出A;B;C
-
set(_my_list "A" "B" "C")
与message(${_my_list})
将给出ABC
set(_my_text "A B C")
withmessage("${_my_text}")
would giveA B C
set(_my_list A B C)
withmessage("${_my_list}")
would giveA;B;C
set(_my_list "A" "B" "C")
withmessage("${_my_list}")
would giveA;B;C
set(_my_list "A" "B" "C")
withmessage(${_my_list})
would giveABC
一些经验法则
您应该考虑一些经验法则:
There are some rules of thumb you should consider:
-
a)当变量包含文本(尤其是可能包含分号的文本)时,应添加引号.
a) When your variable contains text - especially one that could contain semicolons - you should add quotes.
原因:分号是CMake中列表元素的定界符.因此,将引号括起来应该是一个文本(它可以在任何地方使用,并且对我个人而言,CMake语法突出显示效果更好)
Reasoning: A semicolon is a delimiter for list elements in CMake. So put quotes around a text that is supposed to be one (it works everywhere and for me personally looks better with CMake syntax highlighting)
编辑:感谢@schieferstapel的提示
Thanks for the hint from @schieferstapel
b)更准确地说:变量内容的空格已带有引号,但确实保留了这些引号(可以想象,变量内容已成为变量内容的一部分).除了if()
调用的显着例外,该方法还可以在所有未加引号(正常或用户定义的函数参数)的地方工作,其中CMake在变量扩展后重新解释未加引号的变量的内容(另请参见经验法则#3和策略 CMP0054:仅将if()
参数解释为未引用的变量或关键字)
b) To be more precise: A variable content with spaces that already had quotes does keep those quotes (imagine as it getting part of the variable's content). This works everywhere also unquoted (normal or user-defined function parameters) with the prominent exception of if()
calls, where CMake re-interprets the content of unquoted variables after variable expansion (see also rule of thumb #3 and policy CMP0054: Only interpret if()
arguments as variables or keywords when unquoted)
示例:
-
set(_my_text "A B C")
与message(${_my_text})
也会给出A B C
-
set(_my_text "A;B;C")
和if (${_my_text} STREQUAL "A;B;C")
将给出if given arguments: "A" "B" "C" "STREQUAL" "A;B;C" Unknown arguments specified
set(_my_text "A B C")
withmessage(${_my_text})
would also giveA B C
set(_my_text "A;B;C")
withif (${_my_text} STREQUAL "A;B;C")
would giveif given arguments: "A" "B" "C" "STREQUAL" "A;B;C" Unknown arguments specified
如果您的变量包含列表,通常不会添加引号.
If your variable contains a list you normally don't add quotes.
原因:如果您给CMake命令一个文件列表之类的东西,通常会期望一个字符串列表,而不是一个包含列表的字符串.您可以看到的区别例如在 foreach()
命令中,接受ITEMS
或
Reasoning: If you give something like a file list to an CMake command it normally expect a list of strings and not one string containing a list. The difference you can see e.g. in the foreach()
command accepting ITEMS
or LISTS
.
if()
语句是一种特殊情况,通常您甚至都不会放括号.
if()
statements are a special case where you normally don't even put the braces.
原因:扩展后的字符串可以再次求值为变量名.为避免这种情况,建议仅命名要比较其内容的变量(例如if (_my_text STREQUAL "A B C")
).
Reasoning: A string could - after expansion - evaluate again to a variable name. To prevent this it's recommended to just name the variable whose content you want to compare (e.g. if (_my_text STREQUAL "A B C")
).
COMMAND
示例
COMMAND
Examples
-
set(_my_text "A B C")
与COMMAND "${CMAKE_COMMAND}" -E echo "${_my_text}"
- 在 VS/Windows 上致电
- 在 GCC/Ubuntu 上致电
- 给予
A B C
cmake.exe -E echo "A B C"
cmake -E echo A\ B\ C
set(_my_text "A B C")
withCOMMAND "${CMAKE_COMMAND}" -E echo "${_my_text}"
would- call
cmake.exe -E echo "A B C"
on VS/Windows - call
cmake -E echo A\ B\ C
on GCC/Ubuntu - give
A B C
- 在 VS/Windows 上致电
- 在 GCC/Ubuntu 上致电
- 给予
A B C
cmake.exe -E echo "A B C"
cmake -E echo "A B C"
- call
cmake.exe -E echo "A B C"
on VS/Windows - call
cmake -E echo "A B C"
on GCC/Ubuntu - give
A B C
- 致电
cmake.exe -E echo A;B;C
- 给予
A
,B: command not found
,C: command not found
- call
cmake.exe -E echo A;B;C
- give
A
,B: command not found
,C: command not found
- 致电
cmake.exe -E echo "A;B;C"
- 给予
A;B;C
- call
cmake.exe -E echo "A;B;C"
- give
A;B;C
- 致电
cmake.exe -E echo "A;B;C"
- 给予
A;B;C
- call
cmake.exe -E echo "A;B;C"
- give
A;B;C
- 致电
cmake.exe -E echo A B C
- 给予
A B C
- call
cmake.exe -E echo A B C
- give
A B C
- 致电
cmake.exe -E echo "A + B" = C
- 给予
A + B = C
- call
cmake.exe -E echo "A + B" = C
- give
A + B = C
使用
add_custom_target()
/add_custom_command()
/execute_process()
Some Rules of Thumb with
add_custom_target()
/add_custom_command()
/execute_process()
在
COMMAND
调用中使用变量时,应考虑一些经验法则:There are some rules of thumb you should consider when you use variables in
COMMAND
calls:-
a)对包含文件路径的参数使用引号(例如,包含可执行文件本身的第一个参数).
a) Use quotes for the arguments that contain file paths (like the first argument containing the executable itself).
原因:它可以包含空格,并且可以重新解释为
COMMAND
调用的单独参数Reasoning: It could contain spaces and could be reinterpreted as separate arguments to the
COMMAND
callb)参见上文,如果变量
set()
确实包含引号也可以使用.b) See above, works also if the variable
set()
did include quotes.如果要将内容连接到单个参数中以传递给被调用的可执行文件,请仅使用引号 .
Use quotes only if you want to concatenate something into a single parameter to be passed to executable that is called.
原因:变量可能包含参数列表,使用引号时,这些参数将无法正确提取(用分号代替空格)
Reasoning: A variable could contain a list of parameters which - when using quotes - won't be correctly extracted (semicolons instead of spaces)
始终在
add_custom_target()
/add_custom_command()
原因:否则,跨平台行为是不确定的,引号引起的字符串可能会给您带来惊喜.
Reasoning: Otherwise the cross-platform behavior is undefined and you could get surprises with your quoted strings.
参考
- CMake: difference between ${} and "${}"
- What's the CMake syntax to set and use variables?
- Looping over a string list
- CMake compare to empty string with STREQUAL failed
这篇关于我什么时候应该引用CMake变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
- call