Browse Source

VS: Add option for custom Win10 SDK version maximum

Since commit 83ddc4d289 (VS: Do not select a Windows SDK too high for
current VS version, 2017-08-07, v3.13.0-rc1~72^2~2) we enforce a maximum
SDK version for the VS 2015 generator.  The blog post linked in the
original commit is no longer available, but it can be seen here:

* https://web.archive.org/web/20190108032520/https://blogs.msdn.microsoft.com/chuckw/2018/10/02/windows-10-october-2018-update/

In particular, it states:

> VS 2015 Users: The Windows 10 SDK (15063, 16299, 17134, 17763)
> is officially only supported for VS 2017.

However, in some circumstances a higher version can be used.

Add a `CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION_MAXIMUM` to override the
generator's default maximum SDK version.

Fixes: #20633
jonathan molinatto 5 years ago
parent
commit
ba497111f6

+ 16 - 0
Help/generator/Visual Studio 14 2015.rst

@@ -45,3 +45,19 @@ via the :manual:`cmake(1)` ``-T`` option, to specify another toolset.
    By default this generator uses the 32-bit variant even on a 64-bit host.
 
 .. include:: VS_TOOLSET_HOST_ARCH.txt
+
+.. _`Windows 10 SDK Maximum Version for VS 2015`:
+
+Windows 10 SDK Maximum Version for VS 2015
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Microsoft stated in a "Windows 10 October 2018 Update" blog post that Windows
+10 SDK versions (15063, 16299, 17134, 17763) are not supported by VS 2015 and
+are only supported by VS 2017 and later.  Therefore by default CMake
+automatically ignores Windows 10 SDKs beyond ``10.0.14393.0``.
+
+However, there are other recommendations for certain driver/Win32 builds that
+indicate otherwise.  A user can override this behavior by either setting the
+:variable:`CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION_MAXIMUM` to a false value
+or setting the :variable:`CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION_MAXIMUM` to
+the string value of the required maximum (e.g. ``10.0.15063.0``).

+ 1 - 0
Help/manual/cmake-variables.7.rst

@@ -124,6 +124,7 @@ Variables that Provide Information
    /variable/CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE
    /variable/CMAKE_VS_PLATFORM_TOOLSET_VERSION
    /variable/CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION
+   /variable/CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION_MAXIMUM
    /variable/CMAKE_XCODE_GENERATE_SCHEME
    /variable/CMAKE_XCODE_PLATFORM_TOOLSET
    /variable/PROJECT-NAME_BINARY_DIR

+ 6 - 0
Help/release/dev/vs-win-sdk-custom-max.rst

@@ -0,0 +1,6 @@
+vs-win-sdk-custom-max
+---------------------
+
+* A :variable:`CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION_MAXIMUM` variable
+  was added to tell the :ref:`Visual Studio Generators` what maximumm
+  version of the Windows SDK to choose.

+ 2 - 0
Help/variable/CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION.rst

@@ -17,3 +17,5 @@ One may set a ``CMAKE_WINDOWS_KITS_10_DIR`` *environment variable*
 to an absolute path to tell CMake to look for Windows 10 SDKs in
 a custom location.  The specified directory is expected to contain
 ``Include/10.0.*`` directories.
+
+See also :variable:`CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION_MAXIMUM`.

+ 14 - 0
Help/variable/CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION_MAXIMUM.rst

@@ -0,0 +1,14 @@
+CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION_MAXIMUM
+------------------------------------------------
+
+.. versionadded:: 3.19
+
+Override the :ref:`Windows 10 SDK Maximum Version for VS 2015`.
+
+The :variable:`CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION_MAXIMUM` variable may
+be set to a false value (e.g. ``OFF``, ``FALSE``, or ``0``) or the SDK version
+to use as the maximum (e.g. ``10.0.14393.0``).  If unset, the default depends
+on which version of Visual Studio is targeted by the current generator.
+
+This can be used in conjunction with :variable:`CMAKE_SYSTEM_VERSION`, which
+CMake uses to select :variable:`CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION`.

+ 26 - 5
Source/cmGlobalVisualStudio14Generator.cxx

@@ -169,7 +169,8 @@ bool cmGlobalVisualStudio14Generator::SelectWindows10SDK(cmMakefile* mf,
                                                          bool required)
 {
   // Find the default version of the Windows 10 SDK.
-  std::string const version = this->GetWindows10SDKVersion();
+  std::string const version = this->GetWindows10SDKVersion(mf);
+
   if (required && version.empty()) {
     std::ostringstream e;
     e << "Could not find an appropriate version of the Windows 10 SDK"
@@ -233,8 +234,25 @@ bool cmGlobalVisualStudio14Generator::IsWindowsStoreToolsetInstalled() const
                                           cmSystemTools::KeyWOW64_32);
 }
 
-std::string cmGlobalVisualStudio14Generator::GetWindows10SDKMaxVersion() const
+std::string cmGlobalVisualStudio14Generator::GetWindows10SDKMaxVersion(
+  cmMakefile* mf) const
 {
+  // if the given value is set, it can either be OFF/FALSE or a valid SDK
+  // string
+  if (std::string const* value =
+        mf->GetDef("CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION_MAXIMUM")) {
+
+    // If the value is some off/false value, then there is NO maximum set.
+    if (cmIsOff(value)) {
+      return std::string();
+    }
+    // If the value is something else, trust that it is a valid SDK value.
+    else if (value) {
+      return *value;
+    }
+    // If value is an invalid pointer, leave result unchanged.
+  }
+
   // The last Windows 10 SDK version that VS 2015 can target is 10.0.14393.0.
   //
   // "VS 2015 Users: The Windows 10 SDK (15063, 16299, 17134, 17763) is
@@ -267,7 +285,8 @@ public:
 };
 #endif
 
-std::string cmGlobalVisualStudio14Generator::GetWindows10SDKVersion()
+std::string cmGlobalVisualStudio14Generator::GetWindows10SDKVersion(
+  cmMakefile* mf)
 {
 #if defined(_WIN32) && !defined(__CYGWIN__)
   std::vector<std::string> win10Roots;
@@ -317,8 +336,10 @@ std::string cmGlobalVisualStudio14Generator::GetWindows10SDKVersion()
     i = cmSystemTools::GetFilenameName(i);
   }
 
-  // Skip SDKs that cannot be used with our toolset.
-  std::string maxVersion = this->GetWindows10SDKMaxVersion();
+  // Skip SDKs that cannot be used with our toolset, unless the user does not
+  // want to limit the highest supported SDK according to the Microsoft
+  // documentation.
+  std::string maxVersion = this->GetWindows10SDKMaxVersion(mf);
   if (!maxVersion.empty()) {
     cm::erase_if(sdks, WindowsSDKTooRecent(maxVersion));
   }

+ 2 - 2
Source/cmGlobalVisualStudio14Generator.h

@@ -43,7 +43,7 @@ protected:
 
   // Used to make sure that the Windows 10 SDK selected can work with the
   // version of the toolset.
-  virtual std::string GetWindows10SDKMaxVersion() const;
+  virtual std::string GetWindows10SDKMaxVersion(cmMakefile* mf) const;
 
   virtual bool SelectWindows10SDK(cmMakefile* mf, bool required);
 
@@ -54,7 +54,7 @@ protected:
   // installed on the machine.
   bool IsWindowsDesktopToolsetInstalled() const override;
 
-  std::string GetWindows10SDKVersion();
+  std::string GetWindows10SDKVersion(cmMakefile* mf);
 
 private:
   class Factory;

+ 2 - 2
Source/cmGlobalVisualStudioVersionedGenerator.cxx

@@ -540,8 +540,8 @@ bool cmGlobalVisualStudioVersionedGenerator::IsWin81SDKInstalled() const
   return false;
 }
 
-std::string cmGlobalVisualStudioVersionedGenerator::GetWindows10SDKMaxVersion()
-  const
+std::string cmGlobalVisualStudioVersionedGenerator::GetWindows10SDKMaxVersion(
+  cmMakefile*) const
 {
   return std::string();
 }

+ 1 - 1
Source/cmGlobalVisualStudioVersionedGenerator.h

@@ -57,7 +57,7 @@ protected:
   // Check for a Win 8 SDK known to the registry or VS installer tool.
   bool IsWin81SDKInstalled() const;
 
-  std::string GetWindows10SDKMaxVersion() const override;
+  std::string GetWindows10SDKMaxVersion(cmMakefile*) const override;
 
   std::string FindMSBuildCommand() override;
   std::string FindDevEnvCommand() override;