How to set warning level in CMake?

In modern CMake, the following works well:

if(MSVC)
  target_compile_options(${TARGET_NAME} PRIVATE /W4 /WX)
else()
  target_compile_options(${TARGET_NAME} PRIVATE -Wall -Wextra -Wpedantic -Werror)
endif()

My colleague suggested an alternative version:

target_compile_options(${TARGET_NAME} PRIVATE
  $<$<CXX_COMPILER_ID:MSVC>:/W4 /WX>
  $<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wall -Wextra -Wpedantic -Werror>
)

Replace ${TARGET_NAME} with the actual target name. -Werror is optional, it turns all warnings into errors.

Or use add_compile_options(...) if you want to apply it to all targets as suggested by @aldo in the comments.

Also, be sure to understand the difference between PRIVATE and PUBLIC (public options will be inherited by targets that depend on the given target).


UPDATE: This answer predates the Modern CMake era. Every sane CMake user should refrain from fiddling with CMAKE_CXX_FLAGS directly and call the target_compile_options command instead. Check the mrts' answer which presents the recommended best practice.

You can do something similar to this:

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()

Some CMake modules I've written include experimental cross-platfrom warning suppression:

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}"
)

Result for Xcode:

  • Set CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION Xcode attribute (aka build settings -> warnings -> suspicious implicit conversions -> YES)
  • Add compiler flag: -Werror

Makefile gcc and clang:

  • Add compiler flags: -Wconversion, -Werror

Visual studio:

  • Add compiler flags: /WX, /w14244

Links

  • List of available warnings
  • Usage and more options

As per Cmake 3.21.1 documentation:

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 and Clang share these flags, so this should cover all 3.


Here is the best solution I found so far (including a compiler check):

if(CMAKE_BUILD_TOOL MATCHES "(msdev|devenv|nmake)")
    add_definitions(/W2)
endif()

The GCC equivalent is -Wall (untested).