В настоящее время я пытаюсь настроить проект, который будет использовать несколько компиляторов (включая Clang, MSVC и GCC) с использованием новых функций CMake в Visual Studio 2019 (особенно с использованием Clang и Ninja в сочетании с CMake и VS2019).
Я использую CMake для настройки проекта как «независимого от компилятора», так что Мне не нужно редактировать сам код для обработки различных компиляторов с помощью инструкций препроцессора или#pragma
инструкции.
Этот проект должен быть настроен на высокий уровень предупреждения (/W4
для MSVC, -Wall
, -Wextra
и -Wpedantic
для Clang) и должен обрабатывать предупреждениякак ошибки.
У меня нет проблем с настройкой части проекта MSVC.Многие из этих настроек имеют «нормальные» значения по умолчанию, которые «просто работают», как я и ожидал.Однако когда дело доходит до Clang, я столкнулся с проблемой:
Я не могу отключить предупреждения для сторонних библиотечных заголовочных файлов.В настоящее время я использую библиотеки Dear Imgui и SFML .Так как Dear Imgui предварительно не скомпилирован, я просто делаю в своем файле CMakeLists.txt
следующее:
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/libs/imgui
)
Я использую статически связанную версию SFML, поэтому я делаю следующее, чтобы включитьit:
# 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
)
К сожалению, 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
)
Использование приведенной выше конфигурации приводит к сотням предупреждений / ошибок в исходных файлах 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"
)
Я начинаю с GLOB
, то есть с исходными файлами моей библиотеки (ПРИМЕЧАНИЕ: я знаю, что на GLOB
обычно смотрят свысока, но мне хотелось использовать его со сторонними библиотечными файламибыло хорошо, так как они не должны измениться в любом случае) .Затем я передаю их в функцию set_source_files_properties
, чтобы применить флаг -Wno-everything
, который, похоже, правильно подавляет все ошибки и предупреждения из этих файлов.
Кажется, что все работает нормально, за исключением одного предупреждения, которое яне могу отключить без использования #pragma
инструкции в моем коде (чего я хочу избежать).При компиляции пустой функции main
, включающей заголовки SFML, я получаю предупреждения об их .hpp
файлах (которые нельзя передать в функцию set_source_files_properties
).
This:
#include <SFML/Graphics.hpp>
int main()
{
}
В результате появляются следующие предупреждения / ошибки:
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]
В этих соответствующих файлах SFML:
ThreadLocal.hpp (57)
Keyboard.hpp (161)
Event.hpp (105)
PrimitiveType.hpp (52)
Другие вещи, которые я пробовал, не работали:
- Помещение файлов
.h
/ .hpp
в функцию set_source_files_properties
CMake (наряду с файлами .cpp
).Работает на Уважаемый Imgui, но все его ошибки были в .cpp
файлах, а не в его заголовках.Не работает для заголовков SFML. - (Не для SFML, но для уважаемого Imgui) Включение каталогов, включенных в
SYSTEM
, для подавления предупреждений.Не работает на Windows.На самом деле не могу сделать это с SFML, так как я использую функцию CMake find_package
вместо того, чтобы делать все вручную. - Используя инструкции
#pragma
.Хотя это работало, каждый SFML-файл содержит десятки различных ошибок, и я хочу избегать повсеместного использования #pragma
s (или оборачивать заголовки SFML в мои собственные заголовки, которые просто обертывают инструкцию #include
в #pragma
s).
Возможно ли вообще отключить эти предупреждения для заголовков моей библиотеки без #pragma
с? Я никогда раньше не использовал Clang, поэтому извиняюсь, если это кажется простым вопросом, но поиск в Интернете не дал мне ничего, что могло бы сработать:
- Вне командной строки (я использую Visual Studio с CMake).
- В Windows (системный флаг, похоже, не работает с этой настройкой).
- Это будет работать конкретно с CMake.