我什么时候应该引用CMake变量? [英] When should I quote CMake variables?

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

问题描述

我是第一次编写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:

  1. CMake是一种脚本语言,变量展开后会评估参数
  2. 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") with message("${_my_text}") would give A B C
  • set(_my_list A B C) with message("${_my_list}") would give A;B;C
  • set(_my_list "A" "B" "C") with message("${_my_list}") would give A;B;C
  • set(_my_list "A" "B" "C") with message(${_my_list}) would give ABC

一些经验法则

您应该考虑一些经验法则:

There are some rules of thumb you should consider:

  1. a)当变量包含文本(尤其是可能包含分号的文本)时,应添加引号.

  1. 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") with message(${_my_text}) would also give A B C
  • set(_my_text "A;B;C") with if (${_my_text} STREQUAL "A;B;C") would give if 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
    • 上致电cmake.exe -E echo "A B C"
    • GCC/Ubuntu
    • 上致电cmake -E echo A\ B\ C
    • 给予A B C
    • set(_my_text "A B C") with COMMAND "${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
      • 上致电cmake.exe -E echo "A B C"
      • GCC/Ubuntu
      • 上致电cmake -E echo "A B C"
      • 给予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
      • 给予AB: command not foundC: 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:

      1. a)对包含文件路径的参数使用引号(例如,包含可执行文件本身的第一个参数).

      1. 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 call

      b)参见上文,如果变量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屋!

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