CMake关于生成器表达式的文档非常清楚地指出,“一个常见的错误是试图通过缩进将生成器表达式拆分为多行”。下面是他们给予的示例:
# WRONG: New lines and spaces all treated as argument separators, so the
# generator expression is split and not recognized correctly.
target_compile_definitions(tgt PRIVATE
$<$<AND:
$<CXX_COMPILER_ID:GNU>,
$<VERSION_GREATER_EQUAL:$<CXX_COMPILER_VERSION>,5>
>:HAVE_5_OR_LATER>
)
我的经验是,使用多行缩进的效果和我所希望的完全一样。例如,下面的代码产生了我在使用空格和缩进时所期望的结果:
target_compile_options(common_interface INTERFACE
$<$<CXX_COMPILER_ID:MSVC>:
/W4 # Turn on warnings
/WX # Turn warnings into errors
>
$<$<CXX_COMPILER_ID:GNU,Clang,AppleClang>:
-Wall # Turn on warnings
-Wextra # Turn on warnings
-Werror # Turn warnings into errors
>
)
根据我对CMake文档的理解,这里的每一行都将作为一个单独的编译选项添加(例如$<$<CXX_COMPILER_ID:MSVC>:
),但显然不是这样,因为生成的构建文件显示标志正确通过。
我的问题是:
1.我遗漏了什么?问题是否仅与某些类型的表达式(例如,逻辑运算符)有关?行为是否已更改,文档是否已过期?或者文档是否需要增强以阐明限制和预期行为?
1.在某些情况下,继续使用空格和缩进是否安全?
我怀疑条件表达式的结果true_string
(或$<IF:condition,true_string,false_string>
中的false_string
)可能包含空格,但表达式的其他参数不能被破坏。
1条答案
按热度按时间6yt4nkrj1#
Tsyvarev对这个问题的评论是关于金钱的,但我会给予一个更正式的回答,作为CMake的维护者之一和您链接到的生成器表达式文档的作者。TLDR版本是“文档描述了您可以依赖的内容。不要依赖文档之外的实现细节,这些细节可能会发生变化。"
文档中明确指出了在哪些地方需要使用引用来确保健壮的行为。将genex拆分成多行或空格从来没有得到过官方的支持。有时候它看起来可能会起作用,但那是巧合,而不是设计。仅仅因为你发现了一个在某些CMake版本中碰巧起作用的案例,你不应该认为这是受支持的行为。特别是当文档现在明确地指出这是不受支持的行为时,我们不能保证这种不受支持的行为在将来的版本中会继续工作。
为了明确起见,您的问题的直接答案是:
1.我遗漏了什么?问题是否仅与某些类型的表达式(例如,逻辑运算符)有关?行为是否已更改,文档是否已过期?或者文档是否需要增强以阐明限制和预期行为?
文档是最新的,我不知道如何使事情比现有文档已经说的更清楚。你问的事情直接违背了文档。你问的方面不是我们打算记录的事情,因为它们不是特别打算被支持的行为!此外,CMake在这方面的行为可能在不同的版本中发生了变化,但它从来没有被承诺是稳定的,因为它从来不是CMake的文档化API的一部分。
1.在某些情况下,继续使用空格和缩进是否安全?
不,当前的文档应该清楚地说明什么是安全的,什么是不安全的。如果你问与文档相矛盾的东西是否安全,那么,希望我的回答仍然是“不”。)
注脚
人们无法引用他们的生成器表达式已经是最经常报告的问题之一(或者更准确地说,报告问题的原因)在CMake论坛和问题跟踪器中。它不停地咬人一遍又一遍,我写了一篇关于一般引用的Quoting In CMake博客文章,还在CMake官方文档的生成器表达式手册中添加了"空格和引用“部分(更新出现在CMake 3.24中)。