1# - Find the Windows SDK aka Platform SDK 2# 3# Relevant Wikipedia article: http://en.wikipedia.org/wiki/Microsoft_Windows_SDK 4# 5# Pass "COMPONENTS tools" to ignore Visual Studio version checks: in case 6# you just want the tool binaries to run, rather than the libraries and headers 7# for compiling. 8# 9# Variables: 10# WINDOWSSDK_FOUND - if any version of the windows or platform SDK was found that is usable with the current version of visual studio 11# WINDOWSSDK_LATEST_DIR 12# WINDOWSSDK_LATEST_NAME 13# WINDOWSSDK_FOUND_PREFERENCE - if we found an entry indicating a "preferred" SDK listed for this visual studio version 14# WINDOWSSDK_PREFERRED_DIR 15# WINDOWSSDK_PREFERRED_NAME 16# 17# WINDOWSSDK_DIRS - contains no duplicates, ordered most recent first. 18# WINDOWSSDK_PREFERRED_FIRST_DIRS - contains no duplicates, ordered with preferred first, followed by the rest in descending recency 19# 20# Functions: 21# windowssdk_name_lookup(<directory> <output variable>) - Find the name corresponding with the SDK directory you pass in, or 22# NOTFOUND if not recognized. Your directory must be one of WINDOWSSDK_DIRS for this to work. 23# 24# windowssdk_build_lookup(<directory> <output variable>) - Find the build version number corresponding with the SDK directory you pass in, or 25# NOTFOUND if not recognized. Your directory must be one of WINDOWSSDK_DIRS for this to work. 26# 27# get_windowssdk_from_component(<file or dir> <output variable>) - Given a library or include dir, 28# find the Windows SDK root dir corresponding to it, or NOTFOUND if unrecognized. 29# 30# get_windowssdk_library_dirs(<directory> <output variable>) - Find the architecture-appropriate 31# library directories corresponding to the SDK directory you pass in (or NOTFOUND if none) 32# 33# get_windowssdk_library_dirs_multiple(<output variable> <directory> ...) - Find the architecture-appropriate 34# library directories corresponding to the SDK directories you pass in, in order, skipping those not found. NOTFOUND if none at all. 35# Good for passing WINDOWSSDK_DIRS or WINDOWSSDK_DIRS to if you really just want a file and don't care where from. 36# 37# get_windowssdk_include_dirs(<directory> <output variable>) - Find the 38# include directories corresponding to the SDK directory you pass in (or NOTFOUND if none) 39# 40# get_windowssdk_include_dirs_multiple(<output variable> <directory> ...) - Find the 41# include directories corresponding to the SDK directories you pass in, in order, skipping those not found. NOTFOUND if none at all. 42# Good for passing WINDOWSSDK_DIRS or WINDOWSSDK_DIRS to if you really just want a file and don't care where from. 43# 44# Requires these CMake modules: 45# FindPackageHandleStandardArgs (known included with CMake >=2.6.2) 46# 47# Original Author: 48# 2012 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net> 49# http://academic.cleardefinition.com 50# Iowa State University HCI Graduate Program/VRAC 51# 52# Copyright Iowa State University 2012. 53# Distributed under the Boost Software License, Version 1.0. 54# (See accompanying file LICENSE_1_0.txt or copy at 55# http://www.boost.org/LICENSE_1_0.txt) 56 57set(_preferred_sdk_dirs) # pre-output 58set(_win_sdk_dirs) # pre-output 59set(_win_sdk_versanddirs) # pre-output 60set(_win_sdk_buildsanddirs) # pre-output 61set(_winsdk_vistaonly) # search parameters 62set(_winsdk_kits) # search parameters 63 64 65set(_WINDOWSSDK_ANNOUNCE OFF) 66if(NOT WINDOWSSDK_FOUND AND (NOT WindowsSDK_FIND_QUIETLY)) 67 set(_WINDOWSSDK_ANNOUNCE ON) 68endif() 69macro(_winsdk_announce) 70 if(_WINSDK_ANNOUNCE) 71 message(STATUS ${ARGN}) 72 endif() 73endmacro() 74 75set(_winsdk_win10vers 76 10.0.10586.0 # TH2 aka Win10 1511 77 10.0.10240.0 # Win10 RTM 78 10.0.10150.0 # just ucrt 79 10.0.10056.0 80) 81 82if(WindowsSDK_FIND_COMPONENTS MATCHES "tools") 83 set(_WINDOWSSDK_IGNOREMSVC ON) 84 _winsdk_announce("Checking for tools from Windows/Platform SDKs...") 85else() 86 set(_WINDOWSSDK_IGNOREMSVC OFF) 87 _winsdk_announce("Checking for Windows/Platform SDKs...") 88endif() 89 90# Appends to the three main pre-output lists used only if the path exists 91# and is not already in the list. 92function(_winsdk_conditional_append _vername _build _path) 93 if(("${_path}" MATCHES "registry") OR (NOT EXISTS "${_path}")) 94 # Path invalid - do not add 95 return() 96 endif() 97 list(FIND _win_sdk_dirs "${_path}" _win_sdk_idx) 98 if(_win_sdk_idx GREATER -1) 99 # Path already in list - do not add 100 return() 101 endif() 102 _winsdk_announce( " - ${_vername}, Build ${_build} @ ${_path}") 103 # Not yet in the list, so we'll add it 104 list(APPEND _win_sdk_dirs "${_path}") 105 set(_win_sdk_dirs "${_win_sdk_dirs}" CACHE INTERNAL "" FORCE) 106 list(APPEND 107 _win_sdk_versanddirs 108 "${_vername}" 109 "${_path}") 110 set(_win_sdk_versanddirs "${_win_sdk_versanddirs}" CACHE INTERNAL "" FORCE) 111 list(APPEND 112 _win_sdk_buildsanddirs 113 "${_build}" 114 "${_path}") 115 set(_win_sdk_buildsanddirs "${_win_sdk_buildsanddirs}" CACHE INTERNAL "" FORCE) 116endfunction() 117 118# Appends to the "preferred SDK" lists only if the path exists 119function(_winsdk_conditional_append_preferred _info _path) 120 if(("${_path}" MATCHES "registry") OR (NOT EXISTS "${_path}")) 121 # Path invalid - do not add 122 return() 123 endif() 124 125 get_filename_component(_path "${_path}" ABSOLUTE) 126 127 list(FIND _win_sdk_preferred_sdk_dirs "${_path}" _win_sdk_idx) 128 if(_win_sdk_idx GREATER -1) 129 # Path already in list - do not add 130 return() 131 endif() 132 _winsdk_announce( " - Found \"preferred\" SDK ${_info} @ ${_path}") 133 # Not yet in the list, so we'll add it 134 list(APPEND _win_sdk_preferred_sdk_dirs "${_path}") 135 set(_win_sdk_preferred_sdk_dirs "${_win_sdk_dirs}" CACHE INTERNAL "" FORCE) 136 137 # Just in case we somehow missed it: 138 _winsdk_conditional_append("${_info}" "" "${_path}") 139endfunction() 140 141# Given a version like v7.0A, looks for an SDK in the registry under "Microsoft SDKs". 142# If the given version might be in both HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows 143# and HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots aka "Windows Kits", 144# use this macro first, since these registry keys usually have more information. 145# 146# Pass a "default" build number as an extra argument in case we can't find it. 147function(_winsdk_check_microsoft_sdks_registry _winsdkver) 148 set(SDKKEY "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\${_winsdkver}") 149 get_filename_component(_sdkdir 150 "[${SDKKEY};InstallationFolder]" 151 ABSOLUTE) 152 153 set(_sdkname "Windows SDK ${_winsdkver}") 154 155 # Default build number passed as extra argument 156 set(_build ${ARGN}) 157 # See if the registry holds a Microsoft-mutilated, err, designated, product name 158 # (just using get_filename_component to execute the registry lookup) 159 get_filename_component(_sdkproductname 160 "[${SDKKEY};ProductName]" 161 NAME) 162 if(NOT "${_sdkproductname}" MATCHES "registry") 163 # Got a product name 164 set(_sdkname "${_sdkname} (${_sdkproductname})") 165 endif() 166 167 # try for a version to augment our name 168 # (just using get_filename_component to execute the registry lookup) 169 get_filename_component(_sdkver 170 "[${SDKKEY};ProductVersion]" 171 NAME) 172 if(NOT "${_sdkver}" MATCHES "registry" AND NOT MATCHES) 173 # Got a version 174 if(NOT "${_sdkver}" MATCHES "\\.\\.") 175 # and it's not an invalid one with two dots in it: 176 # use to override the default build 177 set(_build ${_sdkver}) 178 if(NOT "${_sdkname}" MATCHES "${_sdkver}") 179 # Got a version that's not already in the name, let's use it to improve our name. 180 set(_sdkname "${_sdkname} (${_sdkver})") 181 endif() 182 endif() 183 endif() 184 _winsdk_conditional_append("${_sdkname}" "${_build}" "${_sdkdir}") 185endfunction() 186 187# Given a name for identification purposes, the build number, and a key (technically a "value name") 188# corresponding to a Windows SDK packaged as a "Windows Kit", look for it 189# in HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots 190# Note that the key or "value name" tends to be something weird like KitsRoot81 - 191# no easy way to predict, just have to observe them in the wild. 192# Doesn't hurt to also try _winsdk_check_microsoft_sdks_registry for these: 193# sometimes you get keys in both parts of the registry (in the wow64 portion especially), 194# and the non-"Windows Kits" location is often more descriptive. 195function(_winsdk_check_windows_kits_registry _winkit_name _winkit_build _winkit_key) 196 get_filename_component(_sdkdir 197 "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots;${_winkit_key}]" 198 ABSOLUTE) 199 _winsdk_conditional_append("${_winkit_name}" "${_winkit_build}" "${_sdkdir}") 200endfunction() 201 202# Given a name for identification purposes and the build number 203# corresponding to a Windows 10 SDK packaged as a "Windows Kit", look for it 204# in HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots 205# Doesn't hurt to also try _winsdk_check_microsoft_sdks_registry for these: 206# sometimes you get keys in both parts of the registry (in the wow64 portion especially), 207# and the non-"Windows Kits" location is often more descriptive. 208function(_winsdk_check_win10_kits _winkit_build) 209 get_filename_component(_sdkdir 210 "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots;KitsRoot10]" 211 ABSOLUTE) 212 if(("${_sdkdir}" MATCHES "registry") OR (NOT EXISTS "${_sdkdir}")) 213 return() # not found 214 endif() 215 if(EXISTS "${_sdkdir}/Include/${_winkit_build}/um") 216 _winsdk_conditional_append("Windows Kits 10 (Build ${_winkit_build})" "${_winkit_build}" "${_sdkdir}") 217 endif() 218endfunction() 219 220# Given a name for indentification purposes, the build number, and the associated package GUID, 221# look in the registry under both HKLM and HKCU in \\SOFTWARE\\Microsoft\\MicrosoftSDK\\InstalledSDKs\\ 222# for that guid and the SDK it points to. 223function(_winsdk_check_platformsdk_registry _platformsdkname _build _platformsdkguid) 224 foreach(_winsdk_hive HKEY_LOCAL_MACHINE HKEY_CURRENT_USER) 225 get_filename_component(_sdkdir 226 "[${_winsdk_hive}\\SOFTWARE\\Microsoft\\MicrosoftSDK\\InstalledSDKs\\${_platformsdkguid};Install Dir]" 227 ABSOLUTE) 228 _winsdk_conditional_append("${_platformsdkname} (${_build})" "${_build}" "${_sdkdir}") 229 endforeach() 230endfunction() 231 232### 233# Detect toolchain information: to know whether it's OK to use Vista+ only SDKs 234### 235set(_winsdk_vistaonly_ok OFF) 236if(MSVC AND NOT _WINDOWSSDK_IGNOREMSVC) 237 # VC 10 and older has broad target support 238 if(MSVC_VERSION LESS 1700) 239 # VC 11 by default targets Vista and later only, so we can add a few more SDKs that (might?) only work on vista+ 240 elseif("${CMAKE_VS_PLATFORM_TOOLSET}" MATCHES "_xp") 241 # This is the XP-compatible v110+ toolset 242 elseif("${CMAKE_VS_PLATFORM_TOOLSET}" STREQUAL "v100" OR "${CMAKE_VS_PLATFORM_TOOLSET}" STREQUAL "v90") 243 # This is the VS2010/VS2008 toolset 244 else() 245 # OK, we're VC11 or newer and not using a backlevel or XP-compatible toolset. 246 # These versions have no XP (and possibly Vista pre-SP1) support 247 set(_winsdk_vistaonly_ok ON) 248 if(_WINDOWSSDK_ANNOUNCE AND NOT _WINDOWSSDK_VISTAONLY_PESTERED) 249 set(_WINDOWSSDK_VISTAONLY_PESTERED ON CACHE INTERNAL "" FORCE) 250 message(STATUS "FindWindowsSDK: Detected Visual Studio 2012 or newer, not using the _xp toolset variant: including SDK versions that drop XP support in search!") 251 endif() 252 endif() 253endif() 254if(_WINDOWSSDK_IGNOREMSVC) 255 set(_winsdk_vistaonly_ok ON) 256endif() 257 258### 259# MSVC version checks - keeps messy conditionals in one place 260# (messy because of _WINDOWSSDK_IGNOREMSVC) 261### 262set(_winsdk_msvc_greater_1200 OFF) 263if(_WINDOWSSDK_IGNOREMSVC OR (MSVC AND (MSVC_VERSION GREATER 1200))) 264 set(_winsdk_msvc_greater_1200 ON) 265endif() 266# Newer than VS .NET/VS Toolkit 2003 267set(_winsdk_msvc_greater_1310 OFF) 268if(_WINDOWSSDK_IGNOREMSVC OR (MSVC AND (MSVC_VERSION GREATER 1310))) 269 set(_winsdk_msvc_greater_1310 ON) 270endif() 271 272# VS2005/2008 273set(_winsdk_msvc_less_1600 OFF) 274if(_WINDOWSSDK_IGNOREMSVC OR (MSVC AND (MSVC_VERSION LESS 1600))) 275 set(_winsdk_msvc_less_1600 ON) 276endif() 277 278# VS2013+ 279set(_winsdk_msvc_not_less_1800 OFF) 280if(_WINDOWSSDK_IGNOREMSVC OR (MSVC AND (NOT MSVC_VERSION LESS 1800))) 281 set(_winsdk_msvc_not_less_1800 ON) 282endif() 283 284### 285# START body of find module 286### 287if(_winsdk_msvc_greater_1310) # Newer than VS .NET/VS Toolkit 2003 288 ### 289 # Look for "preferred" SDKs 290 ### 291 292 # Environment variable for SDK dir 293 if(EXISTS "$ENV{WindowsSDKDir}" AND (NOT "$ENV{WindowsSDKDir}" STREQUAL "")) 294 _winsdk_conditional_append_preferred("WindowsSDKDir environment variable" "$ENV{WindowsSDKDir}") 295 endif() 296 297 if(_winsdk_msvc_less_1600) 298 # Per-user current Windows SDK for VS2005/2008 299 get_filename_component(_sdkdir 300 "[HKEY_CURRENT_USER\\Software\\Microsoft\\Microsoft SDKs\\Windows;CurrentInstallFolder]" 301 ABSOLUTE) 302 _winsdk_conditional_append_preferred("Per-user current Windows SDK" "${_sdkdir}") 303 304 # System-wide current Windows SDK for VS2005/2008 305 get_filename_component(_sdkdir 306 "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows;CurrentInstallFolder]" 307 ABSOLUTE) 308 _winsdk_conditional_append_preferred("System-wide current Windows SDK" "${_sdkdir}") 309 endif() 310 311 ### 312 # Begin the massive list of SDK searching! 313 ### 314 if(_winsdk_vistaonly_ok AND _winsdk_msvc_not_less_1800) 315 # These require at least Visual Studio 2013 (VC12) 316 317 _winsdk_check_microsoft_sdks_registry(v10.0A) 318 319 # Windows Software Development Kit (SDK) for Windows 10 320 # Several different versions living in the same directory - if nothing else we can assume RTM (10240) 321 _winsdk_check_microsoft_sdks_registry(v10.0 10.0.10240.0) 322 foreach(_win10build ${_winsdk_win10vers}) 323 _winsdk_check_win10_kits(${_win10build}) 324 endforeach() 325 endif() # vista-only and 2013+ 326 327 # Included in Visual Studio 2013 328 # Includes the v120_xp toolset 329 _winsdk_check_microsoft_sdks_registry(v8.1A 8.1.51636) 330 331 if(_winsdk_vistaonly_ok AND _winsdk_msvc_not_less_1800) 332 # Windows Software Development Kit (SDK) for Windows 8.1 333 # http://msdn.microsoft.com/en-gb/windows/desktop/bg162891 334 _winsdk_check_microsoft_sdks_registry(v8.1 8.1.25984.0) 335 _winsdk_check_windows_kits_registry("Windows Kits 8.1" 8.1.25984.0 KitsRoot81) 336 endif() # vista-only and 2013+ 337 338 if(_winsdk_vistaonly_ok) 339 # Included in Visual Studio 2012 340 _winsdk_check_microsoft_sdks_registry(v8.0A 8.0.50727) 341 342 # Microsoft Windows SDK for Windows 8 and .NET Framework 4.5 343 # This is the first version to also include the DirectX SDK 344 # http://msdn.microsoft.com/en-US/windows/desktop/hh852363.aspx 345 _winsdk_check_microsoft_sdks_registry(v8.0 6.2.9200.16384) 346 _winsdk_check_windows_kits_registry("Windows Kits 8.0" 6.2.9200.16384 KitsRoot) 347 endif() # vista-only 348 349 # Included with VS 2012 Update 1 or later 350 # Introduces v110_xp toolset 351 _winsdk_check_microsoft_sdks_registry(v7.1A 7.1.51106) 352 if(_winsdk_vistaonly_ok) 353 # Microsoft Windows SDK for Windows 7 and .NET Framework 4 354 # http://www.microsoft.com/downloads/en/details.aspx?FamilyID=6b6c21d2-2006-4afa-9702-529fa782d63b 355 _winsdk_check_microsoft_sdks_registry(v7.1 7.1.7600.0.30514) 356 endif() # vista-only 357 358 # Included with VS 2010 359 _winsdk_check_microsoft_sdks_registry(v7.0A 6.1.7600.16385) 360 361 # Windows SDK for Windows 7 and .NET Framework 3.5 SP1 362 # Works with VC9 363 # http://www.microsoft.com/en-us/download/details.aspx?id=18950 364 _winsdk_check_microsoft_sdks_registry(v7.0 6.1.7600.16385) 365 366 # Two versions call themselves "v6.1": 367 # Older: 368 # Windows Vista Update & .NET 3.0 SDK 369 # http://www.microsoft.com/en-us/download/details.aspx?id=14477 370 371 # Newer: 372 # Windows Server 2008 & .NET 3.5 SDK 373 # may have broken VS9SP1? they recommend v7.0 instead, or a KB... 374 # http://www.microsoft.com/en-us/download/details.aspx?id=24826 375 _winsdk_check_microsoft_sdks_registry(v6.1 6.1.6000.16384.10) 376 377 # Included in VS 2008 378 _winsdk_check_microsoft_sdks_registry(v6.0A 6.1.6723.1) 379 380 # Microsoft Windows Software Development Kit for Windows Vista and .NET Framework 3.0 Runtime Components 381 # 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 382 _winsdk_check_microsoft_sdks_registry(v6.0 6.0.6000.16384) 383endif() 384 385# Let's not forget the Platform SDKs, which sometimes are useful! 386if(_winsdk_msvc_greater_1200) 387 _winsdk_check_platformsdk_registry("Microsoft Platform SDK for Windows Server 2003 R2" "5.2.3790.2075.51" "D2FF9F89-8AA2-4373-8A31-C838BF4DBBE1") 388 _winsdk_check_platformsdk_registry("Microsoft Platform SDK for Windows Server 2003 SP1" "5.2.3790.1830.15" "8F9E5EF3-A9A5-491B-A889-C58EFFECE8B3") 389endif() 390### 391# Finally, look for "preferred" SDKs 392### 393if(_winsdk_msvc_greater_1310) # Newer than VS .NET/VS Toolkit 2003 394 395 396 # Environment variable for SDK dir 397 if(EXISTS "$ENV{WindowsSDKDir}" AND (NOT "$ENV{WindowsSDKDir}" STREQUAL "")) 398 _winsdk_conditional_append_preferred("WindowsSDKDir environment variable" "$ENV{WindowsSDKDir}") 399 endif() 400 401 if(_winsdk_msvc_less_1600) 402 # Per-user current Windows SDK for VS2005/2008 403 get_filename_component(_sdkdir 404 "[HKEY_CURRENT_USER\\Software\\Microsoft\\Microsoft SDKs\\Windows;CurrentInstallFolder]" 405 ABSOLUTE) 406 _winsdk_conditional_append_preferred("Per-user current Windows SDK" "${_sdkdir}") 407 408 # System-wide current Windows SDK for VS2005/2008 409 get_filename_component(_sdkdir 410 "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows;CurrentInstallFolder]" 411 ABSOLUTE) 412 _winsdk_conditional_append_preferred("System-wide current Windows SDK" "${_sdkdir}") 413 endif() 414endif() 415 416 417function(windowssdk_name_lookup _dir _outvar) 418 list(FIND _win_sdk_versanddirs "${_dir}" _diridx) 419 math(EXPR _idx "${_diridx} - 1") 420 if(${_idx} GREATER -1) 421 list(GET _win_sdk_versanddirs ${_idx} _ret) 422 else() 423 set(_ret "NOTFOUND") 424 endif() 425 set(${_outvar} "${_ret}" PARENT_SCOPE) 426endfunction() 427 428function(windowssdk_build_lookup _dir _outvar) 429 list(FIND _win_sdk_buildsanddirs "${_dir}" _diridx) 430 math(EXPR _idx "${_diridx} - 1") 431 if(${_idx} GREATER -1) 432 list(GET _win_sdk_buildsanddirs ${_idx} _ret) 433 else() 434 set(_ret "NOTFOUND") 435 endif() 436 set(${_outvar} "${_ret}" PARENT_SCOPE) 437endfunction() 438 439# If we found something... 440if(_win_sdk_dirs) 441 list(GET _win_sdk_dirs 0 WINDOWSSDK_LATEST_DIR) 442 windowssdk_name_lookup("${WINDOWSSDK_LATEST_DIR}" 443 WINDOWSSDK_LATEST_NAME) 444 set(WINDOWSSDK_DIRS ${_win_sdk_dirs}) 445 446 # Fallback, in case no preference found. 447 set(WINDOWSSDK_PREFERRED_DIR "${WINDOWSSDK_LATEST_DIR}") 448 set(WINDOWSSDK_PREFERRED_NAME "${WINDOWSSDK_LATEST_NAME}") 449 set(WINDOWSSDK_PREFERRED_FIRST_DIRS ${WINDOWSSDK_DIRS}) 450 set(WINDOWSSDK_FOUND_PREFERENCE OFF) 451endif() 452 453# If we found indications of a user preference... 454if(_win_sdk_preferred_sdk_dirs) 455 list(GET _win_sdk_preferred_sdk_dirs 0 WINDOWSSDK_PREFERRED_DIR) 456 windowssdk_name_lookup("${WINDOWSSDK_PREFERRED_DIR}" 457 WINDOWSSDK_PREFERRED_NAME) 458 set(WINDOWSSDK_PREFERRED_FIRST_DIRS 459 ${_win_sdk_preferred_sdk_dirs} 460 ${_win_sdk_dirs}) 461 list(REMOVE_DUPLICATES WINDOWSSDK_PREFERRED_FIRST_DIRS) 462 set(WINDOWSSDK_FOUND_PREFERENCE ON) 463endif() 464 465include(FindPackageHandleStandardArgs) 466find_package_handle_standard_args(WindowsSDK 467 "No compatible version of the Windows SDK or Platform SDK found." 468 WINDOWSSDK_DIRS) 469 470if(WINDOWSSDK_FOUND) 471 # Internal: Architecture-appropriate library directory names. 472 if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "ARM") 473 if(CMAKE_SIZEOF_VOID_P MATCHES "8") 474 # Only supported in Win10 SDK and up. 475 set(_winsdk_arch8 arm64) # what the WDK for Win8+ calls this architecture 476 else() 477 set(_winsdk_archbare /arm) # what the architecture used to be called in oldest SDKs 478 set(_winsdk_arch arm) # what the architecture used to be called 479 set(_winsdk_arch8 arm) # what the WDK for Win8+ calls this architecture 480 endif() 481 else() 482 if(CMAKE_SIZEOF_VOID_P MATCHES "8") 483 set(_winsdk_archbare /x64) # what the architecture used to be called in oldest SDKs 484 set(_winsdk_arch amd64) # what the architecture used to be called 485 set(_winsdk_arch8 x64) # what the WDK for Win8+ calls this architecture 486 else() 487 set(_winsdk_archbare ) # what the architecture used to be called in oldest SDKs 488 set(_winsdk_arch i386) # what the architecture used to be called 489 set(_winsdk_arch8 x86) # what the WDK for Win8+ calls this architecture 490 endif() 491 endif() 492 493 function(get_windowssdk_from_component _component _var) 494 get_filename_component(_component "${_component}" ABSOLUTE) 495 file(TO_CMAKE_PATH "${_component}" _component) 496 foreach(_sdkdir ${WINDOWSSDK_DIRS}) 497 get_filename_component(_sdkdir "${_sdkdir}" ABSOLUTE) 498 string(LENGTH "${_sdkdir}" _sdklen) 499 file(RELATIVE_PATH _rel "${_sdkdir}" "${_component}") 500 # If we don't have any "parent directory" items... 501 if(NOT "${_rel}" MATCHES "[.][.]") 502 set(${_var} "${_sdkdir}" PARENT_SCOPE) 503 return() 504 endif() 505 endforeach() 506 # Fail. 507 set(${_var} "NOTFOUND" PARENT_SCOPE) 508 endfunction() 509 function(get_windowssdk_library_dirs _winsdk_dir _var) 510 set(_result) 511 set(_suffixes 512 "lib${_winsdk_archbare}" # SDKs like 7.1A 513 "lib/${_winsdk_arch}" # just because some SDKs have x86 dir and root dir 514 "lib/w2k/${_winsdk_arch}" # Win2k min requirement 515 "lib/wxp/${_winsdk_arch}" # WinXP min requirement 516 "lib/wnet/${_winsdk_arch}" # Win Server 2003 min requirement 517 "lib/wlh/${_winsdk_arch}" 518 "lib/wlh/um/${_winsdk_arch8}" # Win Vista ("Long Horn") min requirement 519 "lib/win7/${_winsdk_arch}" 520 "lib/win7/um/${_winsdk_arch8}" # Win 7 min requirement 521 ) 522 foreach(_ver 523 wlh # Win Vista ("Long Horn") min requirement 524 win7 # Win 7 min requirement 525 win8 # Win 8 min requirement 526 winv6.3 # Win 8.1 min requirement 527 ) 528 529 list(APPEND _suffixes 530 "lib/${_ver}/${_winsdk_arch}" 531 "lib/${_ver}/um/${_winsdk_arch8}" 532 "lib/${_ver}/km/${_winsdk_arch8}" 533 ) 534 endforeach() 535 536 # Look for WDF libraries in Win10+ SDK 537 foreach(_mode umdf kmdf) 538 file(GLOB _wdfdirs RELATIVE "${_winsdk_dir}" "${_winsdk_dir}/lib/wdf/${_mode}/${_winsdk_arch8}/*") 539 if(_wdfdirs) 540 list(APPEND _suffixes ${_wdfdirs}) 541 endif() 542 endforeach() 543 544 # Look in each Win10+ SDK version for the components 545 foreach(_win10ver ${_winsdk_win10vers}) 546 foreach(_component um km ucrt mmos) 547 list(APPEND _suffixes "lib/${_win10ver}/${_component}/${_winsdk_arch8}") 548 endforeach() 549 endforeach() 550 551 foreach(_suffix ${_suffixes}) 552 # Check to see if a library actually exists here. 553 file(GLOB _libs "${_winsdk_dir}/${_suffix}/*.lib") 554 if(_libs) 555 list(APPEND _result "${_winsdk_dir}/${_suffix}") 556 endif() 557 endforeach() 558 if(NOT _result) 559 set(_result NOTFOUND) 560 else() 561 list(REMOVE_DUPLICATES _result) 562 endif() 563 set(${_var} ${_result} PARENT_SCOPE) 564 endfunction() 565 function(get_windowssdk_include_dirs _winsdk_dir _var) 566 set(_result) 567 568 set(_subdirs shared um winrt km wdf mmos ucrt) 569 set(_suffixes Include) 570 571 foreach(_dir ${_subdirs}) 572 list(APPEND _suffixes "Include/${_dir}") 573 endforeach() 574 575 foreach(_ver ${_winsdk_win10vers}) 576 foreach(_dir ${_subdirs}) 577 list(APPEND _suffixes "Include/${_ver}/${_dir}") 578 endforeach() 579 endforeach() 580 581 foreach(_suffix ${_suffixes}) 582 # Check to see if a header file actually exists here. 583 file(GLOB _headers "${_winsdk_dir}/${_suffix}/*.h") 584 if(_headers) 585 list(APPEND _result "${_winsdk_dir}/${_suffix}") 586 endif() 587 endforeach() 588 if(NOT _result) 589 set(_result NOTFOUND) 590 else() 591 list(REMOVE_DUPLICATES _result) 592 endif() 593 set(${_var} ${_result} PARENT_SCOPE) 594 endfunction() 595 function(get_windowssdk_library_dirs_multiple _var) 596 set(_result) 597 foreach(_sdkdir ${ARGN}) 598 get_windowssdk_library_dirs("${_sdkdir}" _current_sdk_libdirs) 599 if(_current_sdk_libdirs) 600 list(APPEND _result ${_current_sdk_libdirs}) 601 endif() 602 endforeach() 603 if(NOT _result) 604 set(_result NOTFOUND) 605 else() 606 list(REMOVE_DUPLICATES _result) 607 endif() 608 set(${_var} ${_result} PARENT_SCOPE) 609 endfunction() 610 function(get_windowssdk_include_dirs_multiple _var) 611 set(_result) 612 foreach(_sdkdir ${ARGN}) 613 get_windowssdk_include_dirs("${_sdkdir}" _current_sdk_incdirs) 614 if(_current_sdk_libdirs) 615 list(APPEND _result ${_current_sdk_incdirs}) 616 endif() 617 endforeach() 618 if(NOT _result) 619 set(_result NOTFOUND) 620 else() 621 list(REMOVE_DUPLICATES _result) 622 endif() 623 set(${_var} ${_result} PARENT_SCOPE) 624 endfunction() 625endif() 626