List 在字符串列表上循环
我想循环一下以字符串形式给出的项目列表。根据CMake的要求,项目之间用分号分隔。以下List 在字符串列表上循环,list,foreach,cmake,List,Foreach,Cmake,我想循环一下以字符串形式给出的项目列表。根据CMake的要求,项目之间用分号分隔。以下 cmake_minimum_required(VERSION 2.8) FOREACH(LETTER "a;b;c") MESSAGE("<<${LETTER}>>") ENDFOREACH() 这是循环列表的推荐方法还是有更优雅的解决方案?您困惑的根源可能是CMake对带引号字符串的特殊解释 例如,以下命令可以正确地迭代字符串列表: (1) foreach(LETTER a
cmake_minimum_required(VERSION 2.8)
FOREACH(LETTER "a;b;c")
MESSAGE("<<${LETTER}>>")
ENDFOREACH()
这是循环列表的推荐方法还是有更优雅的解决方案?您困惑的根源可能是CMake对带引号字符串的特殊解释 例如,以下命令可以正确地迭代字符串列表:
(1) foreach(LETTER a b c) [...]
(2) foreach(LETTER a;b;c) [...]
(3) set(MYLIST "a;b;c")
foreach(LETTER ${MYLIST}) [...]
唯一不起作用的情况是
(4) foreach(LETTER "a;b;c") [...]
(1)
和(2)
工作的原因在于:
无引号的参数内容由连续块中的所有文本组成
允许的或转义的字符。逃逸序列和变量
对参考文献进行评估。结果值被除以相同的值
方式列表分为多个元素。每个非空元素都被赋予
命令调用作为参数。因此,未引用的论点可能
作为零个或多个参数提供给命令调用
注意,这不同于,后者也计算转义序列和变量引用,但不进行列表扩展。这解释了(4)
失败的原因
现在有趣的问题是为什么(3)
仍然成功。将同时接受单值和列表值参数。事实上,在关闭)
之前的所有内容或缓存
或父范围
中的一个关键字都被视为该值的一部分。因此,以下两个命令是等效的:
set(MYLIST "a;b;c")
set(MYLIST a;b;c)
在这两种情况下,MYLIST
的值都是a;Bc
(不带引号)
当我们现在将${MYLIST}
扩展到另一个命令中时,您可以想象它使用MYLIST
的值执行简单的字符串替换,即a;Bc
。然后,生成的命令将通过带引号或不带引号的参数规则进行扩展。也就是说,以下措施将起作用:
foreach(LETTER ${MYLIST}) [...]
但这不会:
foreach(LETTER "${MYLIST}") [...]
首先,考虑如果在<代码>前缀调用中键入所有值,如<代码>前缀(n 1 2 3)< /代码>,或者如果您想扩展一个变量,如<代码>前缀(n${MyAuthNoMyListList})
虽然接受的答案在行上展开变量,使代码注入成为可能(如果变量设置在脚本之外),但在大多数情况下仍然可以使用 但对于安全循环(不展开变量),请尝试以下操作:# My dummy data.
set (_my_list "A B C")
string (REPLACE " " ";" _my_list "${_my_list}")
# Actual looping.
foreach (current IN LISTS _my_list)
# All done! do something with ${current}, for example:
if (NOT current IN_LIST _my_other_list)
message(FATAL_ERROR "_my_list has ${current} but _my_other_list does not!!")
endif()
endforeach()
# My dummy data.
set (_my_list "A B C")
string (REPLACE " " ";" _my_list "${_my_list}")
# Actual looping.
foreach (current IN LISTS _my_list)
# All done! do something with ${current}, for example:
if (NOT current IN_LIST _my_other_list)
message(FATAL_ERROR "_my_list has ${current} but _my_other_list does not!!")
endif()
endforeach()