Відповіді:
ОНОВЛЕННЯ: Ця відповідь передує ері 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
є корисним, якщо ви хочете дотримуватися "віднімаючої" стратегії для попереджень, як і кланг -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. Я припускаю, що -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
. Однак, з мого досвіду, це створює занадто багато попереджень.