FindWindowsSDK.cmake 21 KB

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