From f190869d59013d745a8019db3d6d26688dafd3f1 Mon Sep 17 00:00:00 2001 From: kervala Date: Fri, 11 Oct 2019 19:40:24 +0200 Subject: [PATCH] Fixed: Support for VC++ 2019 (don't use registry anymore but CMAKE_CXX_COMPILER instead) --HG-- branch : develop --- code/CMakeModules/FindMSVC.cmake | 169 ++++++++----------------- code/CMakeModules/FindWindowsSDK.cmake | 23 +++- 2 files changed, 71 insertions(+), 121 deletions(-) diff --git a/code/CMakeModules/FindMSVC.cmake b/code/CMakeModules/FindMSVC.cmake index 5dbc4f6a8..2a08a08bb 100644 --- a/code/CMakeModules/FindMSVC.cmake +++ b/code/CMakeModules/FindMSVC.cmake @@ -1,89 +1,55 @@ # - Find MS Visual C++ # +# VC_DIR - where to find Visual C++ # VC_INCLUDE_DIR - where to find headers # VC_INCLUDE_DIRS - where to find headers # 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) - - 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() +# VC_FOUND - True if MSVC found + +IF(CMAKE_CXX_COMPILER) + SET(_COMPILER ${CMAKE_CXX_COMPILER}) + SET(_VERSION ${CMAKE_CXX_COMPILER_VERSION}) +ELSEIF(CMAKE_C_COMPILER) + SET(_COMPILER ${CMAKE_C_COMPILER}) + SET(_VERSION ${CMAKE_C_COMPILER_VERSION}) +ELSE() + MESSAGE(FATAL_ERROR "No way to determine Visual C++ location") +ENDIF() - IF(VC${_VERSION}_DIR AND NOT VC${_VERSION}_DIR STREQUAL "/registry") - SET(VC${_VERSION}_FOUND ON) - DETECT_EXPRESS_VERSION(${_VERSION}) - IF(NOT MSVC_FIND_QUIETLY) - SET(_VERSION_STR ${_VERSION}) - IF(MSVC_EXPRESS) - SET(_VERSION_STR "${_VERSION_STR} Express") - ENDIF() - MESSAGE(STATUS "Found Visual C++ ${_VERSION_STR} in ${VC${_VERSION}_DIR}") - ENDIF() - ELSEIF(VC${_VERSION}_DIR AND NOT VC${_VERSION}_DIR STREQUAL "/registry") - SET(VC${_VERSION}_FOUND OFF) - SET(VC${_VERSION}_DIR "") +IF(MSVC_VERSION LESS 1910) + IF(MSVC_VERSION LESS 1500) + MESSAGE(FATAL_ERROR "Unsupported version of Visual C++ (minimum version is 2008)") + ELSEIF(MSVC_VERSION LESS 1600) + SET(MSVC_TOOLSET "90") + SET(_NAME "2008") + ELSEIF(MSVC_VERSION LESS 1700) + SET(MSVC_TOOLSET "100") + SET(_NAME "2010") + ELSEIF(MSVC_VERSION LESS 1800) + SET(MSVC_TOOLSET "110") + SET(_NAME "2012") + ELSEIF(MSVC_VERSION LESS 1900) + SET(MSVC_TOOLSET "120") + SET(_NAME "2013") + ELSE() + SET(MSVC_TOOLSET "140") + SET(_NAME "2015") ENDIF() -ENDMACRO() - -MACRO(DETECT_VC_VERSION _VERSION) - IF(NOT VC_FOUND) - SET(VC${_VERSION}_FOUND OFF) - DETECT_VC_VERSION_HELPER("HKEY_CURRENT_USER" ${_VERSION}) - IF(NOT VC${_VERSION}_FOUND) - DETECT_VC_VERSION_HELPER("HKEY_LOCAL_MACHINE" ${_VERSION}) - ENDIF() + STRING(REGEX REPLACE "/bin/.+" "" VC_DIR ${_COMPILER}) - IF(VC${_VERSION}_FOUND) - SET(VC_FOUND ON) - SET(VC_DIR "${VC${_VERSION}_DIR}") - ENDIF() - ENDIF() -ENDMACRO() - -MACRO(DETECT_EXPRESS_VERSION _VERSION) - GET_FILENAME_COMPONENT(MSVC_EXPRESS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\${_VERSION}\\Setup\\VC;ProductDir]" ABSOLUTE) + MESSAGE(STATUS "Found Visual C++ ${_NAME} (${_VERSION}) in ${VC_DIR}") +ELSE() + # Toolset = version of runtime DLLs + SET(MSVC_TOOLSET "140") - IF(MSVC_EXPRESS AND NOT MSVC_EXPRESS STREQUAL "/registry") - SET(MSVC_EXPRESS ON) + IF(MSVC_VERSION LESS 1920) + SET(_NAME "2017") + ELSE() + SET(_NAME "2019") ENDIF() -ENDMACRO() - -IF(MSVC_VERSION GREATER 1909) - DETECT_VC_VERSION("15.0") - SET(MSVC_TOOLSET "140") - SET(VC_DIR "${VC_DIR}Tools/MSVC") + STRING(REGEX REPLACE "/MSVC/.+" "/MSVC" VC_DIR ${_COMPILER}) FILE(GLOB MSVC_TOOLCHAIN_VERSIONS RELATIVE ${VC_DIR} "${VC_DIR}/*") @@ -92,48 +58,15 @@ IF(MSVC_VERSION GREATER 1909) 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") -ELSEIF(MSVC14) - DETECT_VC_VERSION("14.0") - SET(MSVC_TOOLSET "140") -ELSEIF(MSVC12) - DETECT_VC_VERSION("12.0") - SET(MSVC_TOOLSET "120") -ELSEIF(MSVC11) - DETECT_VC_VERSION("11.0") - SET(MSVC_TOOLSET "110") -ELSEIF(MSVC10) - DETECT_VC_VERSION("10.0") - SET(MSVC_TOOLSET "100") -ELSEIF(MSVC90) - DETECT_VC_VERSION("9.0") - SET(MSVC_TOOLSET "90") -ELSEIF(MSVC80) - DETECT_VC_VERSION("8.0") - SET(MSVC_TOOLSET "80") -ENDIF() + IF(MSVC_TOOLCHAIN_VERSIONS) + LIST(GET MSVC_TOOLCHAIN_VERSIONS 0 MSVC_TOOLCHAIN_VERSION) -# If you plan to use VC++ compilers with WINE, set VC_DIR environment variable -IF(NOT VC_DIR) - SET(VC_DIR $ENV{VC_DIR}) - # Fix path - FILE(TO_CMAKE_PATH ${VC_DIR} VC_DIR) -ENDIF() + SET(VC_DIR "${VC_DIR}/${MSVC_TOOLCHAIN_VERSION}") -IF(NOT VC_DIR) - IF(CMAKE_CXX_COMPILER) - SET(_COMPILER ${CMAKE_CXX_COMPILER}) + MESSAGE(STATUS "Found Visual C++ ${_NAME} (${_VERSION} with toolchain ${MSVC_TOOLCHAIN_VERSION}) in ${VC_DIR}") ELSE() - SET(_COMPILER ${CMAKE_C_COMPILER}) + MESSAGE(FATAL_ERROR "Unable to find Visual C++ in ${VC_DIR}") ENDIF() - STRING(REGEX REPLACE "/(bin|BIN|Bin)/.+" "" VC_DIR ${_COMPILER}) ENDIF() IF(NOT VC_INCLUDE_DIR AND VC_DIR AND EXISTS "${VC_DIR}") @@ -147,14 +80,14 @@ SET(MSVC_REDIST_DIR "${EXTERNAL_PATH}/redist") IF(NOT EXISTS "${MSVC_REDIST_DIR}") SET(MSVC_REDIST_DIR "${VC_DIR}/redist") - + IF(NOT EXISTS "${MSVC_REDIST_DIR}") SET(MSVC_REDIST_DIR) ENDIF() ENDIF() IF(MSVC_REDIST_DIR) - IF(MSVC1411 OR MSVC1410) + IF(MSVC_VERSION GREATER 1909) # 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 "${MSVC_REDIST_DIR}") @@ -167,7 +100,7 @@ IF(MSVC_REDIST_DIR) # If you have VC++ 2012 Express, put x64/Microsoft.VC110.CRT/*.dll in ${EXTERNAL_PATH}/redist SET(MSVC11_REDIST_DIR "${MSVC_REDIST_DIR}") ELSEIF(MSVC10) - # If you have VC++ 2010 Express, put x64/Microsoft.VC100.CRT/*.dll in ${EXTERNAL_PATH}/redist + # If you have VC++ 2010 Express, put x64/Microsoft.VC100.CRT/*.dll in ${EXTERNAL_PATH}/redist SET(MSVC10_REDIST_DIR "${MSVC_REDIST_DIR}") ELSEIF(MSVC90) SET(MSVC90_REDIST_DIR "${MSVC_REDIST_DIR}") @@ -176,7 +109,11 @@ IF(MSVC_REDIST_DIR) ENDIF() ENDIF() -MESSAGE(STATUS "Using headers from ${VC_INCLUDE_DIR}") +IF(VC_INCLUDE_DIR) + MESSAGE(STATUS "Using VC++ headers from ${VC_INCLUDE_DIR}") +ELSE() + MESSAGE(FATAL_ERROR "Unable to find VC++ headers") +ENDIF() 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 3d9c43bd9..1b02dffb3 100644 --- a/code/CMakeModules/FindWindowsSDK.cmake +++ b/code/CMakeModules/FindWindowsSDK.cmake @@ -20,6 +20,7 @@ MACRO(DETECT_WINSDK_VERSION_HELPER _ROOT _VERSION) 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() @@ -28,14 +29,14 @@ MACRO(DETECT_WINSDK_VERSION_HELPER _ROOT _VERSION) ENDIF() ENDMACRO() -MACRO(DETECT_WINKIT_VERSION _VERSION _SUFFIX) - GET_FILENAME_COMPONENT(WINSDK${_VERSION}_DIR "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots;KitsRoot${_SUFFIX}]" ABSOLUTE) +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") + 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}") + MESSAGE(STATUS "Found Windows Kit ${_VERSION} in ${WINSDK${_VERSION}_DIR} (registry ${_ARCH} bits)") ENDIF() LIST(APPEND WINSDK_DETECTED_VERSIONS ${_VERSION}) ELSE() @@ -52,6 +53,14 @@ MACRO(DETECT_WINSDK_VERSION _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) @@ -378,7 +387,11 @@ FIND_PATH(WINSDK_INCLUDE_DIR Windows.h NO_DEFAULT_PATH ) -MESSAGE(STATUS "Found Windows.h in ${WINSDK_INCLUDE_DIR}") +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