Ответы:
ОБНОВЛЕНИЕ: этот ответ предшествует эпохе Modern CMake. Каждый здравомыслящий пользователь CMake должен воздерживаться от CMAKE_CXX_FLAGS
непосредственных действий и target_compile_options
вместо этого вызывать команду. Проверьте ответ MRTS, в котором представлены рекомендуемые лучшие практики.
Вы можете сделать что-то подобное:
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()
/Wall
можно использовать, если вы хотите использовать «вычитающую» стратегию предупреждений, как и clang -Weverything
. Вместо того, чтобы выбирать предупреждения для включения, вы включаете все, а затем выбираете определенные предупреждения, которые нужно отключить.
В современном CMake хорошо работает следующее:
if(MSVC)
target_compile_options(${TARGET_NAME} PRIVATE /W4 /WX)
else()
target_compile_options(${TARGET_NAME} PRIVATE -Wall -Wextra -pedantic -Werror)
endif()
Мой коллега предложил альтернативный вариант:
target_compile_options(${TARGET_NAME} PRIVATE
$<$<CXX_COMPILER_ID:MSVC>:/W4 /WX>
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wall -Wextra -pedantic -Werror>
)
Замените ${TARGET_NAME}
фактическим именем цели.-Werror
не является обязательным, он превращает все предупреждения в ошибки.
Или используйте add_compile_options(...)
если хотите применить его ко всем целям, как предлагает @aldo в комментариях.
Кроме того, убедитесь, что понимаете разницу между PRIVATE
и PUBLIC
(общедоступные параметры будут унаследованы целями, которые зависят от данной цели).
add_compile_options(...)
если вы хотите применить его ко всем целям.
else()
или endif()
.
add_compile_options()
в том, что предупреждения будут распространяться на цели, добавленные через add_subdirectory()
. Если вы включите внешние библиотеки таким образом, вы можете получить множество предупреждений, если эта библиотека была разработана с другим уровнем предупреждений.
Некоторые модули 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
Вот лучшее решение, которое я нашел до сих пор (включая проверку компилятора):
if(CMAKE_BUILD_TOOL MATCHES "(msdev|devenv|nmake)")
add_definitions(/W2)
endif()
Это установит уровень предупреждения 2 в Visual Studio. Я полагаю, что с a -W2
это будет работать и в GCC (непроверено).
Обновление от @Williams: должно быть -Wall
для GCC.
-Wall
и, возможно, -Wextra
подробно описан на gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
-W -Wall -Wextra -pedantic
. -Wextra
IIRC заменен -W
в более поздней версии GCC, но я оставлю оба варианта для обеспечения совместимости.
В соответствии с 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.
add_compile_options
распространяется на весь каталог, тогда target_compile_options
как только для одной цели.
if(MSVC)
string(REGEX REPLACE "/W[1-3]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
endif()
Если вы используете target_compile_options
- cmake попытается использовать двойной /W*
флаг, который выдаст предупреждение компилятору.
add_compile_options
единственный, чтобы получить массу предупреждений, /W3
которые меняют /W4
. Тот факт, что CMake не обращается к этому элементарному параметру (установка уровня предупреждения), невероятен.
/Wall
флаг (с именемEnableAllWarnings
). Он выдает даже больше предупреждений, чем/W4
. Однако, по моему опыту, он дает слишком много предупреждений.