From a74fe38c46174da2826953a7ee42e7319f729f1e Mon Sep 17 00:00:00 2001
From: Kitty Barnett <develop@catznip.com>
Date: Sat, 6 May 2017 16:55:23 +0200
Subject: [PATCH] Reviewed for Catznip-5.3 (x64)   -> updated
 FindWindowsSDK.cmake for improved Win10 SDK detection   -> added windows64
 package for fmodex   -> [FIXED] fmodex library isn't found during linking for
 x64 builds

--HG--
branch : Viewer-Build
---
 .hgpatchinfo/Viewer-Build.desc   |   3 -
 autobuild.xml                    |   8 +-
 indra/cmake/FMODEX.cmake         |  12 +-
 indra/cmake/FindWindowsSDK.cmake | 650 +++++++++++++++++++++++--------
 4 files changed, 490 insertions(+), 183 deletions(-)

diff --git a/.hgpatchinfo/Viewer-Build.desc b/.hgpatchinfo/Viewer-Build.desc
index 8349f263280..8664994447f 100644
--- a/.hgpatchinfo/Viewer-Build.desc
+++ b/.hgpatchinfo/Viewer-Build.desc
@@ -1,6 +1,4 @@
 [Viewer/Build]
-* Changed compiler options for "Release with Debug" builds
-* Changed compiler and linker options for "Release" builds
 * Enforce EOL consistency through .hgeol
 * Removed LL's changeset tags and added new (consistent) SL-X.Y.Z tags for releases
 * Break into the debugger rather than forcing the process into an unrecoverable state for "llerrs" on non-release builds
@@ -10,4 +8,3 @@
 * CATZ-234: Updated FMOD Ex library to v4.44.61 (Windows)
 * CATZ-232: Updated OpenJPEG library to v1.5.2 (Windows)
 * [FIXED] Viewer fails to compile with only the Windows 8/10 SDK installed
-* [FIXED] JpegLib is built with "Whole Program Optimization" and causing slow linker performance
diff --git a/autobuild.xml b/autobuild.xml
index 7f81064379d..0f411694300 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -740,9 +740,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>601c2fc41a18812a45678ef9a87ef772</string>
+              <string>2038da4ab71da8dc086738007c0acdd3</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/1546/3486/fmodex-4.44.64.501533-windows-501533.tar.bz2</string>
+              <string>http://viewer.catznip.com/downloads/packages/fmodex-4.44.61-windows-171261212.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -752,9 +752,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>e5cde35ae26ebfa256cfe670986e152e</string>
+              <string>b4b73cd64bfd72e7ae84aad429d69cf6</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/1547/3487/fmodex-4.44.64.501533-windows64-501533.tar.bz2</string>
+              <string>http://viewer.catznip.com/downloads/packages/fmodex-4.44.61-windows64-171261211.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
diff --git a/indra/cmake/FMODEX.cmake b/indra/cmake/FMODEX.cmake
index 720933d1b79..9753412de7b 100644
--- a/indra/cmake/FMODEX.cmake
+++ b/indra/cmake/FMODEX.cmake
@@ -26,9 +26,15 @@ if (FMODEX)
       include(Prebuilt)
       use_prebuilt_binary(fmodex)    
       if (WINDOWS)
-        set(FMODEX_LIBRARY 
-            debug fmodexL_vc
-            optimized fmodex_vc)
+        if (ADDRESS_SIZE EQUAL 32)
+            set(FMODEX_LIBRARY
+                debug fmodexL_vc
+                optimized fmodex_vc)
+        else (ADDRESS_SIZE EQUAL 64)
+            set(FMODEX_LIBRARY
+                debug fmodexL64_vc
+                optimized fmodex64_vc)
+        endif (ADDRESS_SIZE EQUAL 32)
       elseif (DARWIN)
         set(FMODEX_LIBRARY 
             debug fmodexL
diff --git a/indra/cmake/FindWindowsSDK.cmake b/indra/cmake/FindWindowsSDK.cmake
index a0f4b4d3280..c536bc7a898 100644
--- a/indra/cmake/FindWindowsSDK.cmake
+++ b/indra/cmake/FindWindowsSDK.cmake
@@ -2,6 +2,10 @@
 #
 # Relevant Wikipedia article: http://en.wikipedia.org/wiki/Microsoft_Windows_SDK
 #
+# Pass "COMPONENTS tools" to ignore Visual Studio version checks: in case
+# you just want the tool binaries to run, rather than the libraries and headers
+# for compiling.
+#
 # Variables:
 #  WINDOWSSDK_FOUND - if any version of the windows or platform SDK was found that is usable with the current version of visual studio
 #  WINDOWSSDK_LATEST_DIR
@@ -17,15 +21,26 @@
 #  windowssdk_name_lookup(<directory> <output variable>) - Find the name corresponding with the SDK directory you pass in, or
 #     NOTFOUND if not recognized. Your directory must be one of WINDOWSSDK_DIRS for this to work.
 #
+#  windowssdk_build_lookup(<directory> <output variable>) - Find the build version number corresponding with the SDK directory you pass in, or
+#     NOTFOUND if not recognized. Your directory must be one of WINDOWSSDK_DIRS for this to work.
+#
 #  get_windowssdk_from_component(<file or dir> <output variable>) - Given a library or include dir,
 #     find the Windows SDK root dir corresponding to it, or NOTFOUND if unrecognized.
 #
 #  get_windowssdk_library_dirs(<directory> <output variable>) - Find the architecture-appropriate
 #     library directories corresponding to the SDK directory you pass in (or NOTFOUND if none)
 #
+#  get_windowssdk_library_dirs_multiple(<output variable> <directory> ...) - Find the architecture-appropriate
+#     library directories corresponding to the SDK directories you pass in, in order, skipping those not found. NOTFOUND if none at all.
+#     Good for passing WINDOWSSDK_DIRS or WINDOWSSDK_DIRS to if you really just want a file and don't care where from.
+#
 #  get_windowssdk_include_dirs(<directory> <output variable>) - Find the
 #     include directories corresponding to the SDK directory you pass in (or NOTFOUND if none)
 #
+#  get_windowssdk_include_dirs_multiple(<output variable> <directory> ...) - Find the
+#     include directories corresponding to the SDK directories you pass in, in order, skipping those not found. NOTFOUND if none at all.
+#     Good for passing WINDOWSSDK_DIRS or WINDOWSSDK_DIRS to if you really just want a file and don't care where from.
+#
 # Requires these CMake modules:
 #  FindPackageHandleStandardArgs (known included with CMake >=2.6.2)
 #
@@ -39,182 +54,413 @@
 # (See accompanying file LICENSE_1_0.txt or copy at
 # http://www.boost.org/LICENSE_1_0.txt)
 
-set(_preferred_sdk_dirs)
-set(_win_sdk_dirs)
-set(_win_sdk_versanddirs)
-if(MSVC_VERSION GREATER 1310) # Newer than VS .NET/VS Toolkit 2003
+set(_preferred_sdk_dirs) # pre-output
+set(_win_sdk_dirs) # pre-output
+set(_win_sdk_versanddirs) # pre-output
+set(_win_sdk_buildsanddirs) # pre-output
+set(_winsdk_vistaonly) # search parameters
+set(_winsdk_kits) # search parameters
+
+
+set(_WINDOWSSDK_ANNOUNCE OFF)
+if(NOT WINDOWSSDK_FOUND AND (NOT WindowsSDK_FIND_QUIETLY))
+	set(_WINDOWSSDK_ANNOUNCE ON)
+endif()
+macro(_winsdk_announce)
+	if(_WINSDK_ANNOUNCE)
+		message(STATUS ${ARGN})
+	endif()
+endmacro()
+
+set(_winsdk_win10vers
+	10.0.14393.0 # Redstone aka Win10 1607 "Anniversary Update"
+	10.0.10586.0 # TH2 aka Win10 1511
+	10.0.10240.0 # Win10 RTM
+	10.0.10150.0 # just ucrt
+	10.0.10056.0
+)
+
+if(WindowsSDK_FIND_COMPONENTS MATCHES "tools")
+	set(_WINDOWSSDK_IGNOREMSVC ON)
+	_winsdk_announce("Checking for tools from Windows/Platform SDKs...")
+else()
+	set(_WINDOWSSDK_IGNOREMSVC OFF)
+	_winsdk_announce("Checking for Windows/Platform SDKs...")
+endif()
+
+# Appends to the three main pre-output lists used only if the path exists
+# and is not already in the list.
+function(_winsdk_conditional_append _vername _build _path)
+	if(("${_path}" MATCHES "registry") OR (NOT EXISTS "${_path}"))
+		# Path invalid - do not add
+		return()
+	endif()
+	list(FIND _win_sdk_dirs "${_path}" _win_sdk_idx)
+	if(_win_sdk_idx GREATER -1)
+		# Path already in list - do not add
+		return()
+	endif()
+	_winsdk_announce( " - ${_vername}, Build ${_build} @ ${_path}")
+	# Not yet in the list, so we'll add it
+	list(APPEND _win_sdk_dirs "${_path}")
+	set(_win_sdk_dirs "${_win_sdk_dirs}" CACHE INTERNAL "" FORCE)
+	list(APPEND
+		_win_sdk_versanddirs
+		"${_vername}"
+		"${_path}")
+	set(_win_sdk_versanddirs "${_win_sdk_versanddirs}" CACHE INTERNAL "" FORCE)
+	list(APPEND
+		_win_sdk_buildsanddirs
+		"${_build}"
+		"${_path}")
+	set(_win_sdk_buildsanddirs "${_win_sdk_buildsanddirs}" CACHE INTERNAL "" FORCE)
+endfunction()
+
+# Appends to the "preferred SDK" lists only if the path exists
+function(_winsdk_conditional_append_preferred _info _path)
+	if(("${_path}" MATCHES "registry") OR (NOT EXISTS "${_path}"))
+		# Path invalid - do not add
+		return()
+	endif()
+
+	get_filename_component(_path "${_path}" ABSOLUTE)
+
+	list(FIND _win_sdk_preferred_sdk_dirs "${_path}" _win_sdk_idx)
+	if(_win_sdk_idx GREATER -1)
+		# Path already in list - do not add
+		return()
+	endif()
+	_winsdk_announce( " - Found \"preferred\" SDK ${_info} @ ${_path}")
+	# Not yet in the list, so we'll add it
+	list(APPEND _win_sdk_preferred_sdk_dirs "${_path}")
+	set(_win_sdk_preferred_sdk_dirs "${_win_sdk_dirs}" CACHE INTERNAL "" FORCE)
+
+	# Just in case we somehow missed it:
+	_winsdk_conditional_append("${_info}" "" "${_path}")
+endfunction()
+
+# Given a version like v7.0A, looks for an SDK in the registry under "Microsoft SDKs".
+# If the given version might be in both HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows
+# and HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots aka "Windows Kits",
+# use this macro first, since these registry keys usually have more information.
+#
+# Pass a "default" build number as an extra argument in case we can't find it.
+function(_winsdk_check_microsoft_sdks_registry _winsdkver)
+	set(SDKKEY "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\${_winsdkver}")
+	get_filename_component(_sdkdir
+		"[${SDKKEY};InstallationFolder]"
+		ABSOLUTE)
+
+	set(_sdkname "Windows SDK ${_winsdkver}")
+
+	# Default build number passed as extra argument
+	set(_build ${ARGN})
+	# See if the registry holds a Microsoft-mutilated, err, designated, product name
+	# (just using get_filename_component to execute the registry lookup)
+	get_filename_component(_sdkproductname
+		"[${SDKKEY};ProductName]"
+		NAME)
+	if(NOT "${_sdkproductname}" MATCHES "registry")
+		# Got a product name
+		set(_sdkname "${_sdkname} (${_sdkproductname})")
+	endif()
+
+	# try for a version to augment our name
+	# (just using get_filename_component to execute the registry lookup)
+	get_filename_component(_sdkver
+		"[${SDKKEY};ProductVersion]"
+		NAME)
+	if(NOT "${_sdkver}" MATCHES "registry" AND NOT MATCHES)
+		# Got a version
+		if(NOT "${_sdkver}" MATCHES "\\.\\.")
+			# and it's not an invalid one with two dots in it:
+			# use to override the default build
+			set(_build ${_sdkver})
+			if(NOT "${_sdkname}" MATCHES "${_sdkver}")
+				# Got a version that's not already in the name, let's use it to improve our name.
+				set(_sdkname "${_sdkname} (${_sdkver})")
+			endif()
+		endif()
+	endif()
+	_winsdk_conditional_append("${_sdkname}" "${_build}" "${_sdkdir}")
+endfunction()
+
+# Given a name for identification purposes, the build number, and a key (technically a "value name")
+# corresponding to a Windows SDK packaged as a "Windows Kit", look for it
+# in HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots
+# Note that the key or "value name" tends to be something weird like KitsRoot81 -
+# no easy way to predict, just have to observe them in the wild.
+# Doesn't hurt to also try _winsdk_check_microsoft_sdks_registry for these:
+# sometimes you get keys in both parts of the registry (in the wow64 portion especially),
+# and the non-"Windows Kits" location is often more descriptive.
+function(_winsdk_check_windows_kits_registry _winkit_name _winkit_build _winkit_key)
+	get_filename_component(_sdkdir
+		"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots;${_winkit_key}]"
+		ABSOLUTE)
+	_winsdk_conditional_append("${_winkit_name}" "${_winkit_build}" "${_sdkdir}")
+endfunction()
+
+# Given a name for identification purposes and the build number
+# corresponding to a Windows 10 SDK packaged as a "Windows Kit", look for it
+# in HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots
+# Doesn't hurt to also try _winsdk_check_microsoft_sdks_registry for these:
+# sometimes you get keys in both parts of the registry (in the wow64 portion especially),
+# and the non-"Windows Kits" location is often more descriptive.
+function(_winsdk_check_win10_kits _winkit_build)
+	get_filename_component(_sdkdir
+		"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots;KitsRoot10]"
+		ABSOLUTE)
+	if(("${_sdkdir}" MATCHES "registry") OR (NOT EXISTS "${_sdkdir}"))
+		return() # not found
+	endif()
+	if(EXISTS "${_sdkdir}/Include/${_winkit_build}/um")
+		_winsdk_conditional_append("Windows Kits 10 (Build ${_winkit_build})" "${_winkit_build}" "${_sdkdir}")
+	endif()
+endfunction()
+
+# Given a name for indentification purposes, the build number, and the associated package GUID,
+# look in the registry under both HKLM and HKCU in \\SOFTWARE\\Microsoft\\MicrosoftSDK\\InstalledSDKs\\
+# for that guid and the SDK it points to.
+function(_winsdk_check_platformsdk_registry _platformsdkname _build _platformsdkguid)
+	foreach(_winsdk_hive HKEY_LOCAL_MACHINE HKEY_CURRENT_USER)
+		get_filename_component(_sdkdir
+			"[${_winsdk_hive}\\SOFTWARE\\Microsoft\\MicrosoftSDK\\InstalledSDKs\\${_platformsdkguid};Install Dir]"
+			ABSOLUTE)
+		_winsdk_conditional_append("${_platformsdkname} (${_build})" "${_build}" "${_sdkdir}")
+	endforeach()
+endfunction()
+
+###
+# Detect toolchain information: to know whether it's OK to use Vista+ only SDKs
+###
+set(_winsdk_vistaonly_ok OFF)
+if(MSVC AND NOT _WINDOWSSDK_IGNOREMSVC)
+	# VC 10 and older has broad target support
+	if(MSVC_VERSION LESS 1700)
+		# VC 11 by default targets Vista and later only, so we can add a few more SDKs that (might?) only work on vista+
+	elseif("${CMAKE_VS_PLATFORM_TOOLSET}" MATCHES "_xp")
+		# This is the XP-compatible v110+ toolset
+	elseif("${CMAKE_VS_PLATFORM_TOOLSET}" STREQUAL "v100" OR "${CMAKE_VS_PLATFORM_TOOLSET}" STREQUAL "v90")
+		# This is the VS2010/VS2008 toolset
+	else()
+		# OK, we're VC11 or newer and not using a backlevel or XP-compatible toolset.
+		# These versions have no XP (and possibly Vista pre-SP1) support
+		set(_winsdk_vistaonly_ok ON)
+		if(_WINDOWSSDK_ANNOUNCE AND NOT _WINDOWSSDK_VISTAONLY_PESTERED)
+			set(_WINDOWSSDK_VISTAONLY_PESTERED ON CACHE INTERNAL "" FORCE)
+			message(STATUS "FindWindowsSDK: Detected Visual Studio 2012 or newer, not using the _xp toolset variant: including SDK versions that drop XP support in search!")
+		endif()
+	endif()
+endif()
+if(_WINDOWSSDK_IGNOREMSVC)
+	set(_winsdk_vistaonly_ok ON)
+endif()
+
+###
+# MSVC version checks - keeps messy conditionals in one place
+# (messy because of _WINDOWSSDK_IGNOREMSVC)
+###
+set(_winsdk_msvc_greater_1200 OFF)
+if(_WINDOWSSDK_IGNOREMSVC OR (MSVC AND (MSVC_VERSION GREATER 1200)))
+	set(_winsdk_msvc_greater_1200 ON)
+endif()
+# Newer than VS .NET/VS Toolkit 2003
+set(_winsdk_msvc_greater_1310 OFF)
+if(_WINDOWSSDK_IGNOREMSVC OR (MSVC AND (MSVC_VERSION GREATER 1310)))
+	set(_winsdk_msvc_greater_1310 ON)
+endif()
+
+# VS2005/2008
+set(_winsdk_msvc_less_1600 OFF)
+if(_WINDOWSSDK_IGNOREMSVC OR (MSVC AND (MSVC_VERSION LESS 1600)))
+	set(_winsdk_msvc_less_1600 ON)
+endif()
+
+# VS2013+
+set(_winsdk_msvc_not_less_1800 OFF)
+if(_WINDOWSSDK_IGNOREMSVC OR (MSVC AND (NOT MSVC_VERSION LESS 1800)))
+	set(_winsdk_msvc_not_less_1800 ON)
+endif()
+
+###
+# START body of find module
+###
+if(_winsdk_msvc_greater_1310) # Newer than VS .NET/VS Toolkit 2003
+	###
+	# Look for "preferred" SDKs
+	###
 
 	# Environment variable for SDK dir
 	if(EXISTS "$ENV{WindowsSDKDir}" AND (NOT "$ENV{WindowsSDKDir}" STREQUAL ""))
-		message(STATUS "Got $ENV{WindowsSDKDir} - Windows/Platform SDK directories: ${_win_sdk_dirs}")
-		list(APPEND _preferred_sdk_dirs "$ENV{WindowsSDKDir}")
+		_winsdk_conditional_append_preferred("WindowsSDKDir environment variable" "$ENV{WindowsSDKDir}")
 	endif()
 
-	if(MSVC_VERSION LESS 1600)
+	if(_winsdk_msvc_less_1600)
 		# Per-user current Windows SDK for VS2005/2008
 		get_filename_component(_sdkdir
 			"[HKEY_CURRENT_USER\\Software\\Microsoft\\Microsoft SDKs\\Windows;CurrentInstallFolder]"
 			ABSOLUTE)
-		if(EXISTS "${_sdkdir}")
-			list(APPEND _preferred_sdk_dirs "${_sdkdir}")
-		endif()
+		_winsdk_conditional_append_preferred("Per-user current Windows SDK" "${_sdkdir}")
 
 		# System-wide current Windows SDK for VS2005/2008
 		get_filename_component(_sdkdir
 			"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows;CurrentInstallFolder]"
 			ABSOLUTE)
-		if(EXISTS "${_sdkdir}")
-			list(APPEND _preferred_sdk_dirs "${_sdkdir}")
-		endif()
+		_winsdk_conditional_append_preferred("System-wide current Windows SDK" "${_sdkdir}")
 	endif()
 
-	if(MSVC_VERSION LESS 1700)
-		# VC 10 and older has broad target support
-		set(_winsdk_vistaonly)
-	else()
-		# VC 11 by default targets Vista and later only, so we can add a few more SDKs that (might?) only work on vista+
-		if("${CMAKE_VS_PLATFORM_TOOLSET}" MATCHES "_xp")
-			# This is the XP-compatible v110 toolset
-		elseif("${CMAKE_VS_PLATFORM_TOOLSET}" STREQUAL "v100")
-			# This is the VS2010 toolset
-		else()
-			#if(NOT WINDOWSSDK_FOUND AND NOT WindowsSDK_FIND_QUIETLY)
-			#	message(STATUS "FindWindowsSDK: Detected Visual Studio 2012 or newer, not using the _xp toolset variant: including SDK versions that drop XP support in search!")
-			#endif()
-			# These versions have no XP (and possibly Vista pre-SP1) support
-			set(_winsdk_vistaonly)
-			if(NOT MSVC_VERSION LESS 1800)
-				list(APPEND _winsdk_vistaonly
-					# Windows Software Development Kit (SDK) for Windows 8.1
-					# http://msdn.microsoft.com/en-gb/windows/desktop/bg162891
-					v8.1)
-			endif()
-			list(APPEND _winsdk_vistaonly
-				# Included in Visual Studio 2012
-				v8.0A
-
-				# Microsoft Windows SDK for Windows 8 and .NET Framework 4.5
-				# This is the first version to also include the DirectX SDK
-				# http://msdn.microsoft.com/en-US/windows/desktop/hh852363.aspx
-				v8.0
-
-				# Microsoft Windows SDK for Windows 7 and .NET Framework 4
-				# http://www.microsoft.com/downloads/en/details.aspx?FamilyID=6b6c21d2-2006-4afa-9702-529fa782d63b
-				v7.1
-				)
-		endif()
-	endif()
-	foreach(_winsdkver
-		${_winsdk_vistaonly}
+	###
+	# Begin the massive list of SDK searching!
+	###
+	if(_winsdk_vistaonly_ok AND _winsdk_msvc_not_less_1800)
+		# These require at least Visual Studio 2013 (VC12)
+
+		_winsdk_check_microsoft_sdks_registry(v10.0A)
+
+		# Windows Software Development Kit (SDK) for Windows 10
+		# Several different versions living in the same directory - if nothing else we can assume RTM (10240)
+		_winsdk_check_microsoft_sdks_registry(v10.0 10.0.10240.0)
+		foreach(_win10build ${_winsdk_win10vers})
+			_winsdk_check_win10_kits(${_win10build})
+		endforeach()
+	endif() # vista-only and 2013+
 
-		# Included in Visual Studio 2013
-		# Includes the v120_xp toolset
-		v8.1A
+	# Included in Visual Studio 2013
+	# Includes the v120_xp toolset
+	_winsdk_check_microsoft_sdks_registry(v8.1A 8.1.51636)
 
-		# Included with VS 2012 Update 1 or later
-		# Introduces v110_xp toolset
-		v7.1A
+	if(_winsdk_vistaonly_ok AND _winsdk_msvc_not_less_1800)
+		# Windows Software Development Kit (SDK) for Windows 8.1
+		# http://msdn.microsoft.com/en-gb/windows/desktop/bg162891
+		_winsdk_check_microsoft_sdks_registry(v8.1 8.1.25984.0)
+		_winsdk_check_windows_kits_registry("Windows Kits 8.1" 8.1.25984.0 KitsRoot81)
+	endif() # vista-only and 2013+
 
-		# Included with VS 2010
-		v7.0A
+	if(_winsdk_vistaonly_ok)
+		# Included in Visual Studio 2012
+		_winsdk_check_microsoft_sdks_registry(v8.0A 8.0.50727)
 
-		# Windows SDK for Windows 7 and .NET Framework 3.5 SP1
-		# Works with VC9
-		#http://www.microsoft.com/en-us/download/details.aspx?id=18950
-		v7.0
+		# Microsoft Windows SDK for Windows 8 and .NET Framework 4.5
+		# This is the first version to also include the DirectX SDK
+		# http://msdn.microsoft.com/en-US/windows/desktop/hh852363.aspx
+		_winsdk_check_microsoft_sdks_registry(v8.0 6.2.9200.16384)
+		_winsdk_check_windows_kits_registry("Windows Kits 8.0" 6.2.9200.16384 KitsRoot)
+	endif() # vista-only
 
-		# Two versions call themselves "v6.1":
-		# Older:
-		# Windows Vista Update & .NET 3.0 SDK
-		# http://www.microsoft.com/en-us/download/details.aspx?id=14477
+	# Included with VS 2012 Update 1 or later
+	# Introduces v110_xp toolset
+	_winsdk_check_microsoft_sdks_registry(v7.1A 7.1.51106)
+	if(_winsdk_vistaonly_ok)
+		# Microsoft Windows SDK for Windows 7 and .NET Framework 4
+		# http://www.microsoft.com/downloads/en/details.aspx?FamilyID=6b6c21d2-2006-4afa-9702-529fa782d63b
+		_winsdk_check_microsoft_sdks_registry(v7.1 7.1.7600.0.30514)
+	endif() # vista-only
 
-		# Newer:
-		# Windows Server 2008 & .NET 3.5 SDK
-		# may have broken VS9SP1? they recommend v7.0 instead, or a KB...
-		# http://www.microsoft.com/en-us/download/details.aspx?id=24826
-		v6.1
+	# Included with VS 2010
+	_winsdk_check_microsoft_sdks_registry(v7.0A 6.1.7600.16385)
 
-		# Included in VS 2008
-		v6.0A
+	# Windows SDK for Windows 7 and .NET Framework 3.5 SP1
+	# Works with VC9
+	# http://www.microsoft.com/en-us/download/details.aspx?id=18950
+	_winsdk_check_microsoft_sdks_registry(v7.0 6.1.7600.16385)
 
-		# Microsoft Windows Software Development Kit for Windows Vista and .NET Framework 3.0 Runtime Components
-		# http://blogs.msdn.com/b/stanley/archive/2006/11/08/microsoft-windows-software-development-kit-for-windows-vista-and-net-framework-3-0-runtime-components.aspx
-		v6.0)
+	# Two versions call themselves "v6.1":
+	# Older:
+	# Windows Vista Update & .NET 3.0 SDK
+	# http://www.microsoft.com/en-us/download/details.aspx?id=14477
+
+	# Newer:
+	# Windows Server 2008 & .NET 3.5 SDK
+	# may have broken VS9SP1? they recommend v7.0 instead, or a KB...
+	# http://www.microsoft.com/en-us/download/details.aspx?id=24826
+	_winsdk_check_microsoft_sdks_registry(v6.1 6.1.6000.16384.10)
+
+	# Included in VS 2008
+	_winsdk_check_microsoft_sdks_registry(v6.0A 6.1.6723.1)
+
+	# Microsoft Windows Software Development Kit for Windows Vista and .NET Framework 3.0 Runtime Components
+	# http://blogs.msdn.com/b/stanley/archive/2006/11/08/microsoft-windows-software-development-kit-for-windows-vista-and-net-framework-3-0-runtime-components.aspx
+	_winsdk_check_microsoft_sdks_registry(v6.0 6.0.6000.16384)
+endif()
 
+# Let's not forget the Platform SDKs, which sometimes are useful!
+if(_winsdk_msvc_greater_1200)
+	_winsdk_check_platformsdk_registry("Microsoft Platform SDK for Windows Server 2003 R2" "5.2.3790.2075.51" "D2FF9F89-8AA2-4373-8A31-C838BF4DBBE1")
+	_winsdk_check_platformsdk_registry("Microsoft Platform SDK for Windows Server 2003 SP1" "5.2.3790.1830.15" "8F9E5EF3-A9A5-491B-A889-C58EFFECE8B3")
+endif()
+###
+# Finally, look for "preferred" SDKs
+###
+if(_winsdk_msvc_greater_1310) # Newer than VS .NET/VS Toolkit 2003
+
+
+	# Environment variable for SDK dir
+	if(EXISTS "$ENV{WindowsSDKDir}" AND (NOT "$ENV{WindowsSDKDir}" STREQUAL ""))
+		_winsdk_conditional_append_preferred("WindowsSDKDir environment variable" "$ENV{WindowsSDKDir}")
+	endif()
+
+	if(_winsdk_msvc_less_1600)
+		# Per-user current Windows SDK for VS2005/2008
 		get_filename_component(_sdkdir
-			"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\${_winsdkver};InstallationFolder]"
+			"[HKEY_CURRENT_USER\\Software\\Microsoft\\Microsoft SDKs\\Windows;CurrentInstallFolder]"
 			ABSOLUTE)
-		if(EXISTS "${_sdkdir}")
-			list(APPEND _win_sdk_dirs "${_sdkdir}")
-			list(APPEND
-				_win_sdk_versanddirs
-				"Windows SDK ${_winsdkver}"
-				"${_sdkdir}")
-		endif()
-	endforeach()
-endif()
-if(MSVC_VERSION GREATER 1200)
-	foreach(_platformsdkinfo
-		"D2FF9F89-8AA2-4373-8A31-C838BF4DBBE1_Microsoft Platform SDK for Windows Server 2003 R2"
-		"8F9E5EF3-A9A5-491B-A889-C58EFFECE8B3_Microsoft Platform SDK for Windows Server 2003 SP1")
-		string(SUBSTRING "${_platformsdkinfo}" 0 36 _platformsdkguid)
-		string(SUBSTRING "${_platformsdkinfo}" 37 -1 _platformsdkname)
-		foreach(HIVE HKEY_LOCAL_MACHINE HKEY_CURRENT_USER)
-			get_filename_component(_sdkdir
-				"[${HIVE}\\SOFTWARE\\Microsoft\\MicrosoftSDK\\InstalledSDKs\\${_platformsdkguid};Install Dir]"
-				ABSOLUTE)
-			if(EXISTS "${_sdkdir}")
-				list(APPEND _win_sdk_dirs "${_sdkdir}")
-				list(APPEND _win_sdk_versanddirs "${_platformsdkname}" "${_sdkdir}")
-			endif()
-		endforeach()
-	endforeach()
+		_winsdk_conditional_append_preferred("Per-user current Windows SDK" "${_sdkdir}")
+
+		# System-wide current Windows SDK for VS2005/2008
+		get_filename_component(_sdkdir
+			"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows;CurrentInstallFolder]"
+			ABSOLUTE)
+		_winsdk_conditional_append_preferred("System-wide current Windows SDK" "${_sdkdir}")
+	endif()
 endif()
 
-set(_win_sdk_versanddirs
-	"${_win_sdk_versanddirs}"
-	CACHE
-	INTERNAL
-	"mapping between windows sdk version locations and names"
-	FORCE)
 
 function(windowssdk_name_lookup _dir _outvar)
 	list(FIND _win_sdk_versanddirs "${_dir}" _diridx)
-	math(EXPR _nameidx "${_diridx} - 1")
-	if(${_nameidx} GREATER -1)
-		list(GET _win_sdk_versanddirs ${_nameidx} _sdkname)
+	math(EXPR _idx "${_diridx} - 1")
+	if(${_idx} GREATER -1)
+		list(GET _win_sdk_versanddirs ${_idx} _ret)
+	else()
+		set(_ret "NOTFOUND")
+	endif()
+	set(${_outvar} "${_ret}" PARENT_SCOPE)
+endfunction()
+
+function(windowssdk_build_lookup _dir _outvar)
+	list(FIND _win_sdk_buildsanddirs "${_dir}" _diridx)
+	math(EXPR _idx "${_diridx} - 1")
+	if(${_idx} GREATER -1)
+		list(GET _win_sdk_buildsanddirs ${_idx} _ret)
 	else()
-		set(_sdkname "NOTFOUND")
+		set(_ret "NOTFOUND")
 	endif()
-	set(${_outvar} "${_sdkname}" PARENT_SCOPE)
+	set(${_outvar} "${_ret}" PARENT_SCOPE)
 endfunction()
 
+# If we found something...
 if(_win_sdk_dirs)
-	# Remove duplicates
-	list(REMOVE_DUPLICATES _win_sdk_dirs)
 	list(GET _win_sdk_dirs 0 WINDOWSSDK_LATEST_DIR)
 	windowssdk_name_lookup("${WINDOWSSDK_LATEST_DIR}"
 		WINDOWSSDK_LATEST_NAME)
 	set(WINDOWSSDK_DIRS ${_win_sdk_dirs})
+
+	# Fallback, in case no preference found.
+	set(WINDOWSSDK_PREFERRED_DIR "${WINDOWSSDK_LATEST_DIR}")
+	set(WINDOWSSDK_PREFERRED_NAME "${WINDOWSSDK_LATEST_NAME}")
+	set(WINDOWSSDK_PREFERRED_FIRST_DIRS ${WINDOWSSDK_DIRS})
+	set(WINDOWSSDK_FOUND_PREFERENCE OFF)
 endif()
-if(_preferred_sdk_dirs)
-	list(GET _preferred_sdk_dirs 0 WINDOWSSDK_PREFERRED_DIR)
-	windowssdk_name_lookup("${WINDOWSSDK_LATEST_DIR}"
+
+# If we found indications of a user preference...
+if(_win_sdk_preferred_sdk_dirs)
+	list(GET _win_sdk_preferred_sdk_dirs 0 WINDOWSSDK_PREFERRED_DIR)
+	windowssdk_name_lookup("${WINDOWSSDK_PREFERRED_DIR}"
 		WINDOWSSDK_PREFERRED_NAME)
 	set(WINDOWSSDK_PREFERRED_FIRST_DIRS
-		${_preferred_sdk_dirs}
+		${_win_sdk_preferred_sdk_dirs}
 		${_win_sdk_dirs})
 	list(REMOVE_DUPLICATES WINDOWSSDK_PREFERRED_FIRST_DIRS)
 	set(WINDOWSSDK_FOUND_PREFERENCE ON)
-
-	# In case a preferred dir was found that isn't found otherwise
-	#set(WINDOWSSDK_DIRS ${WINDOWSSDK_DIRS} ${WINDOWSSDK_PREFERRED_FIRST_DIRS})
-	#list(REMOVE_DUPLICATES WINDOWSSDK_DIRS)
-else()
-	set(WINDOWSSDK_PREFERRED_DIR "${WINDOWSSDK_LATEST_DIR}")
-	set(WINDOWSSDK_PREFERRED_NAME "${WINDOWSSDK_LATEST_NAME}")
-	set(WINDOWSSDK_PREFERRED_FIRST_DIRS ${WINDOWSSDK_DIRS})
-	set(WINDOWSSDK_FOUND_PREFERENCE OFF)
 endif()
 
 include(FindPackageHandleStandardArgs)
@@ -223,26 +469,16 @@ find_package_handle_standard_args(WindowsSDK
 	WINDOWSSDK_DIRS)
 
 if(WINDOWSSDK_FOUND)
-	if(NOT _winsdk_remembered_dirs STREQUAL WINDOWSSDK_DIRS)
-		set(_winsdk_remembered_dirs
-			"${WINDOWSSDK_DIRS}"
-			CACHE
-			INTERNAL
-			""
-			FORCE)
-		if(NOT WindowsSDK_FIND_QUIETLY)
-			foreach(_sdkdir ${WINDOWSSDK_DIRS})
-				windowssdk_name_lookup("${_sdkdir}" _sdkname)
-				message(STATUS " - Found ${_sdkname} at ${_sdkdir}")
-			endforeach()
-		endif()
-	endif()
-
 	# Internal: Architecture-appropriate library directory names.
 	if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "ARM")
-		set(_winsdk_archbare /arm) # what the architecture used to be called in oldest SDKs
-		set(_winsdk_arch arm) # what the architecture used to be called
-		set(_winsdk_arch8 arm) # what the WDK for Win8+ calls this architecture
+		if(CMAKE_SIZEOF_VOID_P MATCHES "8")
+			# Only supported in Win10 SDK and up.
+			set(_winsdk_arch8 arm64) # what the WDK for Win8+ calls this architecture
+		else()
+			set(_winsdk_archbare /arm) # what the architecture used to be called in oldest SDKs
+			set(_winsdk_arch arm) # what the architecture used to be called
+			set(_winsdk_arch8 arm) # what the WDK for Win8+ calls this architecture
+		endif()
 	else()
 		if(CMAKE_SIZEOF_VOID_P MATCHES "8")
 			set(_winsdk_archbare /x64) # what the architecture used to be called in oldest SDKs
@@ -272,51 +508,119 @@ if(WINDOWSSDK_FOUND)
 		set(${_var} "NOTFOUND" PARENT_SCOPE)
 	endfunction()
 	function(get_windowssdk_library_dirs _winsdk_dir _var)
-		set(_result)
-		foreach(_suffix
+		set(_dirs)
+		set(_suffixes
 			"lib${_winsdk_archbare}" # SDKs like 7.1A
+			"lib/${_winsdk_arch}" # just because some SDKs have x86 dir and root dir
 			"lib/w2k/${_winsdk_arch}" # Win2k min requirement
 			"lib/wxp/${_winsdk_arch}" # WinXP min requirement
 			"lib/wnet/${_winsdk_arch}" # Win Server 2003 min requirement
-			"lib/wlh/${_winsdk_arch}" # Win Vista ("Long Horn") min requirement
+			"lib/wlh/${_winsdk_arch}"
 			"lib/wlh/um/${_winsdk_arch8}" # Win Vista ("Long Horn") min requirement
-			"lib/win7/${_winsdk_arch}" # Win 7 min requirement
+			"lib/win7/${_winsdk_arch}"
 			"lib/win7/um/${_winsdk_arch8}" # Win 7 min requirement
-			"lib/win8/um/${_winsdk_arch8}" # Win 8 min requirement
-			"lib/win8/km/${_winsdk_arch8}" # Win 8 min requirement
-			"lib/winv6.3/km/${_winsdk_arch8}" # Win 8.1 min requirement
-			"lib/winv6.3/um/${_winsdk_arch8}" # Win 8.1 min requirement
 		)
+		foreach(_ver
+			wlh # Win Vista ("Long Horn") min requirement
+			win7 # Win 7 min requirement
+			win8 # Win 8 min requirement
+			winv6.3 # Win 8.1 min requirement
+		)
+
+			list(APPEND _suffixes
+				"lib/${_ver}/${_winsdk_arch}"
+				"lib/${_ver}/um/${_winsdk_arch8}"
+				"lib/${_ver}/km/${_winsdk_arch8}"
+			)
+		endforeach()
+
+		# Look for WDF libraries in Win10+ SDK
+		foreach(_mode umdf kmdf)
+			file(GLOB _wdfdirs RELATIVE "${_winsdk_dir}" "${_winsdk_dir}/lib/wdf/${_mode}/${_winsdk_arch8}/*")
+			if(_wdfdirs)
+				list(APPEND _suffixes ${_wdfdirs})
+			endif()
+		endforeach()
+
+		# Look in each Win10+ SDK version for the components
+		foreach(_win10ver ${_winsdk_win10vers})
+			foreach(_component um km ucrt mmos)
+				list(APPEND _suffixes "lib/${_win10ver}/${_component}/${_winsdk_arch8}")
+			endforeach()
+		endforeach()
+
+		foreach(_suffix ${_suffixes})
 			# Check to see if a library actually exists here.
 			file(GLOB _libs "${_winsdk_dir}/${_suffix}/*.lib")
 			if(_libs)
-				list(APPEND _result "${_winsdk_dir}/${_suffix}")
+				list(APPEND _dirs "${_winsdk_dir}/${_suffix}")
 			endif()
 		endforeach()
-		if(NOT _result)
-			set(_result NOTFOUND)
+		if("${_dirs}" STREQUAL "")
+			set(_dirs NOTFOUND)
+		else()
+			list(REMOVE_DUPLICATES _dirs)
 		endif()
-		set(${_var} ${_result} PARENT_SCOPE)
+		set(${_var} ${_dirs} PARENT_SCOPE)
 	endfunction()
 	function(get_windowssdk_include_dirs _winsdk_dir _var)
-		set(_result)
-		foreach(_suffix
-			"Include"
-			"Include/shared"
-			"Include/um"
-			"Include/winrt"
-			"Include/km"
-			"Include/wdf"
-		)
+		set(_dirs)
+
+		set(_subdirs shared um winrt km wdf mmos ucrt)
+		set(_suffixes Include)
+
+		foreach(_dir ${_subdirs})
+			list(APPEND _suffixes "Include/${_dir}")
+		endforeach()
+
+		foreach(_ver ${_winsdk_win10vers})
+			foreach(_dir ${_subdirs})
+				list(APPEND _suffixes "Include/${_ver}/${_dir}")
+			endforeach()
+		endforeach()
+
+		foreach(_suffix ${_suffixes})
 			# Check to see if a header file actually exists here.
 			file(GLOB _headers "${_winsdk_dir}/${_suffix}/*.h")
 			if(_headers)
-				list(APPEND _result "${_winsdk_dir}/${_suffix}")
+				list(APPEND _dirs "${_winsdk_dir}/${_suffix}")
 			endif()
 		endforeach()
-		if(NOT _result)
-			set(_result NOTFOUND)
+		if("${_dirs}" STREQUAL "")
+			set(_dirs NOTFOUND)
+		else()
+			list(REMOVE_DUPLICATES _dirs)
 		endif()
-		set(${_var} ${_result} PARENT_SCOPE)
+		set(${_var} ${_dirs} PARENT_SCOPE)
 	endfunction()
-endif()
+	function(get_windowssdk_library_dirs_multiple _var)
+		set(_dirs)
+		foreach(_sdkdir ${ARGN})
+			get_windowssdk_library_dirs("${_sdkdir}" _current_sdk_libdirs)
+			if(_current_sdk_libdirs)
+				list(APPEND _dirs ${_current_sdk_libdirs})
+			endif()
+		endforeach()
+		if("${_dirs}" STREQUAL "")
+			set(_dirs NOTFOUND)
+		else()
+			list(REMOVE_DUPLICATES _dirs)
+		endif()
+		set(${_var} ${_dirs} PARENT_SCOPE)
+	endfunction()
+	function(get_windowssdk_include_dirs_multiple _var)
+		set(_dirs)
+		foreach(_sdkdir ${ARGN})
+			get_windowssdk_include_dirs("${_sdkdir}" _current_sdk_incdirs)
+			if(_current_sdk_libdirs)
+				list(APPEND _dirs ${_current_sdk_incdirs})
+			endif()
+		endforeach()
+		if("${_dirs}" STREQUAL "")
+			set(_dirs NOTFOUND)
+		else()
+			list(REMOVE_DUPLICATES _dirs)
+		endif()
+		set(${_var} ${_dirs} PARENT_SCOPE)
+	endfunction()
+endif()
\ No newline at end of file
-- 
GitLab