FindWindowsSDK.cmake 23 KB

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