Compiler option stripped by Visual Studio generator?

It seems the VS 16 code generator is stripping /Wall (all warnings), while the NMake and Ninja generators do not. Is this expected?

cmake version 3.23.1
CMakeLists.txt:

cmake_minimum_required(VERSION 3.16.3)
project(hello)
add_executable(hello hello.c)
target_compile_options(hello PUBLIC /WX /Wall /W4)

cmake -B cmake_out -S . -G "Visual Studio 16 2019" -A Win32
Resulting compiler command:

  C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.29.30133\bin\HostX64\x86\CL.exe /c /Zi /nologo /W4 /WX /diagnostics:column /Od /Ob0 /Oy- /D _MBCS /D WIN32 /D _WINDOWS /D "CMAKE_INTDIR=\"Debug\"" /Gm- /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Zc:inline /Fo"hello.dir\Debug\\" /Fd"hello.dir\Debug\vc142.pdb" /external:W4 /Gd /TC /analyze- /errorReport:queue C:\dev\toolchain\hello.c

Notice that /Wall does not appear on the command line.

cmake -B cmake_out -S . -G "NMake Makefiles"
With NMake, /Wall is present:

        echo  /nologo   /DWIN32 /D_WINDOWS /Zi /Ob0 /Od /RTC1 -MDd /WX /Wall /W4 /showIncludes /FoCMakeFiles\hello.dir\hello.c.obj /FdCMakeFiles\hello.dir\ /FS -c C:\dev\toolchain\hello.c > c:\dev\temp\nm522D.tmp
        C:\dev\cmake-3.23.1-windows-x86_64\cmake-3.23.1-windows-x86_64\bin\cmake.exe -E cmake_cl_compile_depends --dep-file=CMakeFiles\hello.dir\hello.c.obj.d --working-dir=C:\dev\toolchain\cmake_out --filter-prefix="Note: including file: " -- C:\PROGRA~2\MICROS~4\2019\ENTERP~1\VC\Tools\MSVC\1429~1.301\bin\Hostx64\x86\cl.exe @c:\dev\temp\nm522D.tmp

Is this expected?

Looks like this is a result of a “lossy” translation to vcxproj and back.

Turns out Wall isn’t being stripped specifically, but earlier options are lost:

Wall: target_compile_options(hello PUBLIC /WX /W4 /Wall)
  W4: target_compile_options(hello PUBLIC /WX /Wall /W4)

The generated vcxproj has the Visual Studio XML setting for warning:

      <WarningLevel>Level4</WarningLevel>

or

      <WarningLevel>EnableAllWarnings</WarningLevel>

based on the last compile option given.

This results in a last-writer-wins overwrite that is different from the behavior of the compiler when both options are provided on the command line (the most verbose option wins).

I had expected target_compile_options to show up as raw compile options on the command line.

Sounds like an issue to me, though I’m not sure of the best way to fix it (sounds like a policy would be necessary).

Cc: @brad.king

The VS generators parse out flags known to map to specific .vcxproj settings, and generate the settings instead. Both /W4 and /Wall map to the WarningLevel setting. The last one wins, just as /W3 /W4 would choose the latter in a direct cl command-line invocation.