Browse Source

Merge topic 'vs-UseDebugLibraries'

721d8b192a VS: Add UseDebugLibraries to vcxproj files by default
47136b6959 VS: Suppress more MSBuild defaults affected by UseDebugLibraries
82a174182a cmVisualStudioGeneratorOptions: Add UsingDebugRuntime method
f498032141 cmVisualStudioGeneratorOptions: Rename {IsDebug => UsingDebugInfo}

Acked-by: Kitware Robot <[email protected]>
Acked-by: buildbot <[email protected]>
Merge-request: !9275
Brad King 1 year ago
parent
commit
7f1bdcc714
27 changed files with 151 additions and 15 deletions
  1. 8 0
      Help/manual/cmake-policies.7.rst
  2. 47 0
      Help/policy/CMP0162.rst
  3. 3 2
      Help/prop_tgt/VS_USE_DEBUG_LIBRARIES.rst
  4. 4 0
      Help/release/dev/vs-UseDebugLibraries.rst
  5. 3 2
      Help/variable/CMAKE_VS_USE_DEBUG_LIBRARIES.rst
  6. 2 2
      Source/cmLocalVisualStudio7Generator.cxx
  7. 7 2
      Source/cmPolicies.h
  8. 18 2
      Source/cmVisualStudio10TargetGenerator.cxx
  9. 10 1
      Source/cmVisualStudioGeneratorOptions.cxx
  10. 4 1
      Source/cmVisualStudioGeneratorOptions.h
  11. 1 0
      Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt
  12. 8 0
      Tests/RunCMake/VS10ProjectUseDebugLibraries/CMP0091-OLD-check.cmake
  13. 10 0
      Tests/RunCMake/VS10ProjectUseDebugLibraries/CMP0091-OLD-stderr.txt
  14. 2 0
      Tests/RunCMake/VS10ProjectUseDebugLibraries/CMP0091-OLD.cmake
  15. 1 1
      Tests/RunCMake/VS10ProjectUseDebugLibraries/CMakeLists.txt
  16. 8 0
      Tests/RunCMake/VS10ProjectUseDebugLibraries/Default-CMP0162-NEW-check.cmake
  17. 2 0
      Tests/RunCMake/VS10ProjectUseDebugLibraries/Default-CMP0162-NEW.cmake
  18. 0 0
      Tests/RunCMake/VS10ProjectUseDebugLibraries/Default-CMP0162-WARN-check.cmake
  19. 2 0
      Tests/RunCMake/VS10ProjectUseDebugLibraries/Default-CMP0162-WARN.cmake
  20. 0 0
      Tests/RunCMake/VS10ProjectUseDebugLibraries/Default-common.cmake
  21. 1 0
      Tests/RunCMake/VS10ProjectUseDebugLibraries/Explicit-CMP0162-NEW-check.cmake
  22. 2 0
      Tests/RunCMake/VS10ProjectUseDebugLibraries/Explicit-CMP0162-NEW.cmake
  23. 1 0
      Tests/RunCMake/VS10ProjectUseDebugLibraries/Explicit-CMP0162-OLD-check.cmake
  24. 2 0
      Tests/RunCMake/VS10ProjectUseDebugLibraries/Explicit-CMP0162-OLD.cmake
  25. 0 0
      Tests/RunCMake/VS10ProjectUseDebugLibraries/Explicit-check-common.cmake
  26. 0 0
      Tests/RunCMake/VS10ProjectUseDebugLibraries/Explicit-common.cmake
  27. 5 2
      Tests/RunCMake/VS10ProjectUseDebugLibraries/RunCMakeTest.cmake

+ 8 - 0
Help/manual/cmake-policies.7.rst

@@ -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
 to determine whether to report an error on use of deprecated macros or
 functions.
 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
 Policies Introduced by CMake 3.29
 =================================
 =================================
 
 

+ 47 - 0
Help/policy/CMP0162.rst

@@ -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

+ 3 - 2
Help/prop_tgt/VS_USE_DEBUG_LIBRARIES.rst

@@ -23,5 +23,6 @@ to be non-debug configurations.
 
 
 The property is initialized from the value of the
 The property is initialized from the value of the
 :variable:`CMAKE_VS_USE_DEBUG_LIBRARIES` variable, if it is set.
 :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`.

+ 4 - 0
Help/release/dev/vs-UseDebugLibraries.rst

@@ -1,6 +1,10 @@
 vs-UseDebugLibraries
 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
 * The :variable:`CMAKE_VS_USE_DEBUG_LIBRARIES` variable and corresponding
   :prop_tgt:`VS_USE_DEBUG_LIBRARIES` target property were added to explicitly
   :prop_tgt:`VS_USE_DEBUG_LIBRARIES` target property were added to explicitly
   control ``UseDebugLibraries`` indicators in ``.vcxproj`` files.
   control ``UseDebugLibraries`` indicators in ``.vcxproj`` files.

+ 3 - 2
Help/variable/CMAKE_VS_USE_DEBUG_LIBRARIES.rst

@@ -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.
 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`
 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`.

+ 2 - 2
Source/cmLocalVisualStudio7Generator.cxx

@@ -1135,7 +1135,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
         cmStrCat(target->GetPDBDirectory(configName), '/', targetNames.PDB);
         cmStrCat(target->GetPDBDirectory(configName), '/', targetNames.PDB);
       fout << "\t\t\t\tProgramDatabaseFile=\""
       fout << "\t\t\t\tProgramDatabaseFile=\""
            << this->ConvertToXMLOutputPathSingle(temp) << "\"\n";
            << this->ConvertToXMLOutputPathSingle(temp) << "\"\n";
-      if (targetOptions.IsDebug()) {
+      if (targetOptions.UsingDebugInfo()) {
         fout << "\t\t\t\tGenerateDebugInformation=\"true\"\n";
         fout << "\t\t\t\tGenerateDebugInformation=\"true\"\n";
       }
       }
       if (this->WindowsCEProject) {
       if (this->WindowsCEProject) {
@@ -1223,7 +1223,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
         target->GetPDBDirectory(configName));
         target->GetPDBDirectory(configName));
       fout << "\t\t\t\tProgramDatabaseFile=\"" << path << "/"
       fout << "\t\t\t\tProgramDatabaseFile=\"" << path << "/"
            << targetNames.PDB << "\"\n";
            << targetNames.PDB << "\"\n";
-      if (targetOptions.IsDebug()) {
+      if (targetOptions.UsingDebugInfo()) {
         fout << "\t\t\t\tGenerateDebugInformation=\"true\"\n";
         fout << "\t\t\t\tGenerateDebugInformation=\"true\"\n";
       }
       }
       if (this->WindowsCEProject) {
       if (this->WindowsCEProject) {

+ 7 - 2
Source/cmPolicies.h

@@ -493,7 +493,11 @@ class cmMakefile;
     "More read-only target properties now error when trying to set them.", 3, \
     "More read-only target properties now error when trying to set them.", 3, \
     29, 0, cmPolicies::WARN)                                                  \
     29, 0, cmPolicies::WARN)                                                  \
   SELECT(POLICY, CMP0161, "CPACK_PRODUCTBUILD_DOMAINS defaults to true.", 3,  \
   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_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
 #define CM_FOR_EACH_POLICY_ID(POLICY)                                         \
 #define CM_FOR_EACH_POLICY_ID(POLICY)                                         \
@@ -536,7 +540,8 @@ class cmMakefile;
   F(CMP0155)                                                                  \
   F(CMP0155)                                                                  \
   F(CMP0156)                                                                  \
   F(CMP0156)                                                                  \
   F(CMP0157)                                                                  \
   F(CMP0157)                                                                  \
-  F(CMP0160)
+  F(CMP0160)                                                                  \
+  F(CMP0162)
 
 
 #define CM_FOR_EACH_CUSTOM_COMMAND_POLICY(F)                                  \
 #define CM_FOR_EACH_CUSTOM_COMMAND_POLICY(F)                                  \
   F(CMP0116)                                                                  \
   F(CMP0116)                                                                  \

+ 18 - 2
Source/cmVisualStudio10TargetGenerator.cxx

@@ -1577,7 +1577,7 @@ void cmVisualStudio10TargetGenerator::WriteMSToolConfigurationValuesManaged(
 
 
   Options& o = *(this->ClOptions[config]);
   Options& o = *(this->ClOptions[config]);
 
 
-  if (o.IsDebug()) {
+  if (o.UsingDebugInfo()) {
     e1.Element("DebugSymbols", "true");
     e1.Element("DebugSymbols", "true");
     e1.Element("DefineDebug", "true");
     e1.Element("DefineDebug", "true");
   }
   }
@@ -1633,6 +1633,19 @@ void cmVisualStudio10TargetGenerator::WriteMSToolConfigurationValuesCommon(
     if (!useDebugLibraries.empty()) {
     if (!useDebugLibraries.empty()) {
       maybeUseDebugLibraries = cmIsOn(useDebugLibraries);
       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) {
     if (*maybeUseDebugLibraries) {
     if (*maybeUseDebugLibraries) {
@@ -3528,6 +3541,9 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
     if (!clOptions.HasFlag("BasicRuntimeChecks")) {
     if (!clOptions.HasFlag("BasicRuntimeChecks")) {
       clOptions.AddFlag("BasicRuntimeChecks", "Default");
       clOptions.AddFlag("BasicRuntimeChecks", "Default");
     }
     }
+    if (!clOptions.HasFlag("MinimalRebuild")) {
+      clOptions.AddFlag("MinimalRebuild", "");
+    }
     if (!clOptions.HasFlag("Optimization")) {
     if (!clOptions.HasFlag("Optimization")) {
       clOptions.AddFlag("Optimization", "");
       clOptions.AddFlag("Optimization", "");
     }
     }
@@ -3581,7 +3597,7 @@ void cmVisualStudio10TargetGenerator::WriteClOptions(
     // without value so PDBs don't get generated uselessly. Each tag
     // without value so PDBs don't get generated uselessly. Each tag
     // goes on its own line because Visual Studio corrects it this
     // goes on its own line because Visual Studio corrects it this
     // way when saving the project after CMake generates it.
     // way when saving the project after CMake generates it.
-    if (!clOptions.IsDebug()) {
+    if (!clOptions.UsingDebugInfo()) {
       Elem e3(e2, "DebugInformationFormat");
       Elem e3(e2, "DebugInformationFormat");
       e3.SetHasElements();
       e3.SetHasElements();
     }
     }

+ 10 - 1
Source/cmVisualStudioGeneratorOptions.cxx

@@ -110,7 +110,7 @@ void cmVisualStudioGeneratorOptions::SetVerboseMakefile(bool verbose)
   }
   }
 }
 }
 
 
-bool cmVisualStudioGeneratorOptions::IsDebug() const
+bool cmVisualStudioGeneratorOptions::UsingDebugInfo() const
 {
 {
   if (this->CurrentTool != CSharpCompiler) {
   if (this->CurrentTool != CSharpCompiler) {
     return this->FlagMap.find("DebugInformationFormat") != this->FlagMap.end();
     return this->FlagMap.find("DebugInformationFormat") != this->FlagMap.end();
@@ -124,6 +124,15 @@ bool cmVisualStudioGeneratorOptions::IsDebug() const
   return false;
   return false;
 }
 }
 
 
+cm::optional<bool> cmVisualStudioGeneratorOptions::UsingDebugRuntime() const
+{
+  cm::optional<bool> result;
+  if (const char* rtl = this->GetFlag("RuntimeLibrary")) {
+    result = strstr(rtl, "Debug") != nullptr;
+  }
+  return result;
+}
+
 bool cmVisualStudioGeneratorOptions::IsWinRt() const
 bool cmVisualStudioGeneratorOptions::IsWinRt() const
 {
 {
   return this->FlagMap.find("CompileAsWinRT") != this->FlagMap.end();
   return this->FlagMap.find("CompileAsWinRT") != this->FlagMap.end();

+ 4 - 1
Source/cmVisualStudioGeneratorOptions.h

@@ -7,6 +7,8 @@
 #include <iosfwd>
 #include <iosfwd>
 #include <string>
 #include <string>
 
 
+#include <cm/optional>
+
 #include "cmGlobalVisualStudioGenerator.h"
 #include "cmGlobalVisualStudioGenerator.h"
 #include "cmIDEFlagTable.h"
 #include "cmIDEFlagTable.h"
 #include "cmIDEOptions.h"
 #include "cmIDEOptions.h"
@@ -65,7 +67,8 @@ public:
 
 
   void FixManifestUACFlags();
   void FixManifestUACFlags();
 
 
-  bool IsDebug() const;
+  bool UsingDebugInfo() const;
+  cm::optional<bool> UsingDebugRuntime() const;
   bool IsWinRt() const;
   bool IsWinRt() const;
   bool IsManaged() const;
   bool IsManaged() const;
   // Write options to output.
   // Write options to output.

+ 1 - 0
Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt

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

+ 8 - 0
Tests/RunCMake/VS10ProjectUseDebugLibraries/CMP0091-OLD-check.cmake

@@ -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")

+ 10 - 0
Tests/RunCMake/VS10ProjectUseDebugLibraries/CMP0091-OLD-stderr.txt

@@ -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\)$

+ 2 - 0
Tests/RunCMake/VS10ProjectUseDebugLibraries/CMP0091-OLD.cmake

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

+ 1 - 1
Tests/RunCMake/VS10ProjectUseDebugLibraries/CMakeLists.txt

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

+ 8 - 0
Tests/RunCMake/VS10ProjectUseDebugLibraries/Default-CMP0162-NEW-check.cmake

@@ -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")

+ 2 - 0
Tests/RunCMake/VS10ProjectUseDebugLibraries/Default-CMP0162-NEW.cmake

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

+ 0 - 0
Tests/RunCMake/VS10ProjectUseDebugLibraries/Default-check.cmake → Tests/RunCMake/VS10ProjectUseDebugLibraries/Default-CMP0162-WARN-check.cmake


+ 2 - 0
Tests/RunCMake/VS10ProjectUseDebugLibraries/Default-CMP0162-WARN.cmake

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

+ 0 - 0
Tests/RunCMake/VS10ProjectUseDebugLibraries/Default.cmake → Tests/RunCMake/VS10ProjectUseDebugLibraries/Default-common.cmake


+ 1 - 0
Tests/RunCMake/VS10ProjectUseDebugLibraries/Explicit-CMP0162-NEW-check.cmake

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

+ 2 - 0
Tests/RunCMake/VS10ProjectUseDebugLibraries/Explicit-CMP0162-NEW.cmake

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

+ 1 - 0
Tests/RunCMake/VS10ProjectUseDebugLibraries/Explicit-CMP0162-OLD-check.cmake

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

+ 2 - 0
Tests/RunCMake/VS10ProjectUseDebugLibraries/Explicit-CMP0162-OLD.cmake

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

+ 0 - 0
Tests/RunCMake/VS10ProjectUseDebugLibraries/Explicit-check.cmake → Tests/RunCMake/VS10ProjectUseDebugLibraries/Explicit-check-common.cmake


+ 0 - 0
Tests/RunCMake/VS10ProjectUseDebugLibraries/Explicit.cmake → Tests/RunCMake/VS10ProjectUseDebugLibraries/Explicit-common.cmake


+ 5 - 2
Tests/RunCMake/VS10ProjectUseDebugLibraries/RunCMakeTest.cmake

@@ -1,5 +1,8 @@
 cmake_minimum_required(VERSION 3.29)
 cmake_minimum_required(VERSION 3.29)
 include(RunCMake)
 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)