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

Wer*_*ght 104 cmake warning-level

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

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

mlo*_*kot 87

更新:这个答案早于现代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()
Run Code Online (Sandbox Code Playgroud)

  • 如果你想按照'减法'策略进行警告,就像clang的'-Weverything`一样,`/ Wall`是可用的.您可以启用所有内容,然后选择要禁用的特定警告,而不是选择要启用的警告. (12认同)

mrt*_*rts 58

在现代CMake中,以下效果很好:

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

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

  • 或者只是`add_compile_options(...)`如果你想将它应用于所有目标. (12认同)
  • 请不要无条件添加`-Werror`。`-Werror` 对于开发来说非常有用,但最终用户可能会使用带有新警告的更新版本的编译器。你不想破坏他的流程。 (6认同)
  • 不是迂腐,但为了统一起见,“迂腐”标志应该称为“-Wpedantic”。 (5认同)
  • @aldo `add_compile_options()` 的问题是警告将传播到通过 `add_subdirectory()` 添加的目标。如果您以这种方式包含外部库,并且该库设计有不同的警告级别,您可能会收到很多警告。 (3认同)
  • 仅供参考,现代 CMake 不需要在 `else()` 或 `endif()` 中重复条件。 (2认同)

小智 23

我编写的一些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}"
)
Run Code Online (Sandbox Code Playgroud)

Xcode的结果:

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

Makefile gcc和clang:

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

视觉工作室:

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

链接

  • 你似乎不明白.如果您建议您要实现某项功能,则需要在适当的时候实施该功能.如果做不到这一点,您将被要求从您提出的答案中删除该承诺.您没有表现出实施该功能的承诺,因此请勿另行声明.我知道它很大.我也明白你可能无法将其拉下来.我只是要求你让你的答案反映出来. (5认同)
  • 好消息.很抱歉在这里发布而不是在cmake邮件列表中,但没有级别这将是无用的,有太多的警告,明确地列出它们.如果你想统一它,那么一种方法就是两个单独的cmake_level - 基于clang的统一警告集,以及具有编译器特定含义的native_level.其中一个可能缩短到水平.对不起,如果我没有真正关注对话并出错了 (3认同)
  • 遗憾的是 cmake 不提供此功能 (2认同)

Jay*_*Jay 12

根据Cmake 3.21.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()
Run Code Online (Sandbox Code Playgroud)

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

  • @caoanan 该文档没有提到任何向后兼容性。`add_compile_options` 是目录范围的,而 `ta​​rget_compile_options` 仅适用于单个目标。 (3认同)

Wer*_*ght 7

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

if(CMAKE_BUILD_TOOL MATCHES "(msdev|devenv|nmake)")
    add_definitions(/W2)
endif()
Run Code Online (Sandbox Code Playgroud)

这将在Visual Studio中设置警告级别2.我认为-W2它也适用于GCC(未经测试).

来自@Williams的更新:应该是-WallGCC.

  • GCC的警告标志是`-Wall`,也许是`-Wextra`,详见http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html (6认同)
  • 根据http://stackoverflow.com/a/14234262/474034,这是一个坏主意. (6认同)
  • 这不是[add_definitions](https://cmake.org/cmake/help/latest/command/add_definitions.html)的预期目的(*“旨在添加预处理程序定义” *)。这也不只是最佳实践建议。传递给该命令的参数将显示在生成的生成脚本中,这些脚本调用不需要这些参数的工具(例如资源编译器)。 (2认同)
  • 这不是“编译器检查”,而是构建工具检查。 (2认同)