CMakeDetermineVSServicePack.cmake 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. # - Includes a public function for assisting users in trying to determine the
  2. # Visual Studio service pack in use.
  3. #
  4. # Sets the passed in variable to one of the following values or an empty
  5. # string if unknown.
  6. # vc80
  7. # vc80sp1
  8. # vc90
  9. # vc90sp1
  10. # vc100
  11. # vc100sp1
  12. # vc110
  13. #
  14. # Usage:
  15. # ===========================
  16. #
  17. # if(MSVC)
  18. # include(CMakeDetermineVSServicePack)
  19. # DetermineVSServicePack( my_service_pack )
  20. #
  21. # if( my_service_pack )
  22. # message(STATUS "Detected: ${my_service_pack}")
  23. # endif()
  24. # endif()
  25. #
  26. # ===========================
  27. #=============================================================================
  28. # Copyright 2009-2011 Kitware, Inc.
  29. # Copyright 2009-2010 Philip Lowman <[email protected]>
  30. # Copyright 2010-2011 Aaron C. meadows <[email protected]>
  31. #
  32. # Distributed under the OSI-approved BSD License (the "License");
  33. # see accompanying file Copyright.txt for details.
  34. #
  35. # This software is distributed WITHOUT ANY WARRANTY; without even the
  36. # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  37. # See the License for more information.
  38. #=============================================================================
  39. # (To distribute this file outside of CMake, substitute the full
  40. # License text for the above reference.)
  41. # [INTERNAL]
  42. # Please do not call this function directly
  43. function(_DetermineVSServicePackFromCompiler _OUT_VAR _cl_version)
  44. if (${_cl_version} VERSION_EQUAL "14.00.50727.42")
  45. set(_version "vc80")
  46. elseif(${_cl_version} VERSION_EQUAL "14.00.50727.762")
  47. set(_version "vc80sp1")
  48. elseif(${_cl_version} VERSION_EQUAL "15.00.21022.08")
  49. set(_version "vc90")
  50. elseif(${_cl_version} VERSION_EQUAL "15.00.30729.01")
  51. set(_version "vc90sp1")
  52. elseif(${_cl_version} VERSION_EQUAL "16.00.30319.01")
  53. set(_version "vc100")
  54. elseif(${_cl_version} VERSION_EQUAL "16.00.40219.01")
  55. set(_version "vc100sp1")
  56. elseif(${_cl_version} VERSION_EQUAL "17.00.50727.1")
  57. set(_version "vc110")
  58. else()
  59. set(_version "")
  60. endif()
  61. set(${_OUT_VAR} ${_version} PARENT_SCOPE)
  62. endfunction()
  63. ############################################################
  64. # [INTERNAL]
  65. # Please do not call this function directly
  66. function(_DetermineVSServicePack_FastCheckVersionWithCompiler _SUCCESS_VAR _VERSION_VAR)
  67. if(EXISTS ${CMAKE_CXX_COMPILER})
  68. execute_process(
  69. COMMAND ${CMAKE_CXX_COMPILER} /?
  70. ERROR_VARIABLE _output
  71. OUTPUT_QUIET
  72. )
  73. string(REGEX MATCH "Compiler Version [0-9]+.[0-9]+.[0-9]+.[0-9]+"
  74. _cl_version "${_output}")
  75. if(_cl_version)
  76. string(REGEX MATCHALL "[0-9]+"
  77. _cl_version_list "${_cl_version}")
  78. list(GET _cl_version_list 0 _major)
  79. list(GET _cl_version_list 1 _minor)
  80. list(GET _cl_version_list 2 _patch)
  81. list(GET _cl_version_list 3 _tweak)
  82. if("${_major}${_minor}" STREQUAL "${MSVC_VERSION}")
  83. set(_cl_version ${_major}.${_minor}.${_patch}.${_tweak})
  84. else()
  85. unset(_cl_version)
  86. endif()
  87. endif()
  88. if(_cl_version)
  89. set(${_SUCCESS_VAR} true PARENT_SCOPE)
  90. set(${_VERSION_VAR} ${_cl_version} PARENT_SCOPE)
  91. endif()
  92. endif()
  93. endfunction()
  94. ############################################################
  95. # [INTERNAL]
  96. # Please do not call this function directly
  97. function(_DetermineVSServicePack_CheckVersionWithTryCompile _SUCCESS_VAR _VERSION_VAR)
  98. file(WRITE "${CMAKE_BINARY_DIR}/return0.cc"
  99. "int main() { return 0; }\n")
  100. try_compile(
  101. _CompileResult
  102. "${CMAKE_BINARY_DIR}"
  103. "${CMAKE_BINARY_DIR}/return0.cc"
  104. OUTPUT_VARIABLE _output
  105. COPY_FILE "${CMAKE_BINARY_DIR}/return0.cc")
  106. file(REMOVE "${CMAKE_BINARY_DIR}/return0.cc")
  107. string(REGEX MATCH "Compiler Version [0-9]+.[0-9]+.[0-9]+.[0-9]+"
  108. _cl_version "${_output}")
  109. if(_cl_version)
  110. string(REGEX MATCHALL "[0-9]+"
  111. _cl_version_list "${_cl_version}")
  112. list(GET _cl_version_list 0 _major)
  113. list(GET _cl_version_list 1 _minor)
  114. list(GET _cl_version_list 2 _patch)
  115. list(GET _cl_version_list 3 _tweak)
  116. set(${_SUCCESS_VAR} true PARENT_SCOPE)
  117. set(${_VERSION_VAR} ${_major}.${_minor}.${_patch}.${_tweak} PARENT_SCOPE)
  118. endif()
  119. endfunction()
  120. ############################################################
  121. # [INTERNAL]
  122. # Please do not call this function directly
  123. function(_DetermineVSServicePack_CheckVersionWithTryRun _SUCCESS_VAR _VERSION_VAR)
  124. file(WRITE "${CMAKE_BINARY_DIR}/return0.cc"
  125. "#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")
  126. try_run(
  127. _RunResult
  128. _CompileResult
  129. "${CMAKE_BINARY_DIR}"
  130. "${CMAKE_BINARY_DIR}/return0.cc"
  131. RUN_OUTPUT_VARIABLE _runoutput
  132. )
  133. file(REMOVE "${CMAKE_BINARY_DIR}/return0.cc")
  134. string(REGEX MATCH "[0-9]+.[0-9]+.[0-9]+.[0-9]+"
  135. _cl_version "${_runoutput}")
  136. if(_cl_version)
  137. set(${_SUCCESS_VAR} true PARENT_SCOPE)
  138. set(${_VERSION_VAR} ${_cl_version} PARENT_SCOPE)
  139. endif()
  140. endfunction()
  141. #
  142. # A function to call to determine the Visual Studio service pack
  143. # in use. See documentation above.
  144. function(DetermineVSServicePack _pack)
  145. if(NOT DETERMINED_VS_SERVICE_PACK OR NOT ${_pack})
  146. _DetermineVSServicePack_FastCheckVersionWithCompiler(DETERMINED_VS_SERVICE_PACK _cl_version)
  147. if(NOT DETERMINED_VS_SERVICE_PACK)
  148. _DetermineVSServicePack_CheckVersionWithTryCompile(DETERMINED_VS_SERVICE_PACK _cl_version)
  149. if(NOT DETERMINED_VS_SERVICE_PACK)
  150. _DetermineVSServicePack_CheckVersionWithTryRun(DETERMINED_VS_SERVICE_PACK _cl_version)
  151. endif()
  152. endif()
  153. if(DETERMINED_VS_SERVICE_PACK)
  154. if(_cl_version)
  155. # Call helper function to determine VS version
  156. _DetermineVSServicePackFromCompiler(_sp "${_cl_version}")
  157. if(_sp)
  158. set(${_pack} ${_sp} CACHE INTERNAL
  159. "The Visual Studio Release with Service Pack")
  160. endif()
  161. endif()
  162. endif()
  163. endif()
  164. endfunction()