1 # - Find Windows Platform SDK
\r
2 # Find the Windows includes
\r
4 # WINSDK_INCLUDE_DIR - where to find Windows.h
\r
5 # WINSDK_INCLUDE_DIRS - where to find all Windows headers
\r
6 # WINSDK_LIBRARY_DIR - where to find libraries
\r
7 # WINSDK_FOUND - True if Windows SDK found.
\r
10 # If Windows SDK already found, skip it
\r
14 # Values can be CURRENT or any existing versions 7.1, 8.0A, etc...
\r
15 SET(WINSDK_VERSION "CURRENT" CACHE STRING "Windows SDK version to prefer")
\r
17 MACRO(DETECT_WINSDK_VERSION_HELPER _ROOT _VERSION)
\r
18 GET_FILENAME_COMPONENT(WINSDK${_VERSION}_DIR "[${_ROOT}\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\v${_VERSION};InstallationFolder]" ABSOLUTE)
\r
20 IF(WINSDK${_VERSION}_DIR AND NOT WINSDK${_VERSION}_DIR STREQUAL "/registry" AND EXISTS "${WINSDK${_VERSION}_DIR}/Include")
\r
21 SET(WINSDK${_VERSION}_FOUND ON)
\r
22 GET_FILENAME_COMPONENT(WINSDK${_VERSION}_VERSION_FULL "[${_ROOT}\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\v${_VERSION};ProductVersion]" NAME)
\r
24 IF(NOT WindowsSDK_FIND_QUIETLY)
\r
25 MESSAGE(STATUS "Found Windows SDK ${_VERSION} in ${WINSDK${_VERSION}_DIR}")
\r
28 SET(WINSDK${_VERSION}_DIR "")
\r
32 MACRO(DETECT_WINKIT_VERSION_HELPER _VERSION _SUFFIX _PREFIX _ARCH)
\r
33 GET_FILENAME_COMPONENT(WINSDK${_VERSION}_DIR "[HKEY_LOCAL_MACHINE\\SOFTWARE\\${_PREFIX}Microsoft\\Windows Kits\\Installed Roots;KitsRoot${_SUFFIX}]" ABSOLUTE)
\r
35 IF(WINSDK${_VERSION}_DIR AND NOT WINSDK${_VERSION}_DIR STREQUAL "/registry" AND EXISTS "${WINSDK${_VERSION}_DIR}/Include")
\r
36 SET(WINSDK${_VERSION}_FOUND ON)
\r
37 SET(WINSDK${_VERSION}_VERSION_FULL "${_VERSION}")
\r
38 IF(NOT WindowsSDK_FIND_QUIETLY)
\r
39 MESSAGE(STATUS "Found Windows Kit ${_VERSION} in ${WINSDK${_VERSION}_DIR} (registry ${_ARCH} bits)")
\r
41 LIST(APPEND WINSDK_DETECTED_VERSIONS ${_VERSION})
\r
43 SET(WINSDK${_VERSION}_DIR "")
\r
47 MACRO(DETECT_WINSDK_VERSION _VERSION)
\r
48 SET(WINSDK${_VERSION}_FOUND OFF)
\r
49 DETECT_WINSDK_VERSION_HELPER("HKEY_CURRENT_USER" ${_VERSION})
\r
51 IF(NOT WINSDK${_VERSION}_FOUND)
\r
52 DETECT_WINSDK_VERSION_HELPER("HKEY_LOCAL_MACHINE" ${_VERSION})
\r
56 MACRO(DETECT_WINKIT_VERSION _VERSION _SUFFIX)
\r
57 DETECT_WINKIT_VERSION_HELPER("${_VERSION}" "${_SUFFIX}" "WOW6432Node\\\\" "32")
\r
59 IF(NOT WINSDK${_VERSION}_FOUND)
\r
60 DETECT_WINKIT_VERSION_HELPER("${_VERSION}" "${_SUFFIX}" "" "64")
\r
64 SET(WINSDK_DETECTED_VERSIONS)
\r
66 # Fixed versions for Windows Kits (VC++ from 2012)
\r
67 DETECT_WINKIT_VERSION("10.0" "10")
\r
68 DETECT_WINKIT_VERSION("8.1" "81")
\r
69 DETECT_WINKIT_VERSION("8.0" "")
\r
71 # For VC++ up to 2010
\r
72 SET(WINSDK_VERSIONS "7.1" "7.1A" "7.0" "7.0A" "6.1" "6.0" "6.0A")
\r
74 # Search all supported Windows SDKs
\r
75 FOREACH(_VERSION ${WINSDK_VERSIONS})
\r
76 DETECT_WINSDK_VERSION(${_VERSION})
\r
78 IF(WINSDK${_VERSION}_FOUND)
\r
79 LIST(APPEND WINSDK_DETECTED_VERSIONS ${_VERSION})
\r
83 SET(WINSDK_SUFFIXES)
\r
86 SET(WINSDK8_SUFFIX "arm64")
\r
88 SET(WINSDK8_SUFFIX "arm")
\r
90 SET(WINSDK8_SUFFIX "x64")
\r
91 SET(WINSDK_SUFFIXES "x64" "amd64")
\r
93 SET(WINSDK8_SUFFIX "x86")
\r
96 SET(WINSDKCURRENT_VERSION_INCLUDE $ENV{INCLUDE})
\r
98 IF(WINSDKCURRENT_VERSION_INCLUDE)
\r
99 FILE(TO_CMAKE_PATH "${WINSDKCURRENT_VERSION_INCLUDE}" WINSDKCURRENT_VERSION_INCLUDE)
\r
102 SET(WINSDKENV_DIR $ENV{WINSDK_DIR})
\r
104 IF(NOT WINSDKENV_DIR)
\r
105 SET(WINSDKENV_DIR $ENV{WindowsSDKDir})
\r
108 MACRO(FIND_WINSDK_VERSION_HEADERS)
\r
109 IF(WINSDK_DIR AND NOT WINSDK_VERSION)
\r
110 # Search version in headers
\r
111 FIND_FILE(_MSI_FILE Msi.h
\r
113 ${WINSDK_DIR}/Include/um
\r
114 ${WINSDK_DIR}/Include
\r
118 IF(NOT WINSDK_VERSION)
\r
119 # Look for Windows SDK 8.1
\r
120 FILE(STRINGS ${_MSI_FILE} _CONTENT REGEX "^#ifndef NTDDI_WINBLUE")
\r
123 SET(WINSDK_VERSION "8.1")
\r
127 IF(NOT WINSDK_VERSION)
\r
128 # Look for Windows SDK 8.0
\r
129 FILE(STRINGS ${_MSI_FILE} _CONTENT REGEX "^#ifndef NTDDI_WIN8")
\r
132 SET(WINSDK_VERSION "8.0")
\r
136 IF(NOT WINSDK_VERSION)
\r
137 # Look for Windows SDK 7.0
\r
138 FILE(STRINGS ${_MSI_FILE} _CONTENT REGEX "^#ifndef NTDDI_WIN7")
\r
141 FIND_FILE(_WINSDKVER_FILE winsdkver.h WinSDKVer.h
\r
143 ${WINSDK_DIR}/Include/um
\r
144 ${WINSDK_DIR}/Include
\r
147 IF(_WINSDKVER_FILE)
\r
148 # Load WinSDKVer.h content
\r
149 FILE(STRINGS ${_WINSDKVER_FILE} _CONTENT REGEX "^#define NTDDI_MAXVER")
\r
151 # Get NTDDI_MAXVER value
\r
152 STRING(REGEX REPLACE "^.*0x([0-9A-Fa-f]+).*$" "\\1" _WINSDKVER "${_CONTENT}")
\r
154 # In Windows SDK 7.1, NTDDI_MAXVER is wrong
\r
155 IF(_WINSDKVER STREQUAL "06010000")
\r
156 SET(WINSDK_VERSION "7.1")
\r
157 ELSEIF(_WINSDKVER STREQUAL "0601")
\r
158 SET(WINSDK_VERSION "7.0A")
\r
160 MESSAGE(FATAL_ERROR "Can't determine Windows SDK version with NTDDI_MAXVER 0x${_WINSDKVER}")
\r
163 SET(WINSDK_VERSION "7.0")
\r
168 IF(NOT WINSDK_VERSION)
\r
169 # Look for Windows SDK 6.0
\r
170 FILE(STRINGS ${_MSI_FILE} _CONTENT REGEX "^#ifndef NTDDI_VISTA")
\r
173 SET(WINSDK_VERSION "6.0")
\r
177 IF(NOT WINSDK_VERSION)
\r
178 # Look for Windows SDK 5.2
\r
179 FILE(STRINGS ${_MSI_FILE} _CONTENT REGEX "^#ifndef NTDDI_WS03SP1")
\r
182 SET(WINSDK_VERSION "5.2")
\r
186 IF(NOT WINSDK_VERSION)
\r
187 # Look for Windows SDK 5.1
\r
188 FILE(STRINGS ${_MSI_FILE} _CONTENT REGEX "^#ifndef NTDDI_WINXP")
\r
191 SET(WINSDK_VERSION "5.1")
\r
195 IF(NOT WINSDK_VERSION)
\r
196 # Look for Windows SDK 5.0
\r
197 FILE(STRINGS ${_MSI_FILE} _CONTENT REGEX "^#ifndef NTDDI_WIN2K")
\r
200 SET(WINSDK_VERSION "5.0")
\r
204 MESSAGE(FATAL_ERROR "Unable to find Msi.h in ${WINSDK_DIR}")
\r
209 MACRO(USE_CURRENT_WINSDK)
\r
211 SET(WINSDK_VERSION "")
\r
212 SET(WINSDK_VERSION_FULL "")
\r
214 # Use WINSDK environment variable
\r
216 FIND_PATH(WINSDK_DIR Windows.h
\r
218 ${WINSDKENV_DIR}/Include/um
\r
219 ${WINSDKENV_DIR}/Include
\r
223 # Use INCLUDE environment variable
\r
224 IF(NOT WINSDK_DIR AND WINSDKCURRENT_VERSION_INCLUDE)
\r
225 FOREACH(_INCLUDE ${WINSDKCURRENT_VERSION_INCLUDE})
\r
226 FILE(TO_CMAKE_PATH ${_INCLUDE} _INCLUDE)
\r
228 # Look for Windows.h because there are several paths
\r
229 IF(EXISTS ${_INCLUDE}/Windows.h)
\r
230 STRING(REGEX REPLACE "/(include|INCLUDE|Include)(.*)" "" WINSDK_DIR ${_INCLUDE})
\r
231 MESSAGE(STATUS "Found Windows SDK in INCLUDE environment variable: ${WINSDK_DIR}")
\r
238 # Compare WINSDK_DIR with registered Windows SDKs
\r
239 FOREACH(_VERSION ${WINSDK_DETECTED_VERSIONS})
\r
240 IF(WINSDK_DIR STREQUAL "${WINSDK${_VERSION}_DIR}")
\r
241 SET(WINSDK_VERSION ${_VERSION})
\r
242 SET(WINSDK_VERSION_FULL "${WINSDK${WINSDK_VERSION}_VERSION_FULL}")
\r
247 FIND_WINSDK_VERSION_HEADERS()
\r
251 # Use Windows SDK versions installed with VC++ when possible
\r
252 IF(MSVC_VERSION GREATER 1909)
\r
253 # Special case, use Kits for SDK
\r
254 SET(WINSDK_VERSION "10.0")
\r
255 SET(WINSDK_DIR ${WINSDK_UCRT_DIR})
\r
257 SET(WINSDK_VERSION "8.1")
\r
259 SET(WINSDK_VERSION "8.1")
\r
261 SET(WINSDK_VERSION "8.0")
\r
263 IF(NOT TARGET_X64 OR NOT MSVC_EXPRESS)
\r
264 SET(WINSDK_VERSION "7.0A")
\r
267 IF(NOT MSVC_EXPRESS)
\r
268 SET(WINSDK_VERSION "6.0A")
\r
271 SET(WINSDK_MSVC80_COMPATIBLES "7.1" "7.1A" "7.0" "7.0A" "6.1" "6.0" "6.0A" "5.2A")
\r
273 # look for each Windows SDK supported by VC++ 2005 (7.1 is the latest)
\r
274 FOREACH(_VERSION ${WINSDK_DETECTED_VERSIONS})
\r
275 # look if this version of Windows SDK is installed
\r
276 LIST(FIND WINSDK_MSVC80_COMPATIBLES ${_VERSION} _FOUND)
\r
277 IF(NOT _FOUND EQUAL -1)
\r
278 SET(WINSDK_VERSION "${_VERSION}")
\r
283 IF(NOT MSVC_EXPRESS AND NOT WINSDK_VERSION)
\r
284 SET(WINSDK_VERSION "5.2A")
\r
287 MESSAGE(FATAL_ERROR "Your compiler is either too old or too recent, please update this CMake module.")
\r
290 # Use installed Windows SDK
\r
291 IF(NOT WINSDK_VERSION)
\r
292 IF(WINSDK8.1_FOUND)
\r
293 SET(WINSDK_VERSION "8.1")
\r
294 ELSEIF(WINSDK8.0_FOUND)
\r
295 SET(WINSDK_VERSION "8.0")
\r
296 ELSEIF(WINSDK7.1_FOUND)
\r
297 SET(WINSDK_VERSION "7.1")
\r
298 ELSEIF(WINSDK7.0_FOUND)
\r
299 SET(WINSDK_VERSION "7.0")
\r
300 ELSEIF(WINSDK6.1_FOUND)
\r
301 SET(WINSDK_VERSION "6.1")
\r
302 ELSEIF(WINSDK6.0_FOUND)
\r
303 SET(WINSDK_VERSION "6.0")
\r
305 MESSAGE(FATAL_ERROR "You have no compatible Windows SDK installed.")
\r
309 # Look for correct registered Windows SDK version
\r
310 FOREACH(_VERSION ${WINSDK_DETECTED_VERSIONS})
\r
311 IF(WINSDK_VERSION STREQUAL _VERSION)
\r
312 SET(WINSDK_VERSION_FULL "${WINSDK${WINSDK_VERSION}_VERSION_FULL}")
\r
313 SET(WINSDK_DIR "${WINSDK${WINSDK_VERSION}_DIR}")
\r
321 # Under VC++ 2015 and 2017, stdio.h, stdlib.h, etc... are part of UCRT
\r
322 SET(WINSDK_UCRT_VERSION "10.0")
\r
325 # Look for correct UCRT
\r
326 IF(WINSDK_UCRT_VERSION AND WINSDK${WINSDK_UCRT_VERSION}_FOUND)
\r
327 SET(WINSDK_UCRT_DIR "${WINSDK${WINSDK_UCRT_VERSION}_DIR}")
\r
330 IF(WINSDK_UCRT_DIR)
\r
331 # determine exact UCRT version
\r
332 SET(WINSDK_UCRT_INCLUDE_ROOT_DIR ${WINSDK_UCRT_DIR}/Include)
\r
333 SET(WINSDK_UCRT_LIB_ROOT_DIR ${WINSDK_UCRT_DIR}/Lib)
\r
335 FILE(GLOB UCRT_SUBDIRS RELATIVE ${WINSDK_UCRT_INCLUDE_ROOT_DIR} ${WINSDK_UCRT_INCLUDE_ROOT_DIR}/*)
\r
338 FOREACH(UCRT_SUBDIR ${UCRT_SUBDIRS})
\r
339 IF(NOT UCRT_VERSION OR UCRT_SUBDIR VERSION_GREATER UCRT_VERSION)
\r
340 SET(UCRT_VERSION ${UCRT_SUBDIR})
\r
345 MESSAGE(STATUS "Using Windows UCRT ${UCRT_VERSION}")
\r
347 SET(WINSDK10_INCLUDE_DIR ${WINSDK_UCRT_INCLUDE_ROOT_DIR}/${UCRT_VERSION})
\r
348 SET(WINSDK10_LIBRARY_DIR ${WINSDK_UCRT_LIB_ROOT_DIR}/${UCRT_VERSION})
\r
350 # directory where UCRT headers are found
\r
351 FIND_PATH(WINSDK_UCRT_INCLUDE_DIR corecrt.h
\r
353 ${WINSDK10_INCLUDE_DIR}/ucrt
\r
356 # directory where UCRT libraries are found
\r
357 FIND_PATH(WINSDK_UCRT_LIBRARY_DIR ucrt.lib
\r
359 ${WINSDK10_LIBRARY_DIR}/ucrt/${WINSDK8_SUFFIX}
\r
364 IF(WINSDK_VERSION STREQUAL "CURRENT")
\r
365 USE_CURRENT_WINSDK()
\r
367 IF(WINSDK${WINSDK_VERSION}_FOUND)
\r
368 SET(WINSDK_VERSION_FULL "${WINSDK${WINSDK_VERSION}_VERSION_FULL}")
\r
369 SET(WINSDK_DIR "${WINSDK${WINSDK_VERSION}_DIR}")
\r
371 USE_CURRENT_WINSDK()
\r
376 MESSAGE(STATUS "Using Windows SDK ${WINSDK_VERSION}")
\r
378 MESSAGE(FATAL_ERROR "Unable to find Windows SDK!")
\r
381 # directory where Win32 headers are found
\r
382 FIND_PATH(WINSDK_INCLUDE_DIR Windows.h
\r
384 ${WINSDK_DIR}/Include/${UCRT_VERSION}/um
\r
385 ${WINSDK_DIR}/Include/um
\r
386 ${WINSDK_DIR}/Include
\r
390 IF(WINSDK_INCLUDE_DIR)
\r
391 MESSAGE(STATUS "Found Windows.h in ${WINSDK_INCLUDE_DIR}")
\r
393 MESSAGE(FATAL_ERROR "Unable to find Windows.h")
\r
396 # directory where WinRT headers are found
\r
397 FIND_PATH(WINSDK_WINRT_INCLUDE_DIR winstring.h
\r
399 ${WINSDK_DIR}/Include/${UCRT_VERSION}/winrt
\r
400 ${WINSDK_DIR}/Include/winrt
\r
404 MESSAGE(STATUS "Found winstring.h in ${WINSDK_WINRT_INCLUDE_DIR}")
\r
406 # directory where DirectX headers are found
\r
407 FIND_PATH(WINSDK_SHARED_INCLUDE_DIR d3d9.h
\r
409 ${WINSDK_DIR}/Include/${UCRT_VERSION}/shared
\r
410 ${WINSDK_DIR}/Include/shared
\r
414 MESSAGE(STATUS "Found d3d9.h in ${WINSDK_SHARED_INCLUDE_DIR}")
\r
416 # directory where OpenGL headers are found
\r
417 FIND_PATH(WINSDK_OPENGL_INCLUDE_DIR GL.h
\r
419 ${WINSDK_INCLUDE_DIR}/gl
\r
420 ${WINSDK_DIR}/Include/um/gl
\r
421 ${WINSDK_DIR}/Include/gl
\r
425 MESSAGE(STATUS "Found GL.h in ${WINSDK_OPENGL_INCLUDE_DIR}")
\r
427 SET(WINSDK_LIBRARY_DIRS
\r
428 ${WINSDK_DIR}/Lib/${UCRT_VERSION}/um/${WINSDK8_SUFFIX}
\r
429 ${WINSDK_DIR}/Lib/winv6.3/um/${WINSDK8_SUFFIX}
\r
430 ${WINSDK_DIR}/Lib/win8/um/${WINSDK8_SUFFIX}
\r
433 IF(WINSDK_SUFFIXES)
\r
434 FOREACH(_SUFFIX ${WINSDK_SUFFIXES})
\r
435 LIST(APPEND WINSDK_LIBRARY_DIRS ${WINSDK_DIR}/Lib/${_SUFFIX})
\r
438 LIST(APPEND WINSDK_LIBRARY_DIRS ${WINSDK_DIR}/Lib)
\r
441 # directory where all libraries are found
\r
442 FIND_PATH(WINSDK_LIBRARY_DIR ComCtl32.lib
\r
444 ${WINSDK_LIBRARY_DIRS}
\r
448 MESSAGE(STATUS "Found ComCtl32.lib in ${WINSDK_LIBRARY_DIR}")
\r
450 SET(WINSDK_BINARY_DIRS
\r
451 ${WINSDK_DIR}/Bin/${UCRT_VERSION}/${WINSDK8_SUFFIX}
\r
452 ${WINSDK_DIR}/Bin/${WINSDK8_SUFFIX}
\r
453 ${WINSDK_DIR}/Bin/x86
\r
457 # signtool is used to sign executables
\r
458 FIND_PROGRAM(WINSDK_SIGNTOOL signtool
\r
460 ${WINSDK_BINARY_DIRS}
\r
464 # midl is used to generate IDL interfaces
\r
465 FIND_PROGRAM(WINSDK_MIDL midl
\r
467 ${WINSDK_BINARY_DIRS}
\r
471 IF(WINSDK_INCLUDE_DIR)
\r
472 SET(WINSDK_FOUND ON)
\r
474 IF(WINSDK_UCRT_INCLUDE_DIR)
\r
475 SET(WINSDK_INCLUDE_DIRS ${WINSDK_INCLUDE_DIRS} ${WINSDK_UCRT_INCLUDE_DIR})
\r
478 IF(WINSDK_SHARED_INCLUDE_DIR)
\r
479 SET(WINSDK_INCLUDE_DIRS ${WINSDK_INCLUDE_DIRS} ${WINSDK_SHARED_INCLUDE_DIR})
\r
482 SET(WINSDK_INCLUDE_DIRS ${WINSDK_INCLUDE_DIRS} ${WINSDK_INCLUDE_DIR})
\r
484 IF(WINSDK_OPENGL_INCLUDE_DIR)
\r
485 SET(WINSDK_INCLUDE_DIRS ${WINSDK_INCLUDE_DIRS} ${WINSDK_OPENGL_INCLUDE_DIR})
\r
488 IF(WINSDK_WINRT_INCLUDE_DIR)
\r
489 SET(WINSDK_INCLUDE_DIRS ${WINSDK_INCLUDE_DIRS} ${WINSDK_WINRT_INCLUDE_DIR})
\r
492 INCLUDE_DIRECTORIES(${WINSDK_INCLUDE_DIRS})
\r
494 IF(WINSDK_UCRT_LIBRARY_DIR)
\r
495 SET(CMAKE_LIBRARY_PATH ${WINSDK_UCRT_LIBRARY_DIR} ${CMAKE_LIBRARY_PATH})
\r
498 SET(CMAKE_LIBRARY_PATH ${WINSDK_LIBRARY_DIR} ${CMAKE_LIBRARY_PATH})
\r
500 # Fix for using Windows SDK 7.1 with Visual C++ 2012, 2013, 2015 and 2017
\r
501 IF(WINSDK_VERSION STREQUAL "7.1" AND (MSVC11 OR MSVC12 OR MSVC14))
\r
502 ADD_DEFINITIONS(-D_USING_V110_SDK71_)
\r
505 IF(NOT WindowsSDK_FIND_QUIETLY)
\r
506 MESSAGE(STATUS "Warning: Unable to find Windows SDK!")
\r