Как установить уровень предупреждения в CMake?
Как установить уровень предупреждения для проекта (а не для всего решения) с помощью CMake? Должен работать на Visual Studio и GCC.
Я нашел различные варианты, но большинство, кажется, либо не работают, либо не соответствуют документации.
7 ответов
Вот лучшее решение, которое я нашел до сих пор (включая проверку компилятора):
if(CMAKE_BUILD_TOOL MATCHES "(msdev|devenv|nmake)")
add_definitions(/W2)
endif()
Это установит уровень предупреждения 2 в Visual Studio. Я полагаю, с -W2
это также будет работать в GCC (не проверено).
Обновление от @Williams: должно быть -Wall
для GCC.
В современном CMake хорошо работает следующее:
if(MSVC)
target_compile_options(${TARGET_NAME} PRIVATE /W4 /WX)
else(MSVC)
target_compile_options(${TARGET_NAME} PRIVATE -Wall -Wextra -pedantic -Werror)
endif(MSVC)
замещать ${TARGET_NAME}
с фактическим именем цели. -Werror
не является обязательным, он превращает все предупреждения в ошибки.
ОБНОВЛЕНИЕ: Этот ответ предшествует эре современного CMake. Каждый здравомыслящий пользователь CMake должен воздерживаться от возни с CMAKE_CXX_FLAGS
прямо и позвоните target_compile_options
команда вместо Проверьте ответ MRT, который представляет рекомендуемые лучшие практики.
Вы можете сделать что-то похожее на это:
if(MSVC)
# Force to always compile with W4
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)
# Update if necessary
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic")
endif()
Некоторые написанные мной модули CMake включают экспериментальное кросс-платформенное подавление предупреждений:
sugar_generate_warning_flags(
target_compile_options
target_properties
ENABLE conversion
TREAT_AS_ERRORS ALL
)
set_target_properties(
foo
PROPERTIES
${target_properties}
COMPILE_OPTIONS
"${target_compile_options}"
)
Результат для Xcode:
- Задавать
CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION
Атрибут Xcode (он же настройки сборки -> предупреждения -> подозрительные неявные преобразования -> ДА) - Добавить флаг компилятора:
-Werror
Makefile gcc и clang:
- Добавьте флаги компилятора:
-Wconversion
,-Werror
Визуальная студия:
- Добавьте флаги компилятора:
/WX
,/w14244
связи
В соответствии с CMake 3.17.1 документации:
if (MSVC)
# warning level 4 and all warnings as errors
add_compile_options(/W4 /WX)
else()
# lots of warnings and all warnings as errors
add_compile_options(-Wall -Wextra -pedantic -Werror)
endif()
GCC и Clang используют эти флаги, так что это должно охватывать все 3.
if(MSVC)
string(REGEX REPLACE "/W[1-3]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
endif()
Если вы используете target_compile_options
- cmake попытается использовать двойной /W*
флаг, который будет предупреждать компилятор.
Как установить уровень предупреждения для проекта (не всего решения) с помощью CMake?
(Я предполагаю, что это означает цельCMake , а не проектCMake .)
Я нашел различные варианты, но большинство из них либо не работают, либо не соответствуют документации.
API-интерфейсы Kitware могут пытаться удержать вас от того, чтобы сделать вашу систему сборки хрупкой и подверженной ошибкам. Особый корпус, поощряемый другими ответами на этот вопрос, нарушает как минимум два важных принципа современных систем сборки CMake...
Во- первых, лучше не указывать подробности, относящиеся к набору инструментов, в файлах CMakeLists.txt. Это делает систему сборки хрупкой. Например, если в будущей версии цепочки инструментов появится новое предупреждение, компилятор выдаст ошибку, и вашему пользователю может потребоваться взломать ваш проект, чтобы построить цель.
Вместо этого напишите файлы CMakeLists.txt, не зависящие от цепочки инструментов, и сохраните возможность пользователя настраивать по своему усмотрению. В идеале ваш проект должен собираться везде с ванильной конфигурацией набора инструментов, даже если это не включает ваши предпочтительные предупреждения по умолчанию.
Во-вторых, если вы собираетесь связать двоичные файлы вместе, флаги должны быть согласованы. Это снижает риск несовместимости, которая может привести к неправильному формату программы. Тем не менее, предупреждающие флаги вряд ли повлияют на генерацию кода, поэтому может быть безопасно варьировать их между целевыми объектами, которые вы связываете вместе.
Итак... если вы хотите указать флаги для каждой цепочки инструментов и если вам абсолютно необходимо иметь разные флаги для разных целей, используйте пользовательские переменные:
# CMakeLists.txt
project(my_project)
add_executable(my_target source_file.cpp)
target_compile_options(my_target PRIVATE "${MY_PROJECT_ELEVATED_WARNING_FLAGS}")
Есть много способов установить эти переменные, например, CMakeCache.txt, файл цепочки инструментов и через
cmake -DMY_PROJECT_ELEVATED_WARNING_FLAGS:STRING="-Wall;-Wextra;-Wpedantic;-Werror" <path-to-project>
для MSVC
cmake -DMY_PROJECT_ELEVATED_WARNING_FLAGS:STRING="/W4;/WX" <path-to-project>