CMake在生成Makefile项目时似乎会附加一些默认的编译器标志,例如-Wall
、-Wextra
等等。其中一个默认标志是-Wsign-conversion
,我想从列表中删除它。可以通过添加抑制标志-Wno-sign-conversion
来实现。
target_compile_options(myTarget PRIVATE "-Wno-sign-conversion")
没有任何效果。采用“现代化的CMake”应该怎么做呢?
CMake在生成Makefile项目时似乎会附加一些默认的编译器标志,例如-Wall
、-Wextra
等等。其中一个默认标志是-Wsign-conversion
,我想从列表中删除它。可以通过添加抑制标志-Wno-sign-conversion
来实现。
target_compile_options(myTarget PRIVATE "-Wno-sign-conversion")
没有任何效果。采用“现代化的CMake”应该怎么做呢?
如果您不想查询编译器的ID /名称和/或版本(很快会变得混乱),则可以使用CheckCCompilerFlag(或CheckCXXCompilerFlag)。这里的技巧是不要检查警告禁用标志,而是检查警告本身。例如:
include(CheckCCompilerFlag)
check_c_compiler_flag(-Wsign-conversion HAVE_SIGN_CONVERSION)
if (HAVE_SIGN_CONVERSION)
target_compile_options(target_name PRIVATE -Wno-sign-conversion)
endif (HAVE_SIGN_CONVERSION)
需要注意的是,建议避免直接设置CMAKE_C_FLAGS
和/或CMAKE_CXX_FLAGS
。如有可能,请使用target_compile_options
仅为需要这样做的目标禁用警告。如果要全局禁用它,请使用add_compile_options
。
请注意,如果您的构建脚本的其他部分直接设置这些标志,您仍可能会收到警告(例如,如果某人执行set(CMAKE_CXX_FLAGS"${CMAKE_CXX_FLAGS} -Wsign-conversion")
)。这也是避免直接设置CMAKE_C_FLAGS
和CMAKE_CXX_FLAGS
的原因之一,因为它变得极其难以控制发生了什么。
选项添加的顺序也很重要。以下最小示例说明了这一点(假设example.cpp
包含将触发-Wsign-conversion
警告的代码):
project(example)
add_executable(example example.cpp)
target_compile_options(example PRIVATE -Wsign-conversion)
target_compile_options(example PRIVATE -Wno-sign-conversion)
这将抑制警告。编译器被这样调用:/usr/bin/c++ -Wsign-conversion -Wno-sign-conversion
我们可以交换这两个target_compile_options
调用:
project(example)
add_executable(example example.cpp)
target_compile_options(example PRIVATE -Wno-sign-conversion)
target_compile_options(example PRIVATE -Wsign-conversion)
/usr/bin/c++ -Wno-sign-conversion -Wsign-conversion
这会触发警告。HAVE_SIGN_CONVERSION == true
并且您添加了禁用标志,那么Makefile中将会出现以下类似的内容:... -Wall -Wextra ... -Wsign-conversion -Wno-sign-conversion
。在GCC中,如果已经设置了相应的“正向”标志,添加任何警告标志的-no
版本似乎是无效的。 - Ignorant-Wsign-conversion -Wno-sign-conversion
。-Wconversion
也会启用-Wsign-conversion
,你能否在禁用-Wsign-conversion
后检查一下是否启用了该标志? - icebp我不太确定这是否是“现代CMake”,但我使用类似于此来设置gcc标志,直接在cmake_minimum_required变量之后。
set (CMAKE_CXX_STANDARD 17)
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-sign-conversion")
endif()