Detect VS 2010 SP1, faster and more robust detection

Patch from Aaron C. Meadows
Adds support for detecting VS 2010 SP1
Also improves performance using CMAKE_CXX_COMPILER if it is available
and for robustness falls back using try_compile() and try_run()
This commit is contained in:
Philip Lowman 2011-06-15 08:33:40 -04:00
parent cc746a6eb7
commit effb6bbfd7
1 changed files with 114 additions and 24 deletions

View File

@ -7,6 +7,8 @@
# vc80sp1
# vc90
# vc90sp1
# vc100
# vc100sp1
#
# Usage:
# ===========================
@ -23,8 +25,9 @@
# ===========================
#=============================================================================
# Copyright 2009-2010 Kitware, Inc.
# Copyright 2009-2011 Kitware, Inc.
# Copyright 2009-2010 Philip Lowman <philip@yhbt.com>
# Copyright 2010-2011 Aaron C. meadows <cmake@shadowguarddev.com>
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
@ -49,43 +52,130 @@ function(_DetermineVSServicePackFromCompiler _OUT_VAR _cl_version)
set(_version "vc90sp1")
elseif(${_cl_version} VERSION_EQUAL "16.00.30319.01")
set(_version "vc100")
elseif(${_cl_version} VERSION_EQUAL "16.00.40219.01")
set(_version "vc100sp1")
else()
set(_version "")
endif()
set(${_OUT_VAR} ${_version} PARENT_SCOPE)
endfunction()
############################################################
# [INTERNAL]
# Please do not call this function directly
function(_DetermineVSServicePack_FastCheckVersionWithCompiler _SUCCESS_VAR _VERSION_VAR)
if(EXISTS ${CMAKE_CXX_COMPILER})
execute_process(
COMMAND ${CMAKE_CXX_COMPILER} /?
ERROR_VARIABLE _output
OUTPUT_QUIET
)
string(REGEX MATCH "Compiler Version [0-9]+.[0-9]+.[0-9]+.[0-9]+"
_cl_version "${_output}")
if(_cl_version)
string(REGEX MATCHALL "[0-9]+"
_cl_version_list "${_cl_version}")
list(GET _cl_version_list 0 _major)
list(GET _cl_version_list 1 _minor)
list(GET _cl_version_list 2 _patch)
list(GET _cl_version_list 3 _tweak)
if("${_major}${_minor}" STREQUAL "${MSVC_VERSION}")
set(_cl_version ${_major}.${_minor}.${_patch}.${_tweak})
else()
unset(_cl_version)
endif()
endif()
if(_cl_version)
set(${_SUCCESS_VAR} true PARENT_SCOPE)
set(${_VERSION_VAR} ${_cl_version} PARENT_SCOPE)
endif()
endif()
endfunction()
############################################################
# [INTERNAL]
# Please do not call this function directly
function(_DetermineVSServicePack_CheckVersionWithTryCompile _SUCCESS_VAR _VERSION_VAR)
file(WRITE "${CMAKE_BINARY_DIR}/return0.cc"
"int main() { return 0; }\n")
try_compile(
_CompileResult
"${CMAKE_BINARY_DIR}"
"${CMAKE_BINARY_DIR}/return0.cc"
OUTPUT_VARIABLE _output
COPY_FILE "${CMAKE_BINARY_DIR}/return0.cc")
file(REMOVE "${CMAKE_BINARY_DIR}/return0.cc")
string(REGEX MATCH "Compiler Version [0-9]+.[0-9]+.[0-9]+.[0-9]+"
_cl_version "${_output}")
if(_cl_version)
string(REGEX MATCHALL "[0-9]+"
_cl_version_list "${_cl_version}")
list(GET _cl_version_list 0 _major)
list(GET _cl_version_list 1 _minor)
list(GET _cl_version_list 2 _patch)
list(GET _cl_version_list 3 _tweak)
set(${_SUCCESS_VAR} true PARENT_SCOPE)
set(${_VERSION_VAR} ${_major}.${_minor}.${_patch}.${_tweak} PARENT_SCOPE)
endif()
endfunction()
############################################################
# [INTERNAL]
# Please do not call this function directly
function(_DetermineVSServicePack_CheckVersionWithTryRun _SUCCESS_VAR _VERSION_VAR)
file(WRITE "${CMAKE_BINARY_DIR}/return0.cc"
"#include <stdio.h>\n\nconst unsigned int CompilerVersion=_MSC_FULL_VER;\n\nint main(int argc, char* argv[])\n{\n int M( CompilerVersion/10000000);\n int m((CompilerVersion%10000000)/100000);\n int b(CompilerVersion%100000);\n\n printf(\"%d.%02d.%05d.01\",M,m,b);\n return 0;\n}\n")
try_run(
_RunResult
_CompileResult
"${CMAKE_BINARY_DIR}"
"${CMAKE_BINARY_DIR}/return0.cc"
RUN_OUTPUT_VARIABLE _runoutput
)
file(REMOVE "${CMAKE_BINARY_DIR}/return0.cc")
string(REGEX MATCH "[0-9]+.[0-9]+.[0-9]+.[0-9]+"
_cl_version "${_runoutput}")
if(_cl_version)
set(${_SUCCESS_VAR} true PARENT_SCOPE)
set(${_VERSION_VAR} ${_cl_version} PARENT_SCOPE)
endif()
endfunction()
#
# A function to call to determine the Visual Studio service pack
# in use. See documentation above.
function(DetermineVSServicePack _pack)
if(NOT DETERMINED_VS_SERVICE_PACK OR NOT ${_pack})
file(WRITE "${CMAKE_BINARY_DIR}/return0.cc"
"int main() { return 0; }\n")
try_compile(DETERMINED_VS_SERVICE_PACK
"${CMAKE_BINARY_DIR}"
"${CMAKE_BINARY_DIR}/return0.cc"
OUTPUT_VARIABLE _output
COPY_FILE "${CMAKE_BINARY_DIR}/return0.cc")
file(REMOVE "${CMAKE_BINARY_DIR}/return0.cc")
if(DETERMINED_VS_SERVICE_PACK AND _output)
string(REGEX MATCH "Compiler Version [0-9]+.[0-9]+.[0-9]+.[0-9]+"
_cl_version "${_output}")
_DetermineVSServicePack_FastCheckVersionWithCompiler(DETERMINED_VS_SERVICE_PACK _cl_version)
if(NOT DETERMINED_VS_SERVICE_PACK)
_DetermineVSServicePack_CheckVersionWithTryCompile(DETERMINED_VS_SERVICE_PACK _cl_version)
if(NOT DETERMINED_VS_SERVICE_PACK)
_DetermineVSServicePack_CheckVersionWithTryRun(DETERMINED_VS_SERVICE_PACK _cl_version)
endif()
endif()
if(DETERMINED_VS_SERVICE_PACK)
if(_cl_version)
string(REGEX MATCHALL "[0-9]+"
_cl_version_list "${_cl_version}")
list(GET _cl_version_list 0 _major)
list(GET _cl_version_list 1 _minor)
list(GET _cl_version_list 2 _patch)
list(GET _cl_version_list 3 _tweak)
set(_cl_version_string ${_major}.${_minor}.${_patch}.${_tweak})
# Call helper function to determine VS version
_DetermineVSServicePackFromCompiler(_sp "${_cl_version_string}")
_DetermineVSServicePackFromCompiler(_sp "${_cl_version}")
if(_sp)
set(${_pack} ${_sp} CACHE INTERNAL
"The Visual Studio Release with Service Pack")