You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ryzom-core/CMakeModules/FindWindowsSDK.cmake

520 lines
15 KiB
CMake

# - Find Windows Platform SDK
# Find the Windows includes
#
# WINSDK_INCLUDE_DIR - where to find Windows.h
# WINSDK_INCLUDE_DIRS - where to find all Windows headers
# WINSDK_LIBRARY_DIR - where to find libraries
# WINSDK_FOUND - True if Windows SDK found.
IF(WINSDK_FOUND)
# If Windows SDK already found, skip it
RETURN()
ENDIF()
# Values can be CURRENT or any existing versions 7.1, 8.0A, etc...
SET(WINSDK_VERSION "CURRENT" CACHE STRING "Windows SDK version to prefer")
MACRO(DETECT_WINSDK_VERSION_HELPER _ROOT _VERSION)
GET_FILENAME_COMPONENT(WINSDK${_VERSION}_DIR "[${_ROOT}\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\v${_VERSION};InstallationFolder]" ABSOLUTE)
IF(WINSDK${_VERSION}_DIR AND NOT WINSDK${_VERSION}_DIR STREQUAL "/registry" AND EXISTS "${WINSDK${_VERSION}_DIR}/Include")
SET(WINSDK${_VERSION}_FOUND ON)
GET_FILENAME_COMPONENT(WINSDK${_VERSION}_VERSION_FULL "[${_ROOT}\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\v${_VERSION};ProductVersion]" NAME)
IF(NOT WindowsSDK_FIND_QUIETLY)
MESSAGE(STATUS "Found Windows SDK ${_VERSION} in ${WINSDK${_VERSION}_DIR}")
ENDIF()
ELSE()
SET(WINSDK${_VERSION}_DIR "")
ENDIF()
ENDMACRO()
MACRO(DETECT_WINKIT_VERSION_HELPER _VERSION _SUFFIX _PREFIX _ARCH)
GET_FILENAME_COMPONENT(WINSDK${_VERSION}_DIR "[HKEY_LOCAL_MACHINE\\SOFTWARE\\${_PREFIX}Microsoft\\Windows Kits\\Installed Roots;KitsRoot${_SUFFIX}]" ABSOLUTE)
IF(WINSDK${_VERSION}_DIR AND NOT WINSDK${_VERSION}_DIR STREQUAL "/registry" AND EXISTS "${WINSDK${_VERSION}_DIR}/Include")
SET(WINSDK${_VERSION}_FOUND ON)
SET(WINSDK${_VERSION}_VERSION_FULL "${_VERSION}")
IF(NOT WindowsSDK_FIND_QUIETLY)
MESSAGE(STATUS "Found Windows Kit ${_VERSION} in ${WINSDK${_VERSION}_DIR} (registry ${_ARCH} bits)")
ENDIF()
LIST(APPEND WINSDK_DETECTED_VERSIONS ${_VERSION})
ELSE()
SET(WINSDK${_VERSION}_DIR "")
ENDIF()
ENDMACRO()
MACRO(DETECT_WINSDK_VERSION _VERSION)
SET(WINSDK${_VERSION}_FOUND OFF)
DETECT_WINSDK_VERSION_HELPER("HKEY_CURRENT_USER" ${_VERSION})
IF(NOT WINSDK${_VERSION}_FOUND)
DETECT_WINSDK_VERSION_HELPER("HKEY_LOCAL_MACHINE" ${_VERSION})
ENDIF()
ENDMACRO()
MACRO(DETECT_WINKIT_VERSION _VERSION _SUFFIX)
DETECT_WINKIT_VERSION_HELPER("${_VERSION}" "${_SUFFIX}" "WOW6432Node\\\\" "32")
IF(NOT WINSDK${_VERSION}_FOUND)
DETECT_WINKIT_VERSION_HELPER("${_VERSION}" "${_SUFFIX}" "" "64")
ENDIF()
ENDMACRO()
SET(WINSDK_DETECTED_VERSIONS)
# Fixed versions for Windows Kits (VC++ from 2012)
DETECT_WINKIT_VERSION("10.0" "10")
DETECT_WINKIT_VERSION("8.1" "81")
DETECT_WINKIT_VERSION("8.0" "")
# For VC++ up to 2010
SET(WINSDK_VERSIONS "7.1" "7.1A" "7.0" "7.0A" "6.1" "6.0" "6.0A")
# Search all supported Windows SDKs
FOREACH(_VERSION ${WINSDK_VERSIONS})
DETECT_WINSDK_VERSION(${_VERSION})
IF(WINSDK${_VERSION}_FOUND)
LIST(APPEND WINSDK_DETECTED_VERSIONS ${_VERSION})
ENDIF()
ENDFOREACH()
SET(WINSDK_SUFFIXES)
IF(TARGET_ARM64)
SET(WINSDK8_SUFFIX "arm64")
ELSEIF(TARGET_ARM)
SET(WINSDK8_SUFFIX "arm")
ELSEIF(TARGET_X64)
SET(WINSDK8_SUFFIX "x64")
SET(WINSDK_SUFFIXES "x64" "amd64")
ELSEIF(TARGET_X86)
SET(WINSDK8_SUFFIX "x86")
ENDIF()
SET(WINSDKCURRENT_VERSION_INCLUDE $ENV{INCLUDE})
IF(WINSDKCURRENT_VERSION_INCLUDE)
FILE(TO_CMAKE_PATH "${WINSDKCURRENT_VERSION_INCLUDE}" WINSDKCURRENT_VERSION_INCLUDE)
ENDIF()
SET(WINSDKENV_DIR $ENV{WINSDK_DIR})
IF(NOT WINSDKENV_DIR)
SET(WINSDKENV_DIR $ENV{WindowsSDKDir})
ENDIF()
MACRO(FIND_WINSDK_VERSION_HEADERS)
IF(WINSDK_DIR AND NOT WINSDK_VERSION)
# Search version in headers
FIND_FILE(_MSI_FILE Msi.h
PATHS
${WINSDK_DIR}/Include/um
${WINSDK_DIR}/Include
)
IF(_MSI_FILE)
IF(NOT WINSDK_VERSION)
# Look for Windows SDK 8.1
FILE(STRINGS ${_MSI_FILE} _CONTENT REGEX "^#ifndef NTDDI_WINBLUE")
IF(_CONTENT)
SET(WINSDK_VERSION "8.1")
ENDIF()
ENDIF()
IF(NOT WINSDK_VERSION)
# Look for Windows SDK 8.0
FILE(STRINGS ${_MSI_FILE} _CONTENT REGEX "^#ifndef NTDDI_WIN8")
IF(_CONTENT)
SET(WINSDK_VERSION "8.0")
ENDIF()
ENDIF()
IF(NOT WINSDK_VERSION)
# Look for Windows SDK 7.0
FILE(STRINGS ${_MSI_FILE} _CONTENT REGEX "^#ifndef NTDDI_WIN7")
IF(_CONTENT)
FIND_FILE(_WINSDKVER_FILE winsdkver.h WinSDKVer.h
PATHS
${WINSDK_DIR}/Include/um
${WINSDK_DIR}/Include
)
IF(_WINSDKVER_FILE)
# Load WinSDKVer.h content
FILE(STRINGS ${_WINSDKVER_FILE} _CONTENT REGEX "^#define NTDDI_MAXVER")
# Get NTDDI_MAXVER value
STRING(REGEX REPLACE "^.*0x([0-9A-Fa-f]+).*$" "\\1" _WINSDKVER "${_CONTENT}")
# In Windows SDK 7.1, NTDDI_MAXVER is wrong
IF(_WINSDKVER STREQUAL "06010000")
SET(WINSDK_VERSION "7.1")
ELSEIF(_WINSDKVER STREQUAL "0601")
SET(WINSDK_VERSION "7.0A")
ELSE()
MESSAGE(FATAL_ERROR "Can't determine Windows SDK version with NTDDI_MAXVER 0x${_WINSDKVER}")
ENDIF()
ELSE()
SET(WINSDK_VERSION "7.0")
ENDIF()
ENDIF()
ENDIF()
IF(NOT WINSDK_VERSION)
# Look for Windows SDK 6.0
FILE(STRINGS ${_MSI_FILE} _CONTENT REGEX "^#ifndef NTDDI_VISTA")
IF(_CONTENT)
SET(WINSDK_VERSION "6.0")
ENDIF()
ENDIF()
IF(NOT WINSDK_VERSION)
# Look for Windows SDK 5.2
FILE(STRINGS ${_MSI_FILE} _CONTENT REGEX "^#ifndef NTDDI_WS03SP1")
IF(_CONTENT)
SET(WINSDK_VERSION "5.2")
ENDIF()
ENDIF()
IF(NOT WINSDK_VERSION)
# Look for Windows SDK 5.1
FILE(STRINGS ${_MSI_FILE} _CONTENT REGEX "^#ifndef NTDDI_WINXP")
IF(_CONTENT)
SET(WINSDK_VERSION "5.1")
ENDIF()
ENDIF()
IF(NOT WINSDK_VERSION)
# Look for Windows SDK 5.0
FILE(STRINGS ${_MSI_FILE} _CONTENT REGEX "^#ifndef NTDDI_WIN2K")
IF(_CONTENT)
SET(WINSDK_VERSION "5.0")
ENDIF()
ENDIF()
ELSE()
MESSAGE(FATAL_ERROR "Unable to find Msi.h in ${WINSDK_DIR}")
ENDIF()
ENDIF()
ENDMACRO()
MACRO(USE_CURRENT_WINSDK)
SET(WINSDK_DIR "")
SET(WINSDK_VERSION "")
SET(WINSDK_VERSION_FULL "")
# Use WINSDK environment variable
IF(WINSDKENV_DIR)
FIND_PATH(WINSDK_DIR Windows.h
HINTS
${WINSDKENV_DIR}/Include/um
${WINSDKENV_DIR}/Include
)
ENDIF()
# Use INCLUDE environment variable
IF(NOT WINSDK_DIR AND WINSDKCURRENT_VERSION_INCLUDE)
FOREACH(_INCLUDE ${WINSDKCURRENT_VERSION_INCLUDE})
FILE(TO_CMAKE_PATH ${_INCLUDE} _INCLUDE)
# Look for Windows.h because there are several paths
IF(EXISTS ${_INCLUDE}/Windows.h)
STRING(REGEX REPLACE "/(include|INCLUDE|Include)(.*)" "" WINSDK_DIR ${_INCLUDE})
MESSAGE(STATUS "Found Windows SDK in INCLUDE environment variable: ${WINSDK_DIR}")
BREAK()
ENDIF()
ENDFOREACH()
ENDIF()
IF(WINSDK_DIR)
# Compare WINSDK_DIR with registered Windows SDKs
FOREACH(_VERSION ${WINSDK_DETECTED_VERSIONS})
IF(WINSDK_DIR STREQUAL "${WINSDK${_VERSION}_DIR}")
SET(WINSDK_VERSION ${_VERSION})
SET(WINSDK_VERSION_FULL "${WINSDK${WINSDK_VERSION}_VERSION_FULL}")
BREAK()
ENDIF()
ENDFOREACH()
FIND_WINSDK_VERSION_HEADERS()
ENDIF()
IF(NOT WINSDK_DIR)
# Use Windows SDK versions installed with VC++ when possible
IF(MSVC_VERSION GREATER 1909)
# Special case, use Kits for SDK
SET(WINSDK_VERSION "10.0")
SET(WINSDK_DIR ${WINSDK_UCRT_DIR})
ELSEIF(MSVC14)
SET(WINSDK_VERSION "8.1")
ELSEIF(MSVC12)
SET(WINSDK_VERSION "8.1")
ELSEIF(MSVC11)
SET(WINSDK_VERSION "8.0")
ELSEIF(MSVC10)
IF(NOT TARGET_X64 OR NOT MSVC_EXPRESS)
SET(WINSDK_VERSION "7.0A")
ENDIF()
ELSEIF(MSVC90)
IF(NOT MSVC_EXPRESS)
SET(WINSDK_VERSION "6.0A")
ENDIF()
ELSEIF(MSVC80)
SET(WINSDK_MSVC80_COMPATIBLES "7.1" "7.1A" "7.0" "7.0A" "6.1" "6.0" "6.0A" "5.2A")
# look for each Windows SDK supported by VC++ 2005 (7.1 is the latest)
FOREACH(_VERSION ${WINSDK_DETECTED_VERSIONS})
# look if this version of Windows SDK is installed
LIST(FIND WINSDK_MSVC80_COMPATIBLES ${_VERSION} _FOUND)
IF(NOT _FOUND EQUAL -1)
SET(WINSDK_VERSION "${_VERSION}")
BREAK()
ENDIF()
ENDFOREACH()
IF(NOT MSVC_EXPRESS AND NOT WINSDK_VERSION)
SET(WINSDK_VERSION "5.2A")
ENDIF()
ELSE()
MESSAGE(FATAL_ERROR "Your compiler is either too old or too recent, please update this CMake module.")
ENDIF()
# Use installed Windows SDK
IF(NOT WINSDK_VERSION)
IF(WINSDK8.1_FOUND)
SET(WINSDK_VERSION "8.1")
ELSEIF(WINSDK8.0_FOUND)
SET(WINSDK_VERSION "8.0")
ELSEIF(WINSDK7.1_FOUND)
SET(WINSDK_VERSION "7.1")
ELSEIF(WINSDK7.0_FOUND)
SET(WINSDK_VERSION "7.0")
ELSEIF(WINSDK6.1_FOUND)
SET(WINSDK_VERSION "6.1")
ELSEIF(WINSDK6.0_FOUND)
SET(WINSDK_VERSION "6.0")
ELSE()
MESSAGE(FATAL_ERROR "You have no compatible Windows SDK installed.")
ENDIF()
ENDIF()
# Look for correct registered Windows SDK version
FOREACH(_VERSION ${WINSDK_DETECTED_VERSIONS})
IF(WINSDK_VERSION STREQUAL _VERSION)
SET(WINSDK_VERSION_FULL "${WINSDK${WINSDK_VERSION}_VERSION_FULL}")
SET(WINSDK_DIR "${WINSDK${WINSDK_VERSION}_DIR}")
BREAK()
ENDIF()
ENDFOREACH()
ENDIF()
ENDMACRO()
IF(MSVC14)
# Under VC++ 2015 and 2017, stdio.h, stdlib.h, etc... are part of UCRT
SET(WINSDK_UCRT_VERSION "10.0")
ENDIF()
# Look for correct UCRT
IF(WINSDK_UCRT_VERSION AND WINSDK${WINSDK_UCRT_VERSION}_FOUND)
SET(WINSDK_UCRT_DIR "${WINSDK${WINSDK_UCRT_VERSION}_DIR}")
ENDIF()
IF(WINSDK_UCRT_DIR)
# determine exact UCRT version
SET(WINSDK_UCRT_INCLUDE_ROOT_DIR ${WINSDK_UCRT_DIR}/Include)
SET(WINSDK_UCRT_LIB_ROOT_DIR ${WINSDK_UCRT_DIR}/Lib)
FILE(GLOB UCRT_SUBDIRS RELATIVE ${WINSDK_UCRT_INCLUDE_ROOT_DIR} ${WINSDK_UCRT_INCLUDE_ROOT_DIR}/*)
SET(UCRT_VERSION)
FOREACH(UCRT_SUBDIR ${UCRT_SUBDIRS})
IF(NOT UCRT_VERSION OR UCRT_SUBDIR VERSION_GREATER UCRT_VERSION)
SET(UCRT_VERSION ${UCRT_SUBDIR})
ENDIF()
ENDFOREACH()
IF(UCRT_VERSION)
MESSAGE(STATUS "Using Windows UCRT ${UCRT_VERSION}")
SET(WINSDK10_INCLUDE_DIR ${WINSDK_UCRT_INCLUDE_ROOT_DIR}/${UCRT_VERSION})
SET(WINSDK10_LIBRARY_DIR ${WINSDK_UCRT_LIB_ROOT_DIR}/${UCRT_VERSION})
# directory where UCRT headers are found
FIND_PATH(WINSDK_UCRT_INCLUDE_DIR corecrt.h
HINTS
${WINSDK10_INCLUDE_DIR}/ucrt
)
# directory where UCRT libraries are found
FIND_PATH(WINSDK_UCRT_LIBRARY_DIR ucrt.lib
HINTS
${WINSDK10_LIBRARY_DIR}/ucrt/${WINSDK8_SUFFIX}
)
ENDIF()
ENDIF()
IF(WINSDK_VERSION STREQUAL "CURRENT")
USE_CURRENT_WINSDK()
ELSE()
IF(WINSDK${WINSDK_VERSION}_FOUND)
SET(WINSDK_VERSION_FULL "${WINSDK${WINSDK_VERSION}_VERSION_FULL}")
SET(WINSDK_DIR "${WINSDK${WINSDK_VERSION}_DIR}")
ELSE()
USE_CURRENT_WINSDK()
ENDIF()
ENDIF()
IF(WINSDK_DIR)
MESSAGE(STATUS "Using Windows SDK ${WINSDK_VERSION}")
ELSE()
MESSAGE(FATAL_ERROR "Unable to find Windows SDK!")
ENDIF()
# directory where Win32 headers are found
FIND_PATH(WINSDK_INCLUDE_DIR Windows.h
HINTS
${WINSDK_DIR}/Include/${UCRT_VERSION}/um
${WINSDK_DIR}/Include/um
${WINSDK_DIR}/Include
NO_DEFAULT_PATH
)
IF(WINSDK_INCLUDE_DIR)
MESSAGE(STATUS "Found Windows.h in ${WINSDK_INCLUDE_DIR}")
ELSE()
MESSAGE(FATAL_ERROR "Unable to find Windows.h")
ENDIF()
# directory where WinRT headers are found
FIND_PATH(WINSDK_WINRT_INCLUDE_DIR winstring.h
HINTS
${WINSDK_DIR}/Include/${UCRT_VERSION}/winrt
${WINSDK_DIR}/Include/winrt
NO_DEFAULT_PATH
)
MESSAGE(STATUS "Found winstring.h in ${WINSDK_WINRT_INCLUDE_DIR}")
# directory where DirectX headers are found
FIND_PATH(WINSDK_SHARED_INCLUDE_DIR d3d9.h
HINTS
${WINSDK_DIR}/Include/${UCRT_VERSION}/shared
${WINSDK_DIR}/Include/shared
NO_DEFAULT_PATH
)
MESSAGE(STATUS "Found d3d9.h in ${WINSDK_SHARED_INCLUDE_DIR}")
# directory where OpenGL headers are found
FIND_PATH(WINSDK_OPENGL_INCLUDE_DIR GL.h
HINTS
${WINSDK_INCLUDE_DIR}/gl
${WINSDK_DIR}/Include/um/gl
${WINSDK_DIR}/Include/gl
NO_DEFAULT_PATH
)
MESSAGE(STATUS "Found GL.h in ${WINSDK_OPENGL_INCLUDE_DIR}")
SET(WINSDK_LIBRARY_DIRS
${WINSDK_DIR}/Lib/${UCRT_VERSION}/um/${WINSDK8_SUFFIX}
${WINSDK_DIR}/Lib/winv6.3/um/${WINSDK8_SUFFIX}
${WINSDK_DIR}/Lib/win8/um/${WINSDK8_SUFFIX}
)
IF(WINSDK_SUFFIXES)
FOREACH(_SUFFIX ${WINSDK_SUFFIXES})
LIST(APPEND WINSDK_LIBRARY_DIRS ${WINSDK_DIR}/Lib/${_SUFFIX})
ENDFOREACH()
ELSE()
LIST(APPEND WINSDK_LIBRARY_DIRS ${WINSDK_DIR}/Lib)
ENDIF()
# directory where all libraries are found
FIND_PATH(WINSDK_LIBRARY_DIR ComCtl32.lib
HINTS
${WINSDK_LIBRARY_DIRS}
NO_DEFAULT_PATH
)
MESSAGE(STATUS "Found ComCtl32.lib in ${WINSDK_LIBRARY_DIR}")
SET(WINSDK_BINARY_DIRS
${WINSDK_DIR}/Bin/${UCRT_VERSION}/${WINSDK8_SUFFIX}
${WINSDK_DIR}/Bin/${WINSDK8_SUFFIX}
${WINSDK_DIR}/Bin/x86
${WINSDK_DIR}/Bin
)
# signtool is used to sign executables
FIND_PROGRAM(WINSDK_SIGNTOOL signtool
HINTS
${WINSDK_BINARY_DIRS}
NO_DEFAULT_PATH
)
# midl is used to generate IDL interfaces
FIND_PROGRAM(WINSDK_MIDL midl
HINTS
${WINSDK_BINARY_DIRS}
NO_DEFAULT_PATH
)
IF(WINSDK_INCLUDE_DIR)
SET(WINSDK_FOUND ON)
IF(WINSDK_UCRT_INCLUDE_DIR)
SET(WINSDK_INCLUDE_DIRS ${WINSDK_INCLUDE_DIRS} ${WINSDK_UCRT_INCLUDE_DIR})
ENDIF()
IF(WINSDK_SHARED_INCLUDE_DIR)
SET(WINSDK_INCLUDE_DIRS ${WINSDK_INCLUDE_DIRS} ${WINSDK_SHARED_INCLUDE_DIR})
ENDIF()
SET(WINSDK_INCLUDE_DIRS ${WINSDK_INCLUDE_DIRS} ${WINSDK_INCLUDE_DIR})
IF(WINSDK_OPENGL_INCLUDE_DIR)
SET(WINSDK_INCLUDE_DIRS ${WINSDK_INCLUDE_DIRS} ${WINSDK_OPENGL_INCLUDE_DIR})
ENDIF()
IF(WINSDK_WINRT_INCLUDE_DIR)
SET(WINSDK_INCLUDE_DIRS ${WINSDK_INCLUDE_DIRS} ${WINSDK_WINRT_INCLUDE_DIR})
ENDIF()
INCLUDE_DIRECTORIES(${WINSDK_INCLUDE_DIRS})
IF(WINSDK_UCRT_LIBRARY_DIR)
SET(CMAKE_LIBRARY_PATH ${WINSDK_UCRT_LIBRARY_DIR} ${CMAKE_LIBRARY_PATH})
ENDIF()
SET(CMAKE_LIBRARY_PATH ${WINSDK_LIBRARY_DIR} ${CMAKE_LIBRARY_PATH})
# Fix for using Windows SDK 7.1 with Visual C++ 2012, 2013, 2015 and 2017
IF(WINSDK_VERSION STREQUAL "7.1" AND (MSVC11 OR MSVC12 OR MSVC14))
ADD_DEFINITIONS(-D_USING_V110_SDK71_)
ENDIF()
IF(NOT DXSDK_DIR)
MESSAGE("Using DirectX from Windows SDK (${WINSDK_LIBRARY_DIRS})")
SET(DXSDK_DIR ${WINSDK_DIR})
FIND_LIBRARY(DXSDK_GUID_LIBRARY dxguid ${WINSDK_LIBRARY_DIRS})
FIND_LIBRARY(DXSDK_DINPUT_LIBRARY dinput8 ${WINSDK_LIBRARY_DIRS})
FIND_LIBRARY(DXSDK_DSOUND_LIBRARY dsound ${WINSDK_LIBRARY_DIRS})
FIND_LIBRARY(DXSDK_XAUDIO_LIBRARY xaudio2 ${WINSDK_LIBRARY_DIRS})
# TODO: FIND_LIBRARY(DXSDK_D3DX9_LIBRARY d3dx9)
FIND_LIBRARY(DXSDK_D3D9_LIBRARY d3d9 ${WINSDK_LIBRARY_DIRS})
ENDIF()
ELSE()
IF(NOT WindowsSDK_FIND_QUIETLY)
MESSAGE(STATUS "Warning: Unable to find Windows SDK!")
ENDIF()
ENDIF()