如何使用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
是可选的,它将所有警告变成错误。
或者add_compile_options(...)
,如果您想按照@aldo 在评论中的建议将其应用于所有目标,请使用。
此外,请务必了解和之间的区别PRIVATE
(PUBLIC
公共选项将由依赖于给定目标的目标继承)。
更新:这个答案早于现代 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()
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_CONVERSION
Xcode 属性(又名构建设置->警告->可疑隐式转换-> YES)-Werror
Makefile gcc 和 clang:
-Wconversion
,-Werror
视觉工作室:
/WX
,/w14244
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 个。
这是迄今为止我找到的最佳解决方案(包括编译器检查):
if(CMAKE_BUILD_TOOL MATCHES "(msdev|devenv|nmake)")
add_definitions(/W2)
endif()
GCC 等效项是-Wall
(未经测试)。
if(MSVC)
string(REGEX REPLACE "/W[1-3]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
endif()
如果您使用target_compile_options
- cmake 将尝试使用双重/W*
标志,这将由编译器发出警告。
如何使用 CMake 为项目(不是整个解决方案)设置警告级别?
(我认为这意味着一个 CMake目标,而不是一个 CMake项目。)
我找到了各种选项,但大多数似乎要么不起作用,要么与文档不一致。
Kitware 的 API 可能会阻止您使构建系统变得脆弱和容易出错。这个问题的其他答案所鼓励的特殊情况至少违反了现代 CMake 构建系统的两个重要原则......
首先,不要在 CMakeLists.txt 文件中指定特定于工具链的详细信息。它使构建系统变得脆弱。例如,如果工具链的未来版本中出现新警告,编译器将发出错误,您的用户可能需要破解您的项目才能构建目标。
相反,编写与工具链无关的 CMakeLists.txt 文件并保留用户在他们认为合适时进行自定义的能力。理想情况下,您的项目应该使用 vanilla 工具链配置在任何地方构建 - 即使默认情况下不会启用您首选的警告。
其次,如果您打算将二进制文件链接在一起,标志应该是一致的。这降低了可能导致程序格式错误的不兼容风险。但是,警告标志不太可能影响代码生成,因此在链接在一起的目标之间改变这些可能是安全的。
所以...如果您希望为每个工具链指定标志,并且如果您绝对必须为不同的目标使用不同的标志,请使用自定义变量:
# 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、工具链文件和 via 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>