Understanding CMP0092: MSVC Warning Flag Handling in CMake


What is CMP0092?

CMP0092 is a CMake policy introduced in version 3.15 that controls how warning flags are handled for MSVC-like compilers. It addresses a behavior change that occurred between CMake versions 3.14 and 3.15.

What's the Issue?

  • New Behavior (CMake >= 3.15)

    • To provide more control, MSVC warning flags are no longer included in the default CMAKE_<LANG>_FLAGS values.
    • This allows projects to explicitly set the desired warning level.
    • By default, MSVC warning flags (like /W3) were automatically added to the CMAKE_<LANG>_FLAGS variable for C and C++ languages.
    • This could be problematic if a project wanted to set a different warning level programmatically. It necessitated manual manipulation of the CMAKE_<LANG>_FLAGS variable, requiring knowledge of CMake's default flags.

Why Use CMP0092?

  • Compatibility with Older Projects
    • CMP0092 offers compatibility with projects that haven't been updated to expect the absence of warning flags in CMAKE_<LANG>_FLAGS.
    • By setting this policy to OLD, projects can maintain the pre-3.15 behavior if necessary.

How to Use CMP0092

  1. Set the Policy

    • Use the cmake_policy command to explicitly set CMP0092 to either OLD or NEW.
    cmake_policy(CMP0092 NEW)  # Enable new behavior (warning flags not in default)
    # OR
    cmake_policy(CMP0092 OLD)  # Maintain old behavior (warning flags in default)
    
  2. Placement of the Policy Command

    • The policy setting takes effect at the first project or enable_language command that initializes the CMAKE_<LANG>_FLAGS variable for a given language.
    • For consistency across a project, ensure the policy is set at the top level or before any language-specific configuration.

Important Considerations

  • Default Behavior (No Policy Set)
    • Unlike many policies, CMake doesn't warn if CMP0092 isn't explicitly set. It defaults to the OLD behavior (warning flags in CMAKE_<LANG>_FLAGS).
  • Nested Projects
    • If your project has nested subdirectories, make sure to convert all projects consistently (either to OLD or NEW behavior) to avoid potential issues.


Example 1: Setting CMP0092 to NEW (Modern Behavior)

This example sets the policy to NEW, ensuring MSVC warning flags are not included in the default compiler flags:

cmake_policy(CMP0092 NEW)  # Enable new behavior (warning flags not in default)

project(MyProject)

# Language-specific configuration (warning flags can be set explicitly here)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W3")  # Example: Set warning level for C
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /WX")  # Example: Treat warnings as errors for C++

add_executable(my_executable source1.cpp source2.c)

Example 2: Maintaining Old Behavior (Compatibility)

This example shows how to maintain the pre-3.15 behavior by setting CMP0092 to OLD:

cmake_policy(CMP0092 OLD)  # Maintain old behavior (warning flags in default)

project(MyOldProject)

# No need to set warning flags explicitly (uses CMake's default behavior)

add_executable(my_old_executable source_old.cpp)


Explicitly Setting Warning Flags

  • Regardless of the CMP0092 policy setting, you can always explicitly set the desired warning flags for each language using target_compile_options:
project(MyProject)

# Set warning flags explicitly (works with any CMP0092 setting)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W3")  # Example: Set warning level for C
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /WX")  # Example: Treat warnings as errors for C++

add_executable(my_executable source1.cpp source2.c)

Treat Warnings as Errors

  • If you want warnings to be treated as errors during compilation, use the COMPILE_WARNING_AS_ERROR target property:
project(MyProject)

# Treat warnings as errors (works with any CMP0092 setting)
set_property(TARGET my_executable PROPERTY COMPILE_WARNING_AS_ERROR ON)

add_executable(my_executable source1.cpp source2.c)
  • For more complex scenarios, you could create custom CMake modules to manage warning flags based on specific logic or project requirements.