如何在CMake中为本机代码和外部代码设置不同的编译器警告级别

How to set different compiler warning levels for native code and external code in CMake

假设我正在为我自己的代码设置一个相当严格的编译器警告级别,但问题是我的代码依赖于一个编写得不太严格的外部库,所以当我从外部包含头文件时图书馆我收到各种各样的警告。有没有办法可以在 CMake 中为不同的文件设置不同的警告级别?

这是一个显示情况的例子,假设我有 main.cpp

#include "external.h"

int main(){
  // some code
}

和对应的CMakeLists.txt

cmake_minimum_required(VERSION 2.8)
project(Test)

set(PROJECT_SRCS
${PROJECT_SOURCE_DIR}/main.cpp
)

if(MSVC)
  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)
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -W -Wall -Werror -Wshadow")
endif()

include_directories(${EXTERNAL_INC})

add_executable(Test ${PROJECT_SRCS})

target_link_libraries(Test ${EXTERNAL_LIB})

假设 "external.h" 导致 -Wshadow 警告,我可以去掉 -Wshadow 但这也意味着我的本机代码不会捕获任何 -Wshadow 警告。我知道我可以在 main.cpp 中添加 pragma warning push 和 pop,但这种方法只适用于 windows。是否可以在 CMake 中执行此操作,以便它适用于 linux 和 windows 等不同平台并保持源代码清洁?

I know I can add pragma warning push and pop in main.cpp but this approach will only work for windows.

GCC 有 diagnostic pragmas, MSVC warning pragmas。只需检查编译器:MSVC 有 _MSC_VER,GCC 有 __GNUC__ 预定义。

Is there a way I can set different warning levels for different files in CMake?

set_source_files_properties 允许您将编译标志添加到特定的源文件以覆盖以前的选项。


您只想隔离这些(写得不好)headers 的警告,而不是整个源文件的警告,因此对这些包含使用 pragma 是更安全的方法。

不,关于这个问题,您不能用 CMake 做任何事情。您只能依赖一些侵入性的 compiler-dependant 方法,例如 push/pop pragma 警告。看来您已经知道如何使用 MSVC 做到这一点,here 是 link 如何使用 GCC 做到这一点。

但是为什么不修改 headers 就不能用 CMake 来做呢?因为 headers 不是独立文件,所以它们被嵌入到 cpp 文件中,然后才被处理。所以应该是整个单位 set-up,而不是 header。通常你不知道什么单位包括什么 headers。因此,即使您使用的编译器支持每个文件的警告级别,尝试使用此功能也太脆弱了:header 稍后可能会被一些对您的策略一无所知的不同程序员包含在任何其他单元中——这取决于对一个人来说太多了,这是不好的。

创建 TurnOffWarnings/TurnOnWarnings header 文件并强制组织中的策略用尖括号括起所有包含在这些自定义 header 之间要容易得多。