diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 635db0023..211690050 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -82,6 +82,7 @@ Variables that Provide Information
/variable/CMAKE_VS_NsightTegra_VERSION
/variable/CMAKE_VS_PLATFORM_NAME
/variable/CMAKE_VS_PLATFORM_TOOLSET
+ /variable/CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION
/variable/CMAKE_XCODE_PLATFORM_TOOLSET
/variable/PROJECT_BINARY_DIR
/variable/PROJECT-NAME_BINARY_DIR
diff --git a/Help/release/dev/vs-win10-sdk.rst b/Help/release/dev/vs-win10-sdk.rst
new file mode 100644
index 000000000..50eb39133
--- /dev/null
+++ b/Help/release/dev/vs-win10-sdk.rst
@@ -0,0 +1,6 @@
+vs-win10-sdk
+------------
+
+* The :generator:`Visual Studio 14 2015` generator learned to select
+ a Windows 10 SDK based on the value of the :variable:`CMAKE_SYSTEM_VERSION`
+ variable and the SDKs available on the host.
diff --git a/Help/variable/CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION.rst b/Help/variable/CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION.rst
new file mode 100644
index 000000000..639284963
--- /dev/null
+++ b/Help/variable/CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION.rst
@@ -0,0 +1,11 @@
+CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION
+----------------------------------------
+
+Visual Studio Windows Target Platform Version.
+
+When targeting Windows 10 and above Visual Studio 2015 and above support
+specification of a target Windows version to select a corresponding SDK.
+The :variable:`CMAKE_SYSTEM_VERSION` variable may be set to specify a
+version. Otherwise CMake computes a default version based on the Windows
+SDK versions available. The chosen Windows target version number is provided
+in ``CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION``.
diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake
index df6daf372..81c25090c 100644
--- a/Modules/CMakeDetermineCompilerId.cmake
+++ b/Modules/CMakeDetermineCompilerId.cmake
@@ -209,6 +209,9 @@ Id flags: ${testflags}
else()
set(id_system_version "")
endif()
+ if(CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION)
+ set(id_WindowsTargetPlatformVersion "${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}")
+ endif()
if(id_platform STREQUAL ARM)
set(id_WindowsSDKDesktopARMSupport "true")
else()
diff --git a/Modules/CompilerId/VS-10.vcxproj.in b/Modules/CompilerId/VS-10.vcxproj.in
index a17d03d0d..2870a11ca 100644
--- a/Modules/CompilerId/VS-10.vcxproj.in
+++ b/Modules/CompilerId/VS-10.vcxproj.in
@@ -12,6 +12,7 @@
Win32Proj
@id_system@
@id_system_version@
+ @id_WindowsTargetPlatformVersion@
@id_WindowsSDKDesktopARMSupport@
diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h
index 49c561601..f4861dc6d 100644
--- a/Source/cmGlobalVisualStudio10Generator.h
+++ b/Source/cmGlobalVisualStudio10Generator.h
@@ -74,6 +74,10 @@ public:
/** Return the CMAKE_SYSTEM_VERSION. */
std::string const& GetSystemVersion() const { return this->SystemVersion; }
+ /** Return the Windows version targeted on VS 2015 and above. */
+ std::string const& GetWindowsTargetPlatformVersion() const
+ { return this->WindowsTargetPlatformVersion; }
+
/** Return true if building for WindowsCE */
bool TargetsWindowsCE() const
{ return this->SystemIsWindowsCE; }
@@ -120,6 +124,7 @@ protected:
std::string GeneratorToolset;
std::string DefaultPlatformToolset;
+ std::string WindowsTargetPlatformVersion;
std::string SystemName;
std::string SystemVersion;
std::string NsightTegraVersion;
diff --git a/Source/cmGlobalVisualStudio14Generator.cxx b/Source/cmGlobalVisualStudio14Generator.cxx
index d73eedf92..74679d842 100644
--- a/Source/cmGlobalVisualStudio14Generator.cxx
+++ b/Source/cmGlobalVisualStudio14Generator.cxx
@@ -110,6 +110,34 @@ cmGlobalVisualStudio14Generator::MatchesGeneratorName(
return false;
}
+//----------------------------------------------------------------------------
+bool cmGlobalVisualStudio14Generator::InitializeWindows(cmMakefile* mf)
+{
+ if (cmHasLiteralPrefix(this->SystemVersion, "10.0"))
+ {
+ return this->SelectWindows10SDK(mf);
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmGlobalVisualStudio14Generator::SelectWindows10SDK(cmMakefile* mf)
+{
+ // Find the default version of the Windows 10 SDK.
+ this->WindowsTargetPlatformVersion = this->GetWindows10SDKVersion();
+ if (this->WindowsTargetPlatformVersion.empty())
+ {
+ std::ostringstream e;
+ e << "Could not find an appropriate version of the Windows 10 SDK"
+ << " installed on this machine";
+ mf->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+ }
+ mf->AddDefinition("CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION",
+ this->WindowsTargetPlatformVersion.c_str());
+ return true;
+}
+
//----------------------------------------------------------------------------
void cmGlobalVisualStudio14Generator::WriteSLNHeader(std::ostream& fout)
{
@@ -137,3 +165,55 @@ cmGlobalVisualStudio14Generator::IsWindowsDesktopToolsetInstalled() const
return cmSystemTools::GetRegistrySubKeys(desktop10Key,
vc14, cmSystemTools::KeyWOW64_32);
}
+
+//----------------------------------------------------------------------------
+std::string cmGlobalVisualStudio14Generator::GetWindows10SDKVersion()
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ // This logic is taken from the vcvarsqueryregistry.bat file from VS2015
+ // Try HKLM and then HKCU.
+ std::string win10Root;
+ if (!cmSystemTools::ReadRegistryValue(
+ "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"
+ "Windows Kits\\Installed Roots;KitsRoot10", win10Root,
+ cmSystemTools::KeyWOW64_32) &&
+ !cmSystemTools::ReadRegistryValue(
+ "HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\"
+ "Windows Kits\\Installed Roots;KitsRoot10", win10Root,
+ cmSystemTools::KeyWOW64_32))
+ {
+ return std::string();
+ }
+
+ std::vector sdks;
+ std::string path = win10Root + "Include/*";
+ // Grab the paths of the different SDKs that are installed
+ cmSystemTools::GlobDirs(path, sdks);
+ if (!sdks.empty())
+ {
+ // Only use the filename, which will be the SDK version.
+ for (std::vector::iterator i = sdks.begin();
+ i != sdks.end(); ++i)
+ {
+ *i = cmSystemTools::GetFilenameName(*i);
+ }
+
+ // Sort the results to make sure we select the most recent one that
+ // has a version less or equal to our version of the operating system
+ std::sort(sdks.begin(), sdks.end(), cmSystemTools::VersionCompareGreater);
+
+ for (std::vector::iterator i = sdks.begin();
+ i != sdks.end(); ++i)
+ {
+ // Find the SDK less or equal to our specified version
+ if (!cmSystemTools::VersionCompareGreater(*i, this->SystemVersion))
+ {
+ // This is the most recent SDK that we can run safely
+ return *i;
+ }
+ }
+ }
+#endif
+ // Return an empty string
+ return std::string();
+}
diff --git a/Source/cmGlobalVisualStudio14Generator.h b/Source/cmGlobalVisualStudio14Generator.h
index 02c6274f5..fcade852c 100644
--- a/Source/cmGlobalVisualStudio14Generator.h
+++ b/Source/cmGlobalVisualStudio14Generator.h
@@ -30,12 +30,16 @@ public:
virtual const char* GetToolsVersion() { return "14.0"; }
protected:
+ virtual bool InitializeWindows(cmMakefile* mf);
virtual const char* GetIDEVersion() { return "14.0"; }
+ virtual bool SelectWindows10SDK(cmMakefile* mf);
// Used to verify that the Desktop toolset for the current generator is
// installed on the machine.
virtual bool IsWindowsDesktopToolsetInstalled() const;
+ std::string GetWindows10SDKVersion();
+
private:
class Factory;
};
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 6c71313e9..91f24766b 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -3006,6 +3006,8 @@ IsXamlSource(const std::string& sourceFile)
void cmVisualStudio10TargetGenerator::WriteApplicationTypeSettings()
{
+ cmGlobalVisualStudio10Generator* gg =
+ static_cast(this->GlobalGenerator);
bool isAppContainer = false;
bool const isWindowsPhone = this->GlobalGenerator->TargetsWindowsPhone();
bool const isWindowsStore = this->GlobalGenerator->TargetsWindowsStore();
@@ -3062,6 +3064,14 @@ void cmVisualStudio10TargetGenerator::WriteApplicationTypeSettings()
this->WriteString("true"
"\n", 2);
}
+ std::string const& targetPlatformVersion =
+ gg->GetWindowsTargetPlatformVersion();
+ if (!targetPlatformVersion.empty())
+ {
+ this->WriteString("", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(targetPlatformVersion) <<
+ "\n";
+ }
}
void cmVisualStudio10TargetGenerator::VerifyNecessaryFiles()