如何在CMake中设置警告级别?


116

如何使用CMake项目(而不是整个解决方案)设置警告级别?应该可以在Visual StudioGCC上使用

我找到了各种选项,但大多数似乎不起作用或与文档不一致。

Answers:


96

更新:此答案早于现代CMake时代。每个理智的CMake用户都应避免摆弄,CMAKE_CXX_FLAGS而应调用该target_compile_options命令。检查mrts的答案,该答案提供了建议的最佳实践。

您可以执行以下操作:

if(MSVC)
  # Force to always compile with W4
  if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
    string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
  else()
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
  endif()
elseif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
  # Update if necessary
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic")
endif()

请注意,新版本的Visual Studio(至少2013年)支持/Wall标志(名为EnableAllWarnings)。它产生的警告比还要多/W4。但是根据我的经验,它会产生太多警告。
亚当·巴杜拉

12
/Wall如果您要遵循警告的“减法”策略(如clang的),则可以使用-Weverything。无需选择要启用的警告,而是启用所有内容,然后选择要禁用的特定警告。
bames53 '16

86

在现代CMake中,以下方法可以很好地工作:

if(MSVC)
  target_compile_options(${TARGET_NAME} PRIVATE /W4 /WX)
else()
  target_compile_options(${TARGET_NAME} PRIVATE -Wall -Wextra -pedantic -Werror)
endif()

我的同事建议了一个替代版本:

target_compile_options(${TARGET_NAME} PRIVATE
  $<$<CXX_COMPILER_ID:MSVC>:/W4 /WX>
  $<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wall -Wextra -pedantic -Werror>
)

替换${TARGET_NAME}为实际的目标名称。-Werror是可选的,它将所有警告变为错误。

或者,add_compile_options(...)如果您想将其应用于@aldo在注释中建议的所有目标,请使用。

此外,一定要了解之间的差异PRIVATEPUBLIC(公共选项将依赖于给定的目标对象继承)。


19
或者只是简单地add_compile_options(...)将其应用于所有目标。
aldo

1
仅供参考,现代CMake不需要在else()或中重复条件endif()
Timmmm

1
@Timmmm感谢您的注意!只是便条,还是您希望我删除条件?
mrts '19

1
@helmesjo不,Timmmm是指4月9日编辑之前存在的CMake代码。您可以查看编辑历史记录以查看已删除的位,这与Timmmm指出的相同。
FeRD

2
@aldo的问题add_compile_options()是,警告将传播到通过添加的目标add_subdirectory()。如果以这种方式包括外部库,则该库的设计具有不同的警告级别,则可能会收到很多警告。
trozen

24

我编写的某些CMake模块包括实验性跨平台警告抑制

sugar_generate_warning_flags(
    target_compile_options
    target_properties
    ENABLE conversion
    TREAT_AS_ERRORS ALL
)

set_target_properties(
    foo
    PROPERTIES
    ${target_properties}
    COMPILE_OPTIONS
    "${target_compile_options}"
)

Xcode的结果:

  • 设置CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSIONXcode属性(又名构建设置 -> 警告 -> 可疑的隐式转换 -> YES
  • 添加编译器标志: -Werror

Makefile gcc和clang:

  • 添加编译器标志:-Wconversion-Werror

视觉工作室:

  • 添加编译器标志:/WX/w14244

链接


1
这是一个可耻的cmake,不提供此功能
Slava

3
好消息。对不起,将其发布在此处,而不是在cmake邮件列表中,但如果没有级别,它将毫无用处,警告太多,无法将其全部明确列出。如果要统一它,一种方法是使用两个单独的cmake_level-统一的警告集(例如,基于clang)和native_level(针对编译器的特定含义)。其中之一可能会缩短到水平。抱歉,如果我没有真正按照谈话内容进行操作,但遇到了问题
Slava 2016年

1
@ void.pointer提出一个有效点。您建议的答案为:我正计划添加此功能”。这并不是说您进行了一些粗略的研究,现在希望其他人为您完成繁重的工作。如果您不希望归因于实现(以及实现进度方面的问题),则需要编辑答案并使自己与过去一年没有取得任何进展的任务分离。
IInspectable

“一年后,仍然没有进展。” -现在这一个有效的观点。一年多过去了,进展。这非常有力地表明该项目被放弃了。如果您想证明我们错了,请向我们展示一些进展。尚未发生,但是您提出的答案仍然表明,该功能即将添加到CMake中。为什么要为将在数年内不可用的功能大惊小怪?那根本没有帮助。显示一些进度,或编辑答案以减少误导。
IInspectable '17

5
您似乎看不懂。如果您建议要实现一项功能,则需要在适当的时候实现该功能。否则,系统会要求您从提议的答案中删除该承诺。您对实现上述功能的承诺为零,因此请勿提出其他要求。我知道这很大。我也了解您可能无能为力。我只是想让您的回答反映出来。
IInspectable '17

6

这是到目前为止我发现的最佳解决方案(包括编译器检查):

if(CMAKE_BUILD_TOOL MATCHES "(msdev|devenv|nmake)")
    add_definitions(/W2)
endif()

这将在Visual Studio中设置警告级别2。我想用-W2它也可以在GCC中使用(未经测试)。

@Williams的更新:应该-Wall用于GCC。


6
GCC的警告标志-Wall可能-Wextragcc.gnu.org/onlinedocs/gcc/Warning-Options.html
Milliams,2010年

1
我使用的清单是-W -Wall -Wextra -pedantic-WextraIIRC -W在GCC的更高版本中进行了替换,但出于兼容性考虑,我将两者都保留了。
Jimmio92 2013年

2
这不是add_definitions的预期目的(“旨在添加预处理器定义”)。这也不只是最佳实践建议。传递给该命令的参数将显示在生成的生成脚本中,这些脚本调用不需要这些参数的工具(例如资源编译器)。
IInspectable

这不是“编译器检查”,而是构建工具检查。
托马斯

3

根据Cmake 3.17.1文档

if (MSVC)
    # warning level 4 and all warnings as errors
    add_compile_options(/W4 /WX)
else()
    # lots of warnings and all warnings as errors
    add_compile_options(-Wall -Wextra -pedantic -Werror)
endif()

GCC和Clang共享这些标志,因此这应涵盖所有3个标志。


不要使用这个。而是使用target_compile_options()。引用最新文档似乎是“正确的”,但这只是为了向后兼容而已。
caoanan

1
@caoanan文档对此没有提及任何向后兼容性。add_compile_options在整个目录范围内,而target_compile_options仅用于单个目标。
6

2
if(MSVC)
    string(REGEX REPLACE "/W[1-3]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
endif()

如果使用target_compile_options-cmake将尝试使用double /W*标志,这将由编译器发出警告。


谢谢你 我天真地add_compile_options用来获取大量/W3被覆盖的警告/W4。CMake没有解决这个基本选项(设置警告级别)的事实令人难以置信。
复活
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.