cmake:何时引用variables?
我第一次写CMakemacros,而且我很难理解variables是如何工作的。 最具体地说,$ {a}似乎与“$ {a}”有不同的含义。
例如这里:
将一个列表传递给一个cmakemacros
我不明白什么时候应该加引号,什么是更大的基本原则。
CMake的两个原则你必须牢记:
- CMake是一种脚本语言,参数在variables扩展后被评估
- CMake区分普通string和列表variables(带有分号分隔符的string)
例子
- 用
message("${_my_text}")
set(_my_text "ABC")
会给ABC
- 用
message("${_my_list}")
set(_my_list ABC)
会给A;B;C
- 用
message("${_my_list}")
set(_my_list "A" "B" "C")
将给A;B;C
- 用
message(${_my_list})
set(_my_list "A" "B" "C")
会给ABC
一些经验法则
你应该考虑一些经验法则:
-
a)当你的variables包含文本 – 尤其是一个可能包含分号的文本 – 你应该添加引号。
推理 :分号是CMake中列表元素的分隔符。 所以把引号放在应该是一个文本的地方(它在任何地方都能正常工作,而且对于我个人而言CMake语法突出显得更好)
编辑:谢谢@schieferstapel暗示
b)更确切地说:一个已经有引号的空格的variables内容会保留这些引号(想象它变成了variables内容的一部分)。 除了
if()
调用,其中CMake在variables扩展之后重新解释非引用variables的内容(另请参阅经验法则#3和策略CMP0054:仅限于此 ),此函数在任何地方都可以正常工作(正常或用户定义的函数参数) 解释if()
参数作为variables或关键字时,不加引号 )例子:
- 用
message(${_my_text})
set(_my_text "ABC")
也会给ABC
-
if given arguments: "A" "B" "C" "STREQUAL" "A;B;C" Unknown arguments specified
if (${_my_text} STREQUAL "A;B;C")
将给出if (${_my_text} STREQUAL "A;B;C")
set(_my_text "A;B;C")
if given arguments: "A" "B" "C" "STREQUAL" "A;B;C" Unknown arguments specified
- 用
-
如果你的variables包含一个列表,你通常不会添加引号。
推理 :如果你给一个CMake命令一个文件列表,它通常期望一个string列表,而不是一个包含列表的string。 你可以看到,例如在接受
ITEMS
或LISTS
的foreach()
命令中的差异。 -
if()
语句是一个特殊的情况下,你通常甚至不把大括号。推理 :一个string可以在扩展之后再次评估为variables名称。 为了防止这种情况,build议您只为要比较其内容的variables命名(例如
if (_my_text STREQUAL "ABC")
)。
COMMAND
例子
- 使用
COMMAND "${CMAKE_COMMAND}" -E echo "${_my_text}"
set(_my_text "ABC")
- 在VS / Windows上调用
cmake.exe -E echo "ABC"
- 在GCC / Ubuntu上调用
cmake -E echo A\ B\ C
- 给
ABC
- 在VS / Windows上调用
- 使用
COMMAND "${CMAKE_COMMAND}" -E echo "${_my_text}" VERBATIM
set(_my_text "ABC")
COMMAND "${CMAKE_COMMAND}" -E echo "${_my_text}" VERBATIM
会- 在VS / Windows上调用
cmake.exe -E echo "ABC"
- 在GCC / Ubuntu上调用
cmake -E echo "ABC"
- 给
ABC
- 在VS / Windows上调用
- 用
COMMAND "${CMAKE_COMMAND}" -E echo "${_my_list}"
set(_my_list ABC)
会- 调用
cmake.exe -E echo A;B;C
- 给
A
,B: command not found
,C: command not found
- 调用
-
set(_my_list ABC)
COMMAND "${CMAKE_COMMAND}" -E echo "${_my_list}" VERBATIM
会- 调用
cmake.exe -E echo "A;B;C"
- 给
A;B;C
- 调用
- 使用
COMMAND "${CMAKE_COMMAND}" -E echo "${_my_list}" VERBATIM
set(_my_list "A" "B" "C")
COMMAND "${CMAKE_COMMAND}" -E echo "${_my_list}" VERBATIM
会- 调用
cmake.exe -E echo "A;B;C"
- 给
A;B;C
- 调用
- 使用
COMMAND "${CMAKE_COMMAND}" -E echo ${_my_list} VERBATIM
set(_my_list "A" "B" "C")
COMMAND "${CMAKE_COMMAND}" -E echo ${_my_list} VERBATIM
会- 调用
cmake.exe -E echo ABC
- 给
ABC
- 调用
- 用
COMMAND "${CMAKE_COMMAND}" -E echo ${_my_list} VERBATIM
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
调用中使用variables时,应该考虑一些经验法则:
-
a)为包含文件path的参数使用引号(如包含可执行文件本身的第一个参数)。
推理 :它可以包含空格,并可以重新解释为
COMMAND
调用的单独参数b)参见上面,如果variables
set()
确实包含引号,也可以使用。 -
仅当您想要将某些参数连接成单个parameter passing给所调用的可执行文件时才使用引号。
推理 :一个variables可以包含一个参数列表 – 当使用引号时 – 不会被正确提取(分号代替空格)
-
总是添加
VERBATIM
选项add_custom_target()
/add_custom_command()
推理 :否则,跨平台的行为是不确定的,你可以得到惊喜引用的string。
参考
- CMake:$ {}和“$ {}”之间的区别
- 什么是CMake语法来设置和使用variables?
- 在一个string列表中循环
- CMake与STREQUAL的空string比较失败