From 92bc8661df1ae080ea582c9bc134a9880a47bc5f Mon Sep 17 00:00:00 2001 From: kervala Date: Sun, 1 Oct 2017 15:19:24 +0200 Subject: [PATCH] Fixed: Support for Visual C++ 2017 and latest Windows 10 Kits --HG-- branch : develop --- code/CMakeModules/FindMSVC.cmake | 58 ++++++++++++- code/CMakeModules/FindWindowsSDK.cmake | 114 ++++++++++++++++--------- code/CMakeModules/nel.cmake | 7 ++ 3 files changed, 136 insertions(+), 43 deletions(-) diff --git a/code/CMakeModules/FindMSVC.cmake b/code/CMakeModules/FindMSVC.cmake index dceb6f054..706541463 100644 --- a/code/CMakeModules/FindMSVC.cmake +++ b/code/CMakeModules/FindMSVC.cmake @@ -5,6 +5,24 @@ # VC_LIBRARY_DIR - where to find libraries # VC_FOUND - True if MSVC found. +MACRO(ADD_TRAILING_SLASH _FILENAME_VAR) + # put content in a new variable + SET(_FILENAME ${${_FILENAME_VAR}}) + # get length of the string + STRING(LENGTH ${_FILENAME} _LEN) + # convert length to last pos + MATH(EXPR _POS "${_LEN}-1") + # get last character of the string + STRING(SUBSTRING ${_FILENAME} ${_POS} 1 _FILENAME_END) + # compare it with a slash + IF(NOT _FILENAME_END STREQUAL "/") + # not a slash, append it + SET(${_FILENAME_VAR} "${_FILENAME}/") + ELSE() + # already a slash + ENDIF() +ENDMACRO() + MACRO(DETECT_VC_VERSION_HELPER _ROOT _VERSION) # Software/Wow6432Node/... GET_FILENAME_COMPONENT(VC${_VERSION}_DIR "[${_ROOT}\\SOFTWARE\\Microsoft\\VisualStudio\\SxS\\VC7;${_VERSION}]" ABSOLUTE) @@ -12,7 +30,11 @@ MACRO(DETECT_VC_VERSION_HELPER _ROOT _VERSION) IF(VC${_VERSION}_DIR AND VC${_VERSION}_DIR STREQUAL "/registry") SET(VC${_VERSION}_DIR) GET_FILENAME_COMPONENT(VC${_VERSION}_DIR "[${_ROOT}\\SOFTWARE\\Microsoft\\VisualStudio\\SxS\\VS7;${_VERSION}]" ABSOLUTE) + IF(VC${_VERSION}_DIR AND NOT VC${_VERSION}_DIR STREQUAL "/registry") + # be sure it's finishing by a / + ADD_TRAILING_SLASH(VC${_VERSION}_DIR) + SET(VC${_VERSION}_DIR "${VC${_VERSION}_DIR}VC/") ENDIF() ENDIF() @@ -55,7 +77,34 @@ MACRO(DETECT_EXPRESS_VERSION _VERSION) ENDIF() ENDMACRO() -IF(MSVC14) +IF(MSVC1411 OR MSVC1410) + DETECT_VC_VERSION("15.0") + SET(MSVC_TOOLSET "140") + + SET(VC_DIR "${VC_DIR}Tools/MSVC") + + FILE(GLOB MSVC_TOOLCHAIN_VERSIONS RELATIVE ${VC_DIR} "${VC_DIR}/*") + + IF(MSVC_TOOLCHAIN_VERSIONS) + LIST(SORT MSVC_TOOLCHAIN_VERSIONS) + LIST(REVERSE MSVC_TOOLCHAIN_VERSIONS) + ENDIF() + + IF(NOT MSVC_TOOLCHAIN_VERSIONS) + MESSAGE(FATAL_ERROR "No MSVC version found in default search path ${VC_DIR}") + ENDIF() + + LIST(GET MSVC_TOOLCHAIN_VERSIONS 0 MSVC_TOOLCHAIN_VERSION) + + SET(VC_DIR "${VC_DIR}/${MSVC_TOOLCHAIN_VERSION}") + SET(VC_INCLUDE_DIR "${VC_DIR}/include") + + IF(NOT MSVC14_REDIST_DIR) + # If you have VC++ 2017 Express, put x64/Microsoft.VC141.CRT/*.dll in ${EXTERNAL_PATH}/redist + # original files whould be in ${VC_DIR}/Redist/MSVC/14.11.25325/x64/Microsoft.VC141.CRT + SET(MSVC14_REDIST_DIR "${EXTERNAL_PATH}/redist") + ENDIF() +ELSEIF(MSVC14) DETECT_VC_VERSION("14.0") SET(MSVC_TOOLSET "140") @@ -109,6 +158,11 @@ IF(NOT VC_DIR) STRING(REGEX REPLACE "/(bin|BIN|Bin)/.+" "" VC_DIR ${_COMPILER}) ENDIF() -SET(VC_INCLUDE_DIR "${VC_DIR}/include") +IF(NOT VC_INCLUDE_DIR) + SET(VC_INCLUDE_DIR "${VC_DIR}/include") +ENDIF() + +MESSAGE(STATUS "Using headers from ${VC_INCLUDE_DIR}") + SET(VC_INCLUDE_DIRS ${VC_INCLUDE_DIR}) INCLUDE_DIRECTORIES(${VC_INCLUDE_DIR}) diff --git a/code/CMakeModules/FindWindowsSDK.cmake b/code/CMakeModules/FindWindowsSDK.cmake index d7918816f..0e2735570 100644 --- a/code/CMakeModules/FindWindowsSDK.cmake +++ b/code/CMakeModules/FindWindowsSDK.cmake @@ -35,7 +35,7 @@ MACRO(DETECT_WINKIT_VERSION _VERSION _SUFFIX) SET(WINSDK${_VERSION}_FOUND ON) SET(WINSDK${_VERSION}_VERSION_FULL "${_VERSION}") IF(NOT WindowsSDK_FIND_QUIETLY) - MESSAGE(STATUS "Found Windows SDK ${_VERSION} in ${WINSDK${_VERSION}_DIR}") + MESSAGE(STATUS "Found Windows Kit ${_VERSION} in ${WINSDK${_VERSION}_DIR}") ENDIF() LIST(APPEND WINSDK_DETECTED_VERSIONS ${_VERSION}) ELSE() @@ -240,7 +240,11 @@ MACRO(USE_CURRENT_WINSDK) IF(NOT WINSDK_DIR) # Use Windows SDK versions installed with VC++ when possible - IF(MSVC14) + IF(MSVC1411 OR MSVC1410) + # 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") @@ -305,7 +309,7 @@ MACRO(USE_CURRENT_WINSDK) ENDMACRO() IF(MSVC14) - # Under VC++ 2015, stdio.h, stdlib.h, etc... are part of UCRT + # Under VC++ 2015 and 2017, stdio.h, stdlib.h, etc... are part of UCRT SET(WINSDK_UCRT_VERSION "10.0") ENDIF() @@ -314,6 +318,40 @@ 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() @@ -334,93 +372,87 @@ 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 ) +MESSAGE(STATUS "Found Windows.h in ${WINSDK_INCLUDE_DIR}") + # 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}) - SET(WINSDK_LIBRARY_DIRS ${WINSDK_LIBRARY_DIRS} ${WINSDK_DIR}/Lib/${_SUFFIX}) + LIST(APPEND WINSDK_LIBRARY_DIRS ${WINSDK_DIR}/Lib/${_SUFFIX}) ENDFOREACH() ELSE() - SET(WINSDK_LIBRARY_DIRS ${WINSDK_LIBRARY_DIRS} ${WINSDK_DIR}/Lib) + 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 ) -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) +MESSAGE(STATUS "Found ComCtl32.lib in ${WINSDK_LIBRARY_DIR}") - 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}") - - # directory where UCRT headers are found - FIND_PATH(WINSDK_UCRT_INCLUDE_DIR corecrt.h - HINTS - ${WINSDK_UCRT_INCLUDE_ROOT_DIR}/${UCRT_VERSION}/ucrt - ) - - # directory where UCRT libraries are found - FIND_PATH(WINSDK_UCRT_LIBRARY_DIR ucrt.lib - HINTS - ${WINSDK_UCRT_LIB_ROOT_DIR}/${UCRT_VERSION}/ucrt/${WINSDK8_SUFFIX} - ) - ENDIF() -ENDIF() +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_DIR}/Bin/${WINSDK8_SUFFIX} - ${WINSDK_DIR}/Bin/x86 - ${WINSDK_DIR}/Bin + ${WINSDK_BINARY_DIRS} + NO_DEFAULT_PATH ) # midl is used to generate IDL interfaces FIND_PROGRAM(WINSDK_MIDL midl HINTS - ${WINSDK_DIR}/Bin/${WINSDK8_SUFFIX} - ${WINSDK_DIR}/Bin/x86 - ${WINSDK_DIR}/Bin + ${WINSDK_BINARY_DIRS} + NO_DEFAULT_PATH ) IF(WINSDK_INCLUDE_DIR) @@ -444,7 +476,7 @@ IF(WINSDK_INCLUDE_DIR) SET(WINSDK_INCLUDE_DIRS ${WINSDK_INCLUDE_DIRS} ${WINSDK_WINRT_INCLUDE_DIR}) ENDIF() - INCLUDE_DIRECTORIES(${WINSDK_INCLUDE_DIRS}) # TODO: Move this after all other includes somehow... + INCLUDE_DIRECTORIES(${WINSDK_INCLUDE_DIRS}) IF(WINSDK_UCRT_LIBRARY_DIR) SET(CMAKE_LIBRARY_PATH ${WINSDK_UCRT_LIBRARY_DIR} ${CMAKE_LIBRARY_PATH}) diff --git a/code/CMakeModules/nel.cmake b/code/CMakeModules/nel.cmake index ed0847015..a8879fd4d 100644 --- a/code/CMakeModules/nel.cmake +++ b/code/CMakeModules/nel.cmake @@ -570,6 +570,13 @@ MACRO(NL_SETUP_BUILD) SET(RELEASE_CFLAGS "/Ox /GF /GS- ${RELEASE_CFLAGS}") # without inlining it's unusable, use custom optimizations again SET(DEBUG_CFLAGS "/Od /Ob1 /GF- ${DEBUG_CFLAGS}") + + # Special cases for VC++ 2017 + IF(MSVC_VERSION EQUAL "1911") + SET(MSVC1411 ON) + ELSEIF(MSVC_VERSION EQUAL "1910") + SET(MSVC1410 ON) + ENDIF() ELSEIF(MSVC12) ADD_PLATFORM_FLAGS("/Gy-") # /Ox is working with VC++ 2013, but custom optimizations don't exist