CMake:将条件编译标志添加到Visual Studio项目

3

Visual Studio允许选择cl编译器或clang-cl编译器来构建项目——这些被称为工具集。这两个编译器具有不同的标志集,尤其是禁用警告的不同标志。其中一个编译器的标志会在另一个编译器上产生错误。

这个问题可以通过根据使用的工具集有条件地定义编译器标志来同时解决Visual Studio中的两个编译器。相关的官方文档在此处

我使用CMake生成Visual Studio项目。 我该如何让CMake为生成的Visual Studio项目添加这样的有条件标志?

2个回答

3

本质上,这是对早期问题 这里 的一种更现代的方法,您可以使用if语句检查编译器类型,并根据其设置编译标志:

if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
    # Disable a Clang warning type.
    target_compile_options(MyLib PRIVATE -Wno-unused-variable)
elseif(MSVC)
    # Disable a MSVC warning type.
    target_compile_options(MyLib PRIVATE /wd4101)
endif()

要将此放入单个表达式中,您可以使用 CMake 生成器表达式(在 CMake 构建系统生成阶段评估):

target_compile_options(MyLib PRIVATE 
    "$<IF:$<STREQUAL:${CMAKE_CXX_COMPILER_ID},Clang>,-Wno-unused-variable,/wd4101>"
)

以下是clang警告类型的列表,供参考。


我已经有这些特定于编译器的开关了。问题与此有点不同:在 Visual Studio 项目设置中切换时,相同生成的 Visual Studio 项目必须能够同时适用于 cl 和 clang-cl,而无需通过 CMake 重新生成项目。 - kaba
1
如果您正在切换编译器/工具集,则确实应该重新运行CMake。 - Kevin
我明白了。如果MSBuild条件无法正常工作,我可以处理它。 - kaba
@kaba 我还添加了一个生成器表达式的方法,这可能更接近你想要实现的目标。 - Kevin
1
我认为重新运行CMake比依赖特殊的MSBuild功能更好。 - kaba

3

你可以使用 CMAKE_CXX_COMPILER_IDCMAKE_CXX_SIMULATE_ID 与你喜欢的编译器处理方式(if-else 或生成器表达式)一起使用。

-T ClangCL 的输出结果(Visual Studio 2019):

message(STATUS ${CMAKE_CXX_COMPILER_ID}) // Clang
message(STATUS ${CMAKE_CXX_SIMULATE_ID}) // MSVC

没有工具包的输出(Visual Studio 2019):

message(STATUS ${CMAKE_CXX_COMPILER_ID}) // MSVC
message(STATUS ${CMAKE_CXX_SIMULATE_ID}) // <empty>

“CMAKE_CXX_SIMULATE_ID”非常有用,我之前并不知道它的存在。我使用它来为clang-cl分支设置。一个奇怪的细节是,“if (NOT ("${CMAKE_CXX_SIMULATE_ID}" STREQUAL "MSVC"))”按预期工作,但“if (NOT (${CMAKE_CXX_SIMULATE_ID} STREQUAL "MSVC"))”则不行(它总是为真)。 - kaba
2
@kaba 当 CMAKE_CXX_SIMULATE_ID 未定义(为空)时会出现这种情况。第二个条件应该产生一个错误。只需使用 if (NOT (CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC")) 即可。 - local-ninja

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接