MSVC: Default to -ZI instead of /Zi for x86 and x64

Add a policy for compatibility.

For more information, see [1].

[1] https://docs.microsoft.com/en-us/cpp/build/reference/z7-zi-zi-debug-information-format?view=msvc-170

Fixes: #10189
This commit is contained in:
Glen Chung 2022-05-24 12:14:59 -07:00 committed by Brad King
parent bb50072355
commit 5fcadc481e
14 changed files with 115 additions and 3 deletions

View File

@ -58,6 +58,7 @@ Policies Introduced by CMake 3.24
.. toctree::
:maxdepth: 1
CMP0138: MSVC compilers use -ZI instead of /Zi for x86 and x64 by default. </policy/CMP0138>
CMP0137: try_compile() passes platform variables in project mode. </policy/CMP0137>
CMP0136: Watcom runtime library flags are selected by an abstraction. </policy/CMP0136>
CMP0135: ExternalProject ignores timestamps in archives by default for the URL download method. </policy/CMP0135>

43
Help/policy/CMP0138.rst Normal file
View File

@ -0,0 +1,43 @@
CMP0138
-------
.. versionadded:: 3.24
MSVC compilers use ``-ZI`` instead of ``/Zi`` for x86 and x64 by default.
When using MSVC C/C++ compilers in CMake 3.23 and below, debug information
format flag ``/Zi`` is added to :variable:`CMAKE_<LANG>_FLAGS_DEBUG` and
:variable:`CMAKE_<LANG>_FLAGS_RELWITHDEBINFO` by default. The ``/Zi`` flag
produces a separate PDB file that contains all the symbolic debugging
information for use with the debugger, however, it does not support Edit
and Continue feature in a debugging session.
CMake 3.24 and above adds ``-ZI`` to :variable:`CMAKE_<LANG>_FLAGS_DEBUG`
and :variable:`CMAKE_<LANG>_FLAGS_RELWITHDEBINFO` instead to enable Edit
and Continue by default.
This policy provides compatibility with projects that have not been updated
to expect the lack of warning flags. The policy setting takes effect as of
the first :command:`project` or :command:`enable_language` command that
initializes :variable:`CMAKE_<LANG>_FLAGS_DEBUG` and
:variable:`CMAKE_<LANG>_FLAGS_RELWITHDEBINFO` for a given language
``<LANG>`` using MSVC compilers.
.. note::
Once the policy has taken effect at the top of a project for a given
language, that choice must be used throughout the tree for that language.
In projects that have nested projects in subdirectories, be sure to
convert everything together.
The ``OLD`` behavior for this policy is to place ``/Zi`` in the default
:variable:`CMAKE_<LANG>_FLAGS_DEBUG` and
:variable:`CMAKE_<LANG>_FLAGS_RELWITHDEBINFO` cache entries. The ``NEW``
behavior for this policy is to place ``-ZI`` in the default cache entries.
This policy was introduced in CMake version 3.24. Use the
:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.
Unlike many policies, CMake version |release| does *not* warn
when this policy is not set and simply uses ``OLD`` behavior.
.. include:: DEPRECATED.txt

View File

@ -0,0 +1,5 @@
msvc-compilers-default-to-ZI
----------------------------
* With MSVC compilers, debug configurations now use ``-ZI`` by default
instead of ``/Zi``. See policy :policy:`CMP0138`.

View File

@ -2,6 +2,15 @@ include(Platform/Windows-MSVC)
if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 18.0)
set(_FS_C " /FS")
endif()
cmake_policy(GET CMP0138 _cmp0138)
if(_cmp0138 STREQUAL "NEW")
if(NOT _MSVC_C_ARCHITECTURE_FAMILY STREQUAL "ARM" AND NOT _MSVC_C_ARCHITECTURE_FAMILY STREQUAL "ARM64")
set(_ZiOrZI "-ZI")
endif()
endif()
unset(_cmp0138)
__windows_compiler_msvc(C)
if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)

View File

@ -3,6 +3,15 @@ set(_COMPILE_CXX " /TP")
if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 18.0)
set(_FS_CXX " /FS")
endif()
cmake_policy(GET CMP0138 _cmp0138)
if(_cmp0138 STREQUAL "NEW")
if(NOT _MSVC_CXX_ARCHITECTURE_FAMILY STREQUAL "ARM" AND NOT _MSVC_CXX_ARCHITECTURE_FAMILY STREQUAL "ARM64")
set(_ZiOrZI "-ZI")
endif()
endif()
unset(_cmp0138)
__windows_compiler_msvc(CXX)
if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)

View File

@ -441,6 +441,10 @@ macro(__windows_compiler_msvc lang)
endif()
unset(_cmp0092)
if(NOT DEFINED _ZiOrZI)
set(_ZiOrZI "/Zi")
endif()
if(CMAKE_VS_PLATFORM_TOOLSET MATCHES "v[0-9]+_clang_.*")
# note: MSVC 14 2015 Update 1 sets -fno-ms-compatibility by default, but this does not allow one to compile many projects
# that include MS's own headers. CMake itself is affected project too.
@ -451,15 +455,16 @@ macro(__windows_compiler_msvc lang)
string(APPEND CMAKE_${lang}_FLAGS_MINSIZEREL_INIT "${_MD} -DNDEBUG") # TODO: Add '-Os' once VS generator maps it properly for Clang
else()
string(APPEND CMAKE_${lang}_FLAGS_INIT " ${_PLATFORM_DEFINES}${_PLATFORM_DEFINES_${lang}} /D_WINDOWS${_W3}${_FLAGS_${lang}}")
string(APPEND CMAKE_${lang}_FLAGS_DEBUG_INIT "${_MDd} /Zi /Ob0 /Od ${_RTC1}")
string(APPEND CMAKE_${lang}_FLAGS_DEBUG_INIT "${_MDd} ${_ZiOrZI} /Ob0 /Od ${_RTC1}")
string(APPEND CMAKE_${lang}_FLAGS_RELEASE_INIT "${_MD} /O2 /Ob2 /DNDEBUG")
string(APPEND CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT "${_MD} /Zi /O2 /Ob1 /DNDEBUG")
string(APPEND CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT "${_MD} ${_ZiOrZI} /O2 /Ob1 /DNDEBUG")
string(APPEND CMAKE_${lang}_FLAGS_MINSIZEREL_INIT "${_MD} /O1 /Ob1 /DNDEBUG")
endif()
unset(_Wall)
unset(_W3)
unset(_MDd)
unset(_MD)
unset(_ZiOrZI)
set(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreaded -MT)
set(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL -MD)

View File

@ -414,7 +414,10 @@ class cmMakefile;
24, 0, cmPolicies::WARN) \
SELECT(POLICY, CMP0137, \
"try_compile() passes platform variables in project mode", 3, 24, 0, \
cmPolicies::WARN)
cmPolicies::WARN) \
SELECT(POLICY, CMP0138, \
"MSVC compilers use -ZI instead of /Zi for x86 and x64 by default.", \
3, 24, 0, cmPolicies::WARN)
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
#define CM_FOR_EACH_POLICY_ID(POLICY) \

View File

@ -352,6 +352,9 @@ if(MSVC)
add_RunCMake_test(MSVCRuntimeLibrary)
add_RunCMake_test(MSVCRuntimeTypeInfo)
add_RunCMake_test(MSVCWarningFlags)
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
add_RunCMake_test(MSVCDebugInformationFormat)
endif()
endif()
if(XCODE_VERSION)
set(ObjectLibrary_ARGS -DXCODE_VERSION=${XCODE_VERSION})

View File

@ -0,0 +1,2 @@
cmake_policy(SET CMP0138 NEW)
include(CMP0138-common.cmake)

View File

@ -0,0 +1,2 @@
cmake_policy(SET CMP0138 OLD)
include(CMP0138-common.cmake)

View File

@ -0,0 +1,2 @@
include(CMP0138-common.cmake)

View File

@ -0,0 +1,20 @@
foreach(lang C CXX)
enable_language(${lang})
cmake_policy(GET CMP0138 cmp0138)
if(cmp0138 STREQUAL "NEW")
if(NOT " ${CMAKE_${lang}_FLAGS_DEBUG} " MATCHES " -ZI ")
message(SEND_ERROR "CMAKE_${lang}_FLAGS_DEBUG does not have '-ZI' under NEW behavior")
endif()
if(NOT " ${CMAKE_${lang}_FLAGS_RELWITHDEBINFO} " MATCHES " -ZI ")
message(SEND_ERROR "CMAKE_${lang}_FLAGS_RELWITHDEBINFO does not have '-ZI' under NEW behavior")
endif()
else()
if(NOT " ${CMAKE_${lang}_FLAGS_DEBUG} " MATCHES " /Zi ")
message(SEND_ERROR "CMAKE_${lang}_FLAGS_DEBUG does not have '/Zi' under OLD behavior")
endif()
if(NOT " ${CMAKE_${lang}_FLAGS_RELWITHDEBINFO} " MATCHES " /Zi ")
message(SEND_ERROR "CMAKE_${lang}_FLAGS_RELWITHDEBINFO does not have '/Zi' under OLD behavior")
endif()
endif()
endforeach()

View File

@ -0,0 +1,3 @@
cmake_minimum_required(VERSION 3.23)
project(${RunCMake_TEST} NONE)
include(${RunCMake_TEST}.cmake)

View File

@ -0,0 +1,5 @@
include(RunCMake)
run_cmake(CMP0138-WARN)
run_cmake(CMP0138-OLD)
run_cmake(CMP0138-NEW)