如何在CMakeLists.txt文件的第三方库头文件中禁止Clang警告?

时间:2019-06-21 16:16:11

标签: c++ cmake clang suppress-warnings

我目前正在尝试使用Visual Studio 2019的新CMake功能(特别是将Clang和Ninja与CMake和VS2019结合使用)使用多个编译器(包括Clang,MSVC和GCC)的项目。< / p>

我正在使用CMake将项目配置为“与编译器无关”,因此,我不需要通过预处理程序指令或{来编辑代码本身即可处理不同的编译器 {1}}指令。

此项目需要配置为具有较高的警告级别(MSVC为#pragma,Clang为/W4-Wall-Wextra),并且必须处理警告作为错误。

在配置项目的MSVC部分时,我没有任何问题。其中许多设置都具有“合理”的默认设置,可以像我期望的那样“正常工作”。但是当涉及到Clang时,我遇到了一个问题:

我似乎无法禁用第三方库头文件的警告。我目前正在使用Dear ImguiSFML库。由于Dear Imgui尚未预编译,因此我只需在-Wpedantic文件中执行以下操作即可将其包括在内:

CMakeLists.txt

我使用的是SFML的静态链接版本,因此我将其包括在内:

include_directories(
    ${CMAKE_CURRENT_SOURCE_DIR}/libs/imgui
)

遗憾的是,SFML当前未遵循当前CMake添加库的标准方法,因此使用CMake或通过CMake配置它有点奇怪。

现在,在将库包含在我的项目中时,上述方法工作得很好(但是我可能需要更改某些内容,因此已将其包含在文章中)。当我尝试在使用Clang时将警告和错误警告配置强加给他们时,问题就来了。

这是我的# Find SFML and link statically to it. # Note: We need to set the SFML_DIR variable manually. set(SFML_STATIC_LIBRARIES TRUE) set(SFML_DIR "${CMAKE_CURRENT_SOURCE_DIR}/libs/SFML-2.5.1/lib/cmake/SFML") find_package(SFML 2.5.1 COMPONENTS system audio window graphics REQUIRED) target_link_libraries(${PROJECT_NAME} PRIVATE sfml-system sfml-audio sfml-window sfml-graphics ) 文件中处理Clang和我的C ++配置的部分:

CMakeLists.txt

使用上述配置会在Dear Imgui的源文件中导致数百个警告/错误(由于使用了“老式” C ++ / C风格的代码),以及在SFML自己的源代码中出现了一堆警告/错误文件和头文件。

在解决以下解决方案之前,我一直在寻找解决该问题的方法,将近一个星期(该解决方案并不完全有效,稍后再介绍):

# Set project to use C++ 17 standard.
set_target_properties(
    ${PROJECT_NAME}
    PROPERTIES
    CXX_STANDARD 17
    CXX_STANDARD_REQUIRED ON
)


target_compile_options(${PROJECT_NAME} PRIVATE
    # All warnings, warnings as errors, be pedantic.
    -Wall
    -Wextra
    -Werror
    -Wpedantic

    # Disable warnings about C++98 incompatibility. We're using C++17 features...
    -Wno-c++98-compat
    -Wno-c++98-compat-pedantic
)

我首先set(LIBS_FOLDER "${CMAKE_CURRENT_SOURCE_DIR}/libs") set(IMGUI_FOLDER "${LIBS_FOLDER}/imgui") set(SFML_FOLDER "${LIBS_FOLDER}/SFML-2.5.1/include/SFML") file(GLOB LIBRARY_FILES # Dear-imgui "${IMGUI_FOLDER}/*.cpp" "${IMGUI_FOLDER}/misc/freetype/*.cpp" "${IMGUI_FOLDER}/misc/fonts/*.cpp" "${IMGUI_FOLDER}/misc/cpp/*.cpp" # SFML "${SFML_FOLDER}/Audio/*.cpp" "${SFML_FOLDER}/Graphics/*.cpp" "${SFML_FOLDER}/Network/*.cpp" "${SFML_FOLDER}/System/*.cpp" "${SFML_FOLDER}/Window/*.cpp" ) set_source_files_properties( ${LIBRARY_FILES} PROPERTIES COMPILE_FLAGS "-Wno-everything" ) -导入库源文件(注意:我知道GLOB通常被人鄙视,但是我觉得将其与第三方库文件一起使用是可以的因为它们无论如何都不会改变)。然后,我将它们传递给GLOB函数以应用set_source_files_properties标志,该标志似乎可以正确地抑制这些文件中的所有错误和警告。

一切似乎都可以正常工作,除了一条警告,如果没有在我的代码中使用-Wno-everything指令,我似乎无法禁用它(我想避免)。编译包含SFML标头的空#pragma函数时,会收到有关其main文件的警告(无法将其传递给.hpp函数)。

此:

set_source_files_properties

导致以下警告/错误:

#include <SFML/Graphics.hpp>

int main()
{
}

在这些相应的SFML文件中:

zero as null pointer constant [-Werror,-Wzero-as-null-pointer-constant]
declaration is marked with '\deprecated' command but does not have a deprecation attribute [-Werror,-Wdocumentation-deprecated-sync]
declaration is marked with '\deprecated' command but does not have a deprecation attribute [-Werror,-Wdocumentation-deprecated-sync]
declaration is marked with '\deprecated' command but does not have a deprecation attribute [-Werror,-Wdocumentation-deprecated-sync]

我尝试过的其他方法均无效:

  • ThreadLocal.hpp (57) Keyboard.hpp (161) Event.hpp (105) PrimitiveType.hpp (52) / .h文件放入.hpp CMake函数中(与set_source_files_properties文件一起)。适用于Dear Imgui,但它的所有错误都在.cpp文件中,而不是文件头中。不适用于SFML的标头。
  • (不是SFML,而是Dear Imgui),将目录包含为.cpp包括禁止显示警告。在Windows上似乎不起作用。 SFML不能真正做到这一点,因为我使用的是CMake的SYSTEM函数,而不是手动完成所有操作。
  • 使用find_package指令。在此方法有效的同时,每个SFML文件都有许多不同的错误,我想避免在各处使用#pragma(或将SFML的标头包装在我自己的标头中,而这些标头仅将#pragma指令包装在{{1}中) } s。

是否有可能在没有#include的情况下对我的库头隐藏这些警告?我以前从未真正使用过Clang,因此道歉,如果这似乎是一个简单的问题,但是在线搜索并没有真正给我任何可行的方法:

  • 在命令行之外(我将Visual Studio与CMake一起使用)。
  • 在Windows上(系统标记似乎不适用于此设置)。
  • 那将特别适用于CMake。

1 个答案:

答案 0 :(得分:0)

您可以将包含路径标记为 SYSTEM。大多数编译器不会在系统头文件中报告警告。在您的情况下,可能看起来像这样:

include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/libs/imgui)

set_target_properties(sfml-system PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $<TARGET_PROPERTY:sfml-system,INTERFACE_INCLUDE_DIRECTORIES>)
set_target_properties(sfml-audio PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $<TARGET_PROPERTY:sfml-audio,INTERFACE_INCLUDE_DIRECTORIES>)
set_target_properties(sfml-window PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $<TARGET_PROPERTY:sfml-window,INTERFACE_INCLUDE_DIRECTORIES>)
set_target_properties(sfml-graphics PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $<TARGET_PROPERTY:sfml-graphics,INTERFACE_INCLUDE_DIRECTORIES>)

例如,这个虚拟项目:

project(example)
cmake_minimum_required(VERSION 3.18)

add_library(dep INTERFACE)
target_include_directories(dep INTERFACE include)
file(WRITE include/header.h "static int a;")

add_library(lib STATIC lib.c)
target_link_libraries(lib PRIVATE dep)
target_compile_options(lib PRIVATE -Wunused -Werror)
file(WRITE lib.c "#include <header.h>")

失败:

$ cmake . && make
include/header.h:1:12: error: ‘a’ defined but not used [-Werror=unused-variable]

但是在添加这一行之后:

set_target_properties(dep PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $<TARGET_PROPERTY:dep,INTERFACE_INCLUDE_DIRECTORIES>)

它构建时没有错误。