您的困惑的根源可能是 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)工作的原因在CMake's language manual for unquoted arguments中找到:
不带引号的参数内容由连续块中的所有文本组成
允许或转义的字符。转义序列和变量
参考文献被评估。结果值除以相同的
列表划分元素的方式。每个非空元素都被赋予
命令调用作为参数。因此,未引用的论点可能
以零个或多个参数的形式提供给命令调用。
请注意,这与quoted arguments 不同,后者也评估转义序列和变量引用,但不进行列表扩展。这就解释了为什么 (4) 会失败。
现在有趣的问题是为什么(3) 仍然成功。 set 将接受单值和列表值参数。事实上,关闭 ) 或关键字 CACHE 或 PARENT_SCOPE 之前的所有内容都被视为值的一部分。因此,以下两个命令是等价的:
set(MYLIST "a;b;c")
set(MYLIST a;b;c)
在这两种情况下,MYLIST 的值都是a;b;c(不带引号)。
当我们现在将${MYLIST} 扩展为另一个命令时,您可以认为它使用MYLIST 的值执行简单的字符串替换,即a;b;c。然后,生成的命令将通过引用或未引用参数的规则进行扩展。也就是说,以下将起作用:
foreach(LETTER ${MYLIST}) [...]
虽然这不会:
foreach(LETTER "${MYLIST}") [...]