VS: Add UseDebugLibraries to vcxproj files by default

Use heuristics to select a reasonable value.  Add policy CMP0162
to provide compatibility with existing projects.

Fixes: #25327
This commit is contained in:
Brad King 2024-02-16 12:42:37 -05:00
parent 47136b6959
commit 721d8b192a
24 changed files with 130 additions and 9 deletions

View File

@ -51,6 +51,14 @@ The :variable:`CMAKE_MINIMUM_REQUIRED_VERSION` variable may also be used
to determine whether to report an error on use of deprecated macros or
functions.
Policies Introduced by CMake 3.30
=================================
.. toctree::
:maxdepth: 1
CMP0162: Visual Studio generators add UseDebugLibraries indicators by default. </policy/CMP0162>
Policies Introduced by CMake 3.29
=================================

47
Help/policy/CMP0162.rst Normal file
View File

@ -0,0 +1,47 @@
CMP0162
-------
.. versionadded:: 3.30
:ref:`Visual Studio Generators` add ``UseDebugLibraries`` indicators by default.
The "Use Debug Libraries" setting in Visual Studio projects indicates what
configurations are considered debug configurations. In standalone projects,
this may affect MSBuild's default selection of MSVC runtime library,
optimization flags, runtime checks, and similar settings. CMake typically
generates all those settings explicitly based on the project's specification,
so CMake 3.29 and below do not write any ``UseDebugLibraries`` indicators to
``.vcxproj`` files.
CMake 3.30 and above prefer to write ``UseDebugLibraries`` indicators because
they are useful for reference by both humans and tools, and may also affect
the behavior of platform-specific SDKs. The indicator for each configuration
of a target is determined as follows:
* If the target compiles sources for a known MSVC runtime library
(such as that specified by :prop_tgt:`MSVC_RUNTIME_LIBRARY`),
then ``UseDebugLibraries`` is ``true`` for configurations that
compile for a "Debug" runtime library, and ``false`` for others.
* Otherwise, such as in targets created by :command:`add_custom_target`,
``UseDebugLibraries`` is ``true`` for the ``Debug`` configuration,
and ``false`` for others.
This policy provides compatibility for projects that have not been updated to
expect the indicators. The policy setting is recorded by each target as it is
created and used to determine the default behavior for that target's
``.vcxproj`` file.
The ``OLD`` behavior for this policy is to not generate ``UseDebugLibraries``
indicators by default. The ``NEW`` behavior for this policy is to generate
``UseDebugLibraries`` indicators by default.
If the :variable:`CMAKE_VS_USE_DEBUG_LIBRARIES` variable and/or
:prop_tgt:`VS_USE_DEBUG_LIBRARIES` target property is set, it explicitly
controls ``UseDebugLibraries`` generation regardless of this policy.
.. |INTRODUCED_IN_CMAKE_VERSION| replace:: 3.30
.. |WARNS_OR_DOES_NOT_WARN| replace:: does *not* warn
.. include:: STANDARD_ADVICE.txt
.. include:: DEPRECATED.txt

View File

@ -23,5 +23,6 @@ to be non-debug configurations.
The property is initialized from the value of the
:variable:`CMAKE_VS_USE_DEBUG_LIBRARIES` variable, if it is set.
If the property is not set, then CMake does not generate any
``UseDebugLibraries`` indicator.
If the property is not set then CMake generates ``UseDebugLibraries`` using
heuristics to determine which configurations are debug configurations.
See policy :policy:`CMP0162`.

View File

@ -1,6 +1,10 @@
vs-UseDebugLibraries
--------------------
* :ref:`Visual Studio Generators` now add ``UseDebugLibraries`` indicators to
``.vcxproj`` files to denote which configurations are debug configurations.
See policy :policy:`CMP0162`.
* The :variable:`CMAKE_VS_USE_DEBUG_LIBRARIES` variable and corresponding
:prop_tgt:`VS_USE_DEBUG_LIBRARIES` target property were added to explicitly
control ``UseDebugLibraries`` indicators in ``.vcxproj`` files.

View File

@ -24,5 +24,6 @@ property on all targets as they are created. It is also propagated by
calls to the :command:`try_compile` command into its test project.
If this variable is not set then the :prop_tgt:`VS_USE_DEBUG_LIBRARIES`
property will not be set automatically. If that property is not set
then CMake does not generate any ``UseDebugLibraries`` indicator.
property will not be set automatically. If that property is not set then
CMake generates ``UseDebugLibraries`` using heuristics to determine which
configurations are debug configurations. See policy :policy:`CMP0162`.

View File

@ -493,7 +493,11 @@ class cmMakefile;
"More read-only target properties now error when trying to set them.", 3, \
29, 0, cmPolicies::WARN) \
SELECT(POLICY, CMP0161, "CPACK_PRODUCTBUILD_DOMAINS defaults to true.", 3, \
29, 0, cmPolicies::WARN)
29, 0, cmPolicies::WARN) \
SELECT( \
POLICY, CMP0162, \
"Visual Studio generators add UseDebugLibraries indicators by default.", \
3, 30, 0, cmPolicies::WARN)
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
#define CM_FOR_EACH_POLICY_ID(POLICY) \
@ -536,7 +540,8 @@ class cmMakefile;
F(CMP0155) \
F(CMP0156) \
F(CMP0157) \
F(CMP0160)
F(CMP0160) \
F(CMP0162)
#define CM_FOR_EACH_CUSTOM_COMMAND_POLICY(F) \
F(CMP0116) \

View File

@ -1633,6 +1633,19 @@ void cmVisualStudio10TargetGenerator::WriteMSToolConfigurationValuesCommon(
if (!useDebugLibraries.empty()) {
maybeUseDebugLibraries = cmIsOn(useDebugLibraries);
}
} else if (this->GeneratorTarget->GetPolicyStatusCMP0162() ==
cmPolicies::NEW) {
// The project did not explicitly specify a value for this target.
// If the target compiles sources for a known MSVC runtime library,
// base our default value on that.
if (this->GeneratorTarget->GetType() <= cmStateEnums::OBJECT_LIBRARY) {
maybeUseDebugLibraries = this->ClOptions[config]->UsingDebugRuntime();
}
// For other targets, such as UTILITY targets, base our default
// on the configuration name.
if (!maybeUseDebugLibraries) {
maybeUseDebugLibraries = cmSystemTools::UpperCase(config) == "DEBUG"_s;
}
}
if (maybeUseDebugLibraries) {
if (*maybeUseDebugLibraries) {

View File

@ -42,6 +42,7 @@
\* CMP0156
\* CMP0157
\* CMP0160
\* CMP0162
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)

View File

@ -0,0 +1,8 @@
include(${CMAKE_CURRENT_LIST_DIR}/check-common.cmake)
UseDebugLibraries_check(default "true" "false")
UseDebugLibraries_check(defaultCLR "true" "false")
UseDebugLibraries_check(defaultUtil "true" "false")
UseDebugLibraries_check(defaultRTL "true" "false")
UseDebugLibraries_check(ALL_BUILD "true" "false")
UseDebugLibraries_check(ZERO_CHECK "true" "false")

View File

@ -0,0 +1,10 @@
^CMake Deprecation Warning at CMP0091-OLD\.cmake:[0-9]+ \(cmake_policy\):
The OLD behavior for policy CMP0091 will be removed from a future version
of CMake\.
The cmake-policies\(7\) manual explains that the OLD behaviors of all
policies are deprecated and that a policy should be set to OLD only under
specific short-term circumstances\. Projects should be ported to the NEW
behavior and not rely on setting a policy to OLD\.
Call Stack \(most recent call first\):
CMakeLists\.txt:[0-9]+ \(include\)$

View File

@ -0,0 +1,2 @@
cmake_policy(SET CMP0091 OLD)
include(Default-CMP0162-NEW.cmake NO_POLICY_SCOPE)

View File

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

View File

@ -0,0 +1,8 @@
include(${CMAKE_CURRENT_LIST_DIR}/check-common.cmake)
UseDebugLibraries_check(default "true" "false")
UseDebugLibraries_check(defaultCLR "true" "false")
UseDebugLibraries_check(defaultUtil "true" "false")
UseDebugLibraries_check(defaultRTL "false" "false")
UseDebugLibraries_check(ALL_BUILD "true" "false")
UseDebugLibraries_check(ZERO_CHECK "true" "false")

View File

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

View File

@ -0,0 +1,2 @@
# Leave CMP0162 unset.
include(Default-common.cmake)

View File

@ -0,0 +1 @@
include(${CMAKE_CURRENT_LIST_DIR}/Explicit-check-common.cmake)

View File

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

View File

@ -0,0 +1 @@
include(${CMAKE_CURRENT_LIST_DIR}/Explicit-check-common.cmake)

View File

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

View File

@ -1,5 +1,8 @@
cmake_minimum_required(VERSION 3.29)
include(RunCMake)
run_cmake(Default)
run_cmake(Explicit)
run_cmake(CMP0091-OLD)
run_cmake(Default-CMP0162-NEW)
run_cmake(Default-CMP0162-WARN)
run_cmake(Explicit-CMP0162-NEW)
run_cmake(Explicit-CMP0162-OLD)