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

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

本文关键字:设置 编译器 警告 代码 外部 CMake 本机代码      更新时间:2023-10-16

假设我正在为我自己的代码设置一个相当严格的编译器警告级别,但问题是我的代码依赖于一个没有写得太严格的外部库,所以当我包含来自外部库的头文件时,我会收到各种警告。有没有办法为 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但这种方法仅适用于Windows。是否可以在CMake中执行此操作,以便它适用于不同的平台,例如linux和Windows,并保持源代码干净?

我知道我可以添加编译指示警告推送并在main中添加弹出.cpp但是这个 方法仅适用于Windows。

GCC 具有诊断编译指示、MSVC 警告编译指示。只需检查编译器:MSVC 已_MSC_VER,GCC 已__GNUC__预定义。

有没有办法为不同的文件设置不同的警告级别 在CMake?

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


您只想隔离这些(写错的)标头的警告,而不是整个源文件的警告,因此对这些包含使用编译指示是更安全的方法。

不,你不能对CMake做任何事情关于这个问题。您只能依赖一些侵入性的编译器依赖方法,例如push/pop杂注警告。似乎您已经知道如何使用 MSVC 执行此操作,这里是如何使用 GCC 执行此操作的链接。

但是为什么你不能在不修改标题的情况下使用 CMake 做到这一点呢?因为标头不是独立的文件,所以它们被嵌入到 cpp 文件中,然后才被处理。因此,应该设置的是整个单元,而不是标题。一般来说,你不知道哪些单位包括哪些标题。因此,即使您使用的编译器支持每个文件的警告级别,尝试使用此功能也太脆弱了:标头可能会被一些对你的策略一无所知的不同程序员包含在任何其他单元中 - 它太依赖于人类,这是不好的。

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