mic*_*190 10 c++ cmake clang suppress-warnings
我目前正在尝试使用 Visual Studio 2019 的新 CMake 功能(特别是将 Clang 和 Ninja 与 CMake 和 VS2019 结合使用)来设置一个项目,该项目将使用多个编译器(包括 Clang、MSVC 和 GCC)。
我正在使用 CMake 将项目配置为“与编译器无关”,这样我就不需要编辑代码本身来通过预处理器指令或#pragma
指令处理不同的编译器。
这个项目需要进行配置,以具有较高的警告级别(/W4
对于MSVC, ,-Wall
,-Wextra
和-Wpedantic
为锵),并且必须将警告视为错误。
在配置项目的 MSVC 部分时,我没有任何问题。很多这些设置都有“正常”的默认值,正如我所期望的那样“正常工作”。但是,当涉及到 Clang 时,我遇到了一个问题:
我似乎无法禁用第三方库头文件的警告。我目前正在使用Dear Imgui和SFML库。由于 Dear Imgui 未预编译,因此我只需在我的CMakeLists.txt
文件中执行以下操作即可将其包含在内:
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/libs/imgui
)
Run Code Online (Sandbox Code Playgroud)
我使用 SFML 的静态链接版本,因此我执行以下操作以包含它:
# 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
)
Run Code Online (Sandbox Code Playgroud)
遗憾的是,SFML 目前没有遵循当前的 CMake 标准添加库的方式,因此通过 CMake 使用或配置它有点奇怪。
现在,当涉及到在我的项目中包含库时,上面的方法工作得很好(但它可能是我需要更改的内容,因此我已将其包含在帖子中)。当我在使用 Clang 时尝试将警告和警告作为错误配置强加给他们时,问题就出现了。
以下是我的CMakeLists.txt
文件中处理 Clang 和 C++ 配置的部分:
# 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
)
Run Code Online (Sandbox Code Playgroud)
使用上述配置会在 Dear Imgui 的源文件中导致数百个警告/错误(由于使用了“老派”C++/C 风格的代码),以及在 SFML 自己的源文件和头文件中的一大堆警告/错误文件。
在确定以下解决方案之前,我一直在寻找解决此问题的方法近一个星期(这并不完全有效,稍后会详细介绍):
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"
)
Run Code Online (Sandbox Code Playgroud)
我首先GLOB
-ing 我的库源文件(注意:我知道GLOB
通常被看不起,但我觉得将它与第三方库文件一起使用很好,因为无论如何它们都不应该改变)。然后我将它们传递给set_source_files_properties
函数以应用-Wno-everything
标志,这似乎正确地抑制了来自这些文件的所有错误和警告。
一切似乎都很好,除了一个警告,如果不使用#pragma
我的代码中的指令(我想避免),我似乎无法禁用该警告。编译main
包含 SFML 标头的空函数时,我收到有关其.hpp
文件的警告(无法传递给set_source_files_properties
函数)。
这个:
#include <SFML/Graphics.hpp>
int main()
{
}
Run Code Online (Sandbox Code Playgroud)
导致以下警告/错误:
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]
Run Code Online (Sandbox Code Playgroud)
在这些各自的 SFML 文件中:
ThreadLocal.hpp (57)
Keyboard.hpp (161)
Event.hpp (105)
PrimitiveType.hpp (52)
Run Code Online (Sandbox Code Playgroud)
我尝试过的其他方法不起作用:
.h
/.hpp
文件放在set_source_files_properties
CMake 函数中(与.cpp
文件一起)。适用于 Dear Imgui,但它的所有错误都在.cpp
文件中,而不是其标题中。不适用于 SFML 的标头。SYSTEM
包含以抑制警告。似乎在 Windows 上不起作用。不能用 SFML 真正做到这一点,因为我使用的是 CMake 的find_package
函数而不是手动完成所有事情。#pragma
说明。虽然这有效,但每个 SFML 文件都有几十个不同的错误,我想避免#pragma
在任何地方使用s(或者将 SFML 的头文件包装在我自己的头文件中,这些头文件只是将#include
指令包装在#pragma
s 中)。甚至可以在没有#pragma
s 的情况下抑制我的库标题的这些警告吗?我以前从未真正使用过 Clang,所以如果这看起来是一个简单的问题,我深表歉意,但在线搜索并没有真正给我任何有用的东西:
Atn*_*nNn 13
您可以将包含路径标记为SYSTEM
。大多数编译器不会在系统头中报告警告。在你的情况下,可能看起来像这样:
include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/libs/imgui)\n\nset_target_properties(sfml-system PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $<TARGET_PROPERTY:sfml-system,INTERFACE_INCLUDE_DIRECTORIES>)\nset_target_properties(sfml-audio PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $<TARGET_PROPERTY:sfml-audio,INTERFACE_INCLUDE_DIRECTORIES>)\nset_target_properties(sfml-window PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $<TARGET_PROPERTY:sfml-window,INTERFACE_INCLUDE_DIRECTORIES>)\nset_target_properties(sfml-graphics PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $<TARGET_PROPERTY:sfml-graphics,INTERFACE_INCLUDE_DIRECTORIES>)\n
Run Code Online (Sandbox Code Playgroud)\n例如,这个虚拟项目:
\nproject(example)\ncmake_minimum_required(VERSION 3.18)\n\nadd_library(dep INTERFACE)\ntarget_include_directories(dep INTERFACE include)\nfile(WRITE include/header.h "static int a;")\n\nadd_library(lib STATIC lib.c)\ntarget_link_libraries(lib PRIVATE dep)\ntarget_compile_options(lib PRIVATE -Wunused -Werror)\nfile(WRITE lib.c "#include <header.h>")\n
Run Code Online (Sandbox Code Playgroud)\n失败:
\n$ cmake . && make\ninclude/header.h:1:12: error: \xe2\x80\x98a\xe2\x80\x99 defined but not used [-Werror=unused-variable]\n
Run Code Online (Sandbox Code Playgroud)\n但添加这一行后:
\nset_target_properties(dep PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $<TARGET_PROPERTY:dep,INTERFACE_INCLUDE_DIRECTORIES>)\n
Run Code Online (Sandbox Code Playgroud)\n它构建没有错误。
\n 归档时间: |
|
查看次数: |
4144 次 |
最近记录: |