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).
As @davidfong notes in the comments, since CMake v3.24, there is the CMAKE_COMPILE_WARNING_AS_ERROR
variable that switches on treating compile warings as errors. In case it is set inside CMakeLists.txt
, the user can still turn it off with the --compile-no-warning-as-error
cmake
flag. In case you want to add warning-as-error manually, add /WX
in Windows and -Werror
elsewhere to target_compile_options
.