我第一次写CMake宏,我很难理解变量是如何工作的。最具体地说,${a}
似乎与"${a}"
具有不同的含义。
例如: Passing a list to a CMake macro
我无法理解何时应该添加引号,以及更重要的基本原则是什么。
答案 0 :(得分:49)
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
一些经验法则
您应该考虑一些经验法则:
a)当你的变量包含文本时 - 尤其是包含分号的文本 - 你应该添加引号。
推理:分号是CMake中列表元素的分隔符。所以在一个应该是一个的文本周围加上引号(它可以在任何地方使用,对于我个人看起来更好用CMake语法高亮)
编辑:感谢@schieferstapel的提示
b)更确切地说:具有已经有引号的空格的变量内容确实保留了这些引号(想象一下它获得变量内容的一部分)。这种方法在任何地方都可以使用不带引号(正常或用户定义的函数参数)以及if()
调用的突出例外,其中CMake在变量扩展后重新解释未引用变量的内容(另请参见经验法则#3和策略{ {3}})
示例:
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
如果您的变量包含列表,则通常不会添加引号。
推理:如果你给CMake命令提供类似文件列表的东西,它通常需要一个字符串列表而不是一个包含列表的字符串。您可以看到差异,例如在CMP0054: Only interpret if()
arguments as variables or keywords when unquoted命令中接受ITEMS
或LISTS
。
if()
声明是一种特殊情况,您通常不会戴上牙套。
推理:字符串可以 - 在扩展后 - 再次评估变量名称。为防止出现这种情况,建议您只为要比较其内容的变量命名(例如if (_my_text STREQUAL "A B C")
)。
COMMAND
示例
set(_my_text "A B C")
与COMMAND "${CMAKE_COMMAND}" -E echo "${_my_text}"
会
cmake.exe -E echo "A B C"
cmake -E echo A\ B\ C
A B C
set(_my_text "A B C")
与COMMAND "${CMAKE_COMMAND}" -E echo "${_my_text}" VERBATIM
会
cmake.exe -E echo "A B C"
cmake -E echo "A B C"
A B C
set(_my_list A B C)
与COMMAND "${CMAKE_COMMAND}" -E echo "${_my_list}"
会
cmake.exe -E echo A;B;C
A
,B: command not found
,C: command not found
set(_my_list A B C)
与COMMAND "${CMAKE_COMMAND}" -E echo "${_my_list}" VERBATIM
会
cmake.exe -E echo "A;B;C"
A;B;C
set(_my_list "A" "B" "C")
与COMMAND "${CMAKE_COMMAND}" -E echo "${_my_list}" VERBATIM
会
cmake.exe -E echo "A;B;C"
A;B;C
set(_my_list "A" "B" "C")
与COMMAND "${CMAKE_COMMAND}" -E echo ${_my_list}
VERBATIM
会
cmake.exe -E echo A B C
A B C
set(_my_list "A + B" "=" "C")
与COMMAND "${CMAKE_COMMAND}" -E echo ${_my_list} VERBATIM
会
cmake.exe -E echo "A + B" = C
A + B = C
add_custom_target()
/ add_custom_command()
/ execute_process()
在COMMAND
调用中使用变量时,您应该考虑一些经验法则:
a)对包含文件路径的参数使用引号(如包含可执行文件本身的第一个参数)。
推理:它可能包含空格,可以重新解释为COMMAND
调用的单独参数
b)如果变量set()
确实包含引号,请参见上文。
如果要将某些内容连接到一个要传递给被调用的可执行文件的参数,请使用
。推理:变量可以包含一个参数列表 - 当使用引号时 - 不能正确提取(分号而不是空格)
始终使用VERBATIM
/ add_custom_target()
add_custom_command()
选项
推理:否则跨平台行为未定义,您可能会对引用的字符串感到惊讶。
<强>参考强>