1# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2# file Copyright.txt or https://cmake.org/licensing for details.
3
4#[=======================================================================[.rst:
5CMakeDetermineVSServicePack
6---------------------------
7
8.. deprecated:: 3.0
9
10  Do not use.
11
12The functionality of this module has been superseded by the
13:variable:`CMAKE_<LANG>_COMPILER_VERSION` variable that contains
14the compiler version number.
15
16Determine the Visual Studio service pack of the 'cl' in use.
17
18Usage::
19
20  if(MSVC)
21    include(CMakeDetermineVSServicePack)
22    DetermineVSServicePack( my_service_pack )
23    if( my_service_pack )
24      message(STATUS "Detected: ${my_service_pack}")
25    endif()
26  endif()
27
28Function DetermineVSServicePack sets the given variable to one of the
29following values or an empty string if unknown::
30
31  vc80, vc80sp1
32  vc90, vc90sp1
33  vc100, vc100sp1
34  vc110, vc110sp1, vc110sp2, vc110sp3, vc110sp4
35#]=======================================================================]
36
37if(NOT CMAKE_MINIMUM_REQUIRED_VERSION VERSION_LESS 2.8.8)
38  message(DEPRECATION
39    "This module is deprecated and should not be used.  "
40    "Use the CMAKE_<LANG>_COMPILER_VERSION variable instead."
41    )
42endif()
43
44# [INTERNAL]
45# Please do not call this function directly
46function(_DetermineVSServicePackFromCompiler _OUT_VAR _cl_version)
47  if    (${_cl_version} VERSION_EQUAL "14.00.50727.42")
48    set(_version "vc80")
49  elseif(${_cl_version} VERSION_EQUAL "14.00.50727.762")
50    set(_version "vc80sp1")
51  elseif(${_cl_version} VERSION_EQUAL "15.00.21022.08")
52    set(_version "vc90")
53  elseif(${_cl_version} VERSION_EQUAL "15.00.30729.01")
54    set(_version "vc90sp1")
55  elseif(${_cl_version} VERSION_EQUAL "16.00.30319.01")
56    set(_version "vc100")
57  elseif(${_cl_version} VERSION_EQUAL "16.00.40219.01")
58    set(_version "vc100sp1")
59  elseif(${_cl_version} VERSION_EQUAL "17.00.50727.1")
60    set(_version "vc110")
61  elseif(${_cl_version} VERSION_EQUAL "17.00.51106.1")
62    set(_version "vc110sp1")
63  elseif(${_cl_version} VERSION_EQUAL "17.00.60315.1")
64    set(_version "vc110sp2")
65  elseif(${_cl_version} VERSION_EQUAL "17.00.60610.1")
66    set(_version "vc110sp3")
67  elseif(${_cl_version} VERSION_EQUAL "17.00.61030")
68    set(_version "vc110sp4")
69  else()
70    set(_version "")
71  endif()
72  set(${_OUT_VAR} ${_version} PARENT_SCOPE)
73endfunction()
74
75
76############################################################
77# [INTERNAL]
78# Please do not call this function directly
79function(_DetermineVSServicePack_FastCheckVersionWithCompiler _SUCCESS_VAR  _VERSION_VAR)
80    if(EXISTS ${CMAKE_CXX_COMPILER})
81      execute_process(
82          COMMAND ${CMAKE_CXX_COMPILER} -?
83          ERROR_VARIABLE _output
84          OUTPUT_QUIET
85        )
86
87      if(_output MATCHES "Compiler Version (([0-9]+)\\.([0-9]+)\\.([0-9]+)(\\.([0-9]+))?)")
88        set(_cl_version ${CMAKE_MATCH_1})
89        set(_major ${CMAKE_MATCH_2})
90        set(_minor ${CMAKE_MATCH_3})
91        if("${_major}${_minor}" STREQUAL "${MSVC_VERSION}")
92          set(${_SUCCESS_VAR} true PARENT_SCOPE)
93          set(${_VERSION_VAR} ${_cl_version} PARENT_SCOPE)
94        endif()
95      endif()
96    endif()
97endfunction()
98
99############################################################
100# [INTERNAL]
101# Please do not call this function directly
102function(_DetermineVSServicePack_CheckVersionWithTryCompile _SUCCESS_VAR  _VERSION_VAR)
103    file(WRITE "${CMAKE_BINARY_DIR}/return0.cc"
104      "int main() { return 0; }\n")
105
106    try_compile(
107      _CompileResult
108      "${CMAKE_BINARY_DIR}"
109      "${CMAKE_BINARY_DIR}/return0.cc"
110      OUTPUT_VARIABLE _output
111      COPY_FILE "${CMAKE_BINARY_DIR}/return0.cc")
112
113    file(REMOVE "${CMAKE_BINARY_DIR}/return0.cc")
114
115    if(_output MATCHES "Compiler Version (([0-9]+)\\.([0-9]+)\\.([0-9]+)(\\.([0-9]+))?)")
116      set(${_SUCCESS_VAR} true PARENT_SCOPE)
117      set(${_VERSION_VAR} "${CMAKE_MATCH_1}" PARENT_SCOPE)
118    endif()
119endfunction()
120
121############################################################
122# [INTERNAL]
123# Please do not call this function directly
124function(_DetermineVSServicePack_CheckVersionWithTryRun _SUCCESS_VAR  _VERSION_VAR)
125    file(WRITE "${CMAKE_BINARY_DIR}/return0.cc"
126        "#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")
127
128    try_run(
129        _RunResult
130        _CompileResult
131        "${CMAKE_BINARY_DIR}"
132        "${CMAKE_BINARY_DIR}/return0.cc"
133        RUN_OUTPUT_VARIABLE  _runoutput
134        )
135
136    file(REMOVE "${CMAKE_BINARY_DIR}/return0.cc")
137
138    string(REGEX MATCH "[0-9]+.[0-9]+.[0-9]+.[0-9]+"
139        _cl_version "${_runoutput}")
140
141    if(_cl_version)
142      set(${_SUCCESS_VAR} true PARENT_SCOPE)
143      set(${_VERSION_VAR} ${_cl_version} PARENT_SCOPE)
144    endif()
145endfunction()
146
147
148#
149# A function to call to determine the Visual Studio service pack
150# in use.  See documentation above.
151function(DetermineVSServicePack _pack)
152    if(NOT DETERMINED_VS_SERVICE_PACK OR NOT ${_pack})
153
154        _DetermineVSServicePack_FastCheckVersionWithCompiler(DETERMINED_VS_SERVICE_PACK _cl_version)
155        if(NOT DETERMINED_VS_SERVICE_PACK)
156            _DetermineVSServicePack_CheckVersionWithTryCompile(DETERMINED_VS_SERVICE_PACK _cl_version)
157            if(NOT DETERMINED_VS_SERVICE_PACK)
158                _DetermineVSServicePack_CheckVersionWithTryRun(DETERMINED_VS_SERVICE_PACK _cl_version)
159            endif()
160        endif()
161
162        if(DETERMINED_VS_SERVICE_PACK)
163
164            if(_cl_version)
165                # Call helper function to determine VS version
166                _DetermineVSServicePackFromCompiler(_sp "${_cl_version}")
167                if(_sp)
168                    set(${_pack} ${_sp} CACHE INTERNAL
169                        "The Visual Studio Release with Service Pack")
170                endif()
171            endif()
172        endif()
173    endif()
174endfunction()
175