CMakeVerifyManifest.cmake 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. # CMakeVerifyManifest.cmake
  2. #
  3. # This script is used to verify that embeded manifests and
  4. # side by side manifests for a project match. To run this
  5. # script, cd to a directory and run the script with cmake -P.
  6. # On the command line you can pass in versions that are OK even
  7. # if not found in the .manifest files. For example,
  8. # cmake -Dallow_versions=8.0.50608.0 -PCmakeVerifyManifest.cmake
  9. # could be used to allow an embeded manifest of 8.0.50608.0
  10. # to be used in a project even if that version was not found
  11. # in the .manifest file.
  12. # This script first recursively globs *.manifest files from
  13. # the current directory. Then globs *.exe and *.dll. Each
  14. # .exe and .dll is scanned for embeded manifests and the versions
  15. # of CRT are compared to those found in the .manifest files
  16. # from the first glob.
  17. #=============================================================================
  18. # Copyright 2008-2009 Kitware, Inc.
  19. #
  20. # Distributed under the OSI-approved BSD License (the "License");
  21. # see accompanying file Copyright.txt for details.
  22. #
  23. # This software is distributed WITHOUT ANY WARRANTY; without even the
  24. # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  25. # See the License for more information.
  26. #=============================================================================
  27. # (To distribute this file outside of CMake, substitute the full
  28. # License text for the above reference.)
  29. # crt_version:
  30. # function to extract the CRT version from a file
  31. # this can be passed a .exe, .dll, or a .manifest file
  32. # it will put the list of versions found into the variable
  33. # specified by list_var
  34. function(crt_version file list_var)
  35. file(STRINGS "${file}" strings REGEX "Microsoft.VC...CRT" NEWLINE_CONSUME)
  36. foreach(s ${strings})
  37. set(has_match 1)
  38. string(REGEX
  39. REPLACE ".*<assembly.*\"Microsoft.VC...CRT\".*version=\"([^\"]*)\".*</assembly>.*$" "\\1"
  40. version "${s}")
  41. if(NOT "${version}" STREQUAL "")
  42. list(APPEND version_list ${version})
  43. else()
  44. message(FATAL_ERROR "Parse error could not find version in [${s}]")
  45. endif()
  46. endforeach(s)
  47. if(NOT DEFINED has_match)
  48. message("Information: no embeded manifest in: ${file}")
  49. return()
  50. endif()
  51. list(APPEND version_list ${${list_var}})
  52. list(REMOVE_DUPLICATES version_list)
  53. if(version_list)
  54. set(${list_var} ${version_list} PARENT_SCOPE)
  55. endif()
  56. endfunction(crt_version)
  57. set(fatal_error FALSE)
  58. # check_version:
  59. #
  60. # test a file against the shipped manifest versions
  61. # for a directory
  62. function(check_version file manifest_versions)
  63. set(manifest_versions ${manifest_versions} ${allow_versions})
  64. # collect versions for a given file
  65. crt_version(${file} file_versions)
  66. # see if the versions
  67. foreach(ver ${file_versions})
  68. list(FIND manifest_versions "${ver}" found_version)
  69. if("${found_version}" EQUAL -1)
  70. message("ERROR: ${file} uses ${ver} not found in shipped manifests:[${manifest_versions}].")
  71. set(fatal_error TRUE PARENT_SCOPE)
  72. endif()
  73. endforeach(ver)
  74. list(LENGTH file_versions len)
  75. if(${len} GREATER 1)
  76. message("WARNING: found more than one version of MICROSOFT.VC80.CRT referenced in ${file}: [${file_versions}]")
  77. endif()
  78. endfunction()
  79. # collect up the versions of CRT that are shipped
  80. # in .manifest files
  81. set(manifest_version_list )
  82. file(GLOB_RECURSE manifest_files "*.manifest")
  83. foreach(f ${manifest_files})
  84. crt_version("${f}" manifest_version_list)
  85. endforeach(f)
  86. list(LENGTH manifest_version_list LEN)
  87. if(LEN EQUAL 0)
  88. message(FATAL_ERROR "No .manifest files found, no version check can be done.")
  89. endif()
  90. message("Versions found in ${manifest_files}: ${manifest_version_list}")
  91. if(DEFINED allow_versions)
  92. message("Extra versions allowed: ${allow_versions}")
  93. endif()
  94. # now find all .exe and .dll files
  95. # and call check_version on each of them
  96. file(GLOB_RECURSE exe_files "*.exe")
  97. file(GLOB_RECURSE dll_files "*.dll")
  98. set(exe_files ${exe_files} ${dll_files})
  99. foreach(f ${exe_files})
  100. check_version(${f} "${manifest_version_list}")
  101. endforeach()
  102. # report a fatal error if there were any so that cmake will return
  103. # a non zero value
  104. if(fatal_error)
  105. message(FATAL_ERROR "This distribution embeds dll "
  106. " versions that it does not ship, and may not work on other machines.")
  107. endif()