如何使用CMake为项目(而不是整个解决方案)设置警告级别? 应该在Visual Studio和GCC上工作。
我发现了各种选项,但大多数似乎要么不起作用,要么与文档不一致。
如何使用CMake为项目(而不是整个解决方案)设置警告级别? 应该在Visual Studio和GCC上工作。
我发现了各种选项,但大多数似乎要么不起作用,要么与文档不一致。
在现代CMake中,以下内容运行良好:
if(MSVC)
target_compile_options(${TARGET_NAME} PRIVATE /W4 /WX)
else()
target_compile_options(${TARGET_NAME} PRIVATE -Wall -Wextra -Wpedantic -Werror)
endif()
我的同事建议了另一种版本:
target_compile_options(${TARGET_NAME} PRIVATE
$<$<CXX_COMPILER_ID:MSVC>:/W4 /WX>
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wall -Wextra -Wpedantic -Werror>
)
用实际的目标名称替换${TARGET_NAME}
。 -Werror
是可选的,它将所有警告转换为错误。
或者按照评论中@aldo的建议使用add_compile_options(...)
将其应用于所有目标。
此外,请确保理解PRIVATE
和PUBLIC
之间的区别(公共选项将被依赖于给定目标的目标继承)。
正如@davidfong在评论中指出的那样,自CMake v3.24起,存在CMAKE_COMPILE_WARNING_AS_ERROR
变量,可以将编译警告视为错误。如果它设置在CMakeLists.txt
中,则用户仍然可以使用--compile-no-warning-as-error
cmake
标志关闭它。如果要手动添加警告作为错误,请将/WX
添加到Windows中,将-Werror
添加到其他地方,并将其添加到target_compile_options
中。
add_compile_options(...)
。 - aldoadd_compile_options()
的问题在于,警告会传播到通过add_subdirectory()
添加的目标。如果以这种方式包含外部库,则如果该库是使用不同警告级别设计的,则可能会收到大量警告。 - trozen-Werror
。 -Werror
对于开发来说非常好,但最终用户可能会使用带有新警告的更新编译器。您不希望破坏他的进程。 - Jérôme Pouiller更新:此回答早于现代CMake时代。每个明智的CMake用户都应避免直接操作CMAKE_CXX_FLAGS
,而应调用target_compile_options
命令。请查看mrts' answer,其中提供了推荐的最佳实践。
您可以执行类似以下内容的操作:
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()
/Wall
标志(名为EnableAllWarnings
)。它产生的警告甚至比/W4
还要多。然而,根据我的经验,它会产生过多的警告。 - Adam Badura/Wall
是可以使用的。不需要选择要启用的警告信息,而是先启用所有内容,然后再选择要禁用的特定警告信息。 - bames53sugar_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_CONVERSION
Xcode 属性(也称为 构建设置 -> 警告 -> 可疑的隐式转换 -> 是)-Werror
Makefile gcc 和 clang:
-Wconversion
,-Werror
Visual Studio:
/WX
,/w14244
if (MSVC)
# warning level 4
add_compile_options(/W4)
else()
# additional warnings
add_compile_options(-Wall -Wextra -Wpedantic)
endif()
add_compile_options
是适用于整个目录的,而target_compile_options
仅适用于单个目标。 - Signal目前我找到的最佳解决方案(包括编译器检查)如下:
if(CMAKE_BUILD_TOOL MATCHES "(msdev|devenv|nmake)")
add_definitions(/W2)
endif()
GCC的等价选项是-Wall
(未经测试)。
-Wall
,可能还有 -Wextra
,详情请参见 http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html。 - Milliamsif(MSVC)
string(REGEX REPLACE "/W[1-3]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
endif()
target_compile_options
,cmake将尝试使用双重/W*
标志,这会导致编译器发出警告。add_compile_options
,结果得到了大量警告,提示/W3
被/W4
覆盖。CMake没有解决这个基本选项(设置警告级别)的事实令人难以置信。 - Resurrection# CMakeLists.txt
project(my_project)
add_executable(my_target source_file.cpp)
target_compile_options(my_target PRIVATE "${MY_PROJECT_ELEVATED_WARNING_FLAGS}")
有许多设置这些变量的方法,例如CMakeCache.txt、工具链文件以及通过CMAKE_PROJECT_INCLUDE_BEFORE
。但最简单的方式是在配置期间使用命令行进行设置,对于GCC来说。
cmake -DMY_PROJECT_ELEVATED_WARNING_FLAGS:STRING="-Wall;-Wextra;-Wpedantic;-Werror" <path-to-project>
适用于MSVC
cmake -DMY_PROJECT_ELEVATED_WARNING_FLAGS:STRING="/W4;/WX" <path-to-project>