From 89b611ab3232cdeb4892458bf9d6c3281a8fda00 Mon Sep 17 00:00:00 2001
From: Brad King <brad.king@kitware.com>
Date: Tue, 8 Aug 2023 16:43:14 -0400
Subject: [PATCH] VS: Select latest Windows SDK even when targeting Windows 8.1
 and below

The policy added by commit f90c8ab54e (VS: Select latest available
Windows SDK version by default, 2023-04-03, v3.27.0-rc1~206^2~1) applied
only when targeting Windows 10+.  Apply it to older versions too.

Fixes: #25170
Issue: #16202
---
 Help/release/3.27.rst                                |  5 +++++
 Source/cmGlobalVisualStudio14Generator.cxx           | 10 ++++++++++
 Tests/RunCMake/GeneratorPlatform/RunCMakeTest.cmake  |  2 +-
 .../GeneratorPlatform/VersionExists-check.cmake      | 12 ++++++++----
 4 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/Help/release/3.27.rst b/Help/release/3.27.rst
index 9b9db838959..457b48ca3a9 100644
--- a/Help/release/3.27.rst
+++ b/Help/release/3.27.rst
@@ -275,6 +275,11 @@ Changes made since CMake 3.27.0 include the following.
 3.27.2
 ------
 
+* :ref:`Visual Studio Generators` for VS 14 (2015) and above now prefer to
+  select the latest Windows SDK, as documented by policy :policy:`CMP0149`,
+  when targeting any version of Windows.  In CMake 3.27.[0-1] the
+  preference was limited to targeting Windows 10 and above.
+
 * :ref:`Visual Studio Generators` for VS 14 (2015) and above now support
   using ``version=8.1`` in the :variable:`CMAKE_GENERATOR_PLATFORM` variable
   to select the Windows 8.1 SDK.  In CMake 3.27.[0-1] the ``version=`` field
diff --git a/Source/cmGlobalVisualStudio14Generator.cxx b/Source/cmGlobalVisualStudio14Generator.cxx
index 506a12add28..01294dd1916 100644
--- a/Source/cmGlobalVisualStudio14Generator.cxx
+++ b/Source/cmGlobalVisualStudio14Generator.cxx
@@ -217,6 +217,16 @@ bool cmGlobalVisualStudio14Generator::InitializePlatformWindows(cmMakefile* mf)
     return this->SelectWindows10SDK(mf);
   }
 
+  // Under CMP0149 NEW behavior, we search for a Windows 10 SDK even
+  // when targeting older Windows versions, but it is not required.
+  if (mf->GetPolicyStatus(cmPolicies::CMP0149) == cmPolicies::NEW) {
+    std::string const version = this->GetWindows10SDKVersion(mf);
+    if (!version.empty()) {
+      this->SetWindowsTargetPlatformVersion(version, mf);
+      return true;
+    }
+  }
+
   // We are not targeting Windows 10+, so fall back to the Windows 8.1 SDK.
   // For VS 2019 and above we must explicitly specify it.
   if (this->Version >= cmGlobalVisualStudioGenerator::VSVersion::VS16 &&
diff --git a/Tests/RunCMake/GeneratorPlatform/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorPlatform/RunCMakeTest.cmake
index 7620b13758f..d8965f7493f 100644
--- a/Tests/RunCMake/GeneratorPlatform/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GeneratorPlatform/RunCMakeTest.cmake
@@ -103,7 +103,6 @@ if("${RunCMake_GENERATOR}" MATCHES "^Visual Studio (1[4567])( 20[0-9][0-9])?$")
     run_cmake_with_options(VersionExists -DCMAKE_SYSTEM_VERSION=10.0)
     unset(RunCMake_GENERATOR_PLATFORM)
   endforeach()
-  list(REMOVE_ITEM kits 8.1)
   foreach(expect_version IN LISTS kits)
     set(RunCMake_TEST_VARIANT_DESCRIPTION "-CMP0149-OLD-${expect_version}")
     run_cmake_with_options(VersionExists -DCMAKE_SYSTEM_VERSION=${expect_version} -DCMAKE_POLICY_DEFAULT_CMP0149=OLD)
@@ -115,6 +114,7 @@ if("${RunCMake_GENERATOR}" MATCHES "^Visual Studio (1[4567])( 20[0-9][0-9])?$")
       run_cmake_with_options(VersionExists -DCMAKE_SYSTEM_VERSION=${test_version} -DCMAKE_POLICY_DEFAULT_CMP0149=NEW)
     endforeach()
   endif()
+  list(REMOVE_ITEM kits 8.1)
   foreach(expect_version IN LISTS kits)
     set(RunCMake_TEST_VARIANT_DESCRIPTION "-WindowsSDKVersion-${expect_version}")
     set(ENV{WindowsSDKVersion} "${expect_version}\\")
diff --git a/Tests/RunCMake/GeneratorPlatform/VersionExists-check.cmake b/Tests/RunCMake/GeneratorPlatform/VersionExists-check.cmake
index 6c3c8e542b0..62fb278249c 100644
--- a/Tests/RunCMake/GeneratorPlatform/VersionExists-check.cmake
+++ b/Tests/RunCMake/GeneratorPlatform/VersionExists-check.cmake
@@ -1,9 +1,13 @@
 if(actual_stdout MATCHES "CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION='([^']+)'")
   set(actual_version "${CMAKE_MATCH_1}")
-  if(NOT "${actual_version}" STREQUAL "${expect_version}")
-    set(RunCMake_TEST_FAILED "Actual SDK version '${actual_version}' did not match expected '${expect_version}'")
-    return()
-  endif()
+elseif(actual_stdout MATCHES "CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=''" AND RunCMake_GENERATOR MATCHES "Visual Studio 1[45] ")
+  set(actual_version "8.1")
 else()
   set(RunCMake_TEST_FAILED "No CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION found in output.")
+  return()
+endif()
+
+if(NOT "${actual_version}" STREQUAL "${expect_version}")
+  set(RunCMake_TEST_FAILED "Actual SDK version '${actual_version}' did not match expected '${expect_version}'")
+  return()
 endif()
-- 
GitLab