是否有一种稳健的方法可以在 CMake 中设置编译器标志,覆盖/替换另一个(如果存在)?

问题描述 投票:0回答:1

问题:我有一个全局的CMakeLists.txt,它设置了一堆全局编译选项(示例将使用MSVC,但它不是唯一的,只是cl.exe在遇到标志覆盖时会生成警告),如

add_compile_options(... /W3 ...)
。当我想为该项目子目录中的某个目标设置
target_compile_options(targetA PRIVATE /W4)
时。然而,这会产生恼人的警告
D9025: overriding '/W3' with '/W4'
。与默认设置或顶级 cmake 文件中设置的其他选项相同。

是否有一些可靠的方法来添加编译选项来替换另一个(如果存在)?我只能说一个非常冗长和丑陋的

get_target_property
,然后是
string(REGEX REPLACE...
(这可能很难获得正确的正则表达式并且不匹配任何额外的东西,我也不确定这是否会包括编译选项的所有源可能来自 CMAKE_CXX_FLAGS 和 co) 以及
target_compile_options
。我想要一些可以轻松添加到想要覆盖“全局”选项的每个目标的东西(无论它们来自顶级 cmake、默认标志还是其他来源)。

c++ cmake compiler-warnings
1个回答
0
投票

我认为答案是否定的...源文件的编译选项的最终列表是从一堆不同的地方编译的(非详尽列表):

更复杂的是,其中大多数都支持生成器表达式,并且

CMake 对目标的“最终”编译选项列表进行选项重复数据删除。编译器对于如何在各种类别的冲突选项中优先选择选项也有各种不同的行为(尽管通常采用最右边的选项。例如MSVC)。 所以问题的一部分是——你知道在哪个级别你想要摆脱某些东西并用其他东西取代它?如果事情非常明确,您可能很幸运能够按照您的建议进行操作,只需进行一些

string

/ list 操作即可删除某些内容并替换它。否则,你可能会陷入一些不幸,无法(不想)接触比你关心的“更高”级别定义的东西,因为它会对其他较低级别产生影响。 在您在目录级别设置默认值并希望在目标级别覆盖的特定情况下,您可以尝试一种方法,将目录级别选项表示为从自定义目标属性读取的生成器表达式,并使用一些如果未提供则使用默认值。也许类似于

add_compile_options("$<$<STREQUAL:$<TARGET_PROPERTY:MY_WARNING_LEVEL_OPTION_PROPERTY>,"">:${DEFAULT_WARNING_LEVEL},$<TARGET_PROPERTY:MY_WARNING_LEVEL_OPTION_PROPERTY>>")

的方式,然后使用

set_target_properties
 设置每个目标“覆盖”。

© www.soinside.com 2019 - 2024. All rights reserved.