浏览代码

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()
Philip Lowman 14 年之前
父节点
当前提交
effb6bbfd7
共有 1 个文件被更改,包括 115 次插入25 次删除
  1. 115 25
      Modules/CMakeDetermineVSServicePack.cmake

+ 115 - 25
Modules/CMakeDetermineVSServicePack.cmake

@@ -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 <[email protected]>
+# Copyright 2010-2011 Aaron C. meadows <[email protected]>
 #
 # 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")