CMakeVerifyManifest.cmake 4.22 KB
Newer Older
1 2 3 4 5 6
#.rst:
# CMakeVerifyManifest
# -------------------
#
#
#
7 8
# CMakeVerifyManifest.cmake
#
9
# This script is used to verify that embedded manifests and side by side
10 11 12 13
# manifests for a project match.  To run this script, cd to a directory
# and run the script with cmake -P.  On the command line you can pass in
# versions that are OK even if not found in the .manifest files.  For
# example, cmake -Dallow_versions=8.0.50608.0
14
# -PCmakeVerifyManifest.cmake could be used to allow an embedded manifest
15 16
# of 8.0.50608.0 to be used in a project even if that version was not
# found in the .manifest file.
17 18 19

# This script first recursively globs *.manifest files from
# the current directory.  Then globs *.exe and *.dll.  Each
20
# .exe and .dll is scanned for embedded manifests and the versions
21 22 23
# of CRT are compared to those found in the .manifest files
# from the first glob.

Bill Hoffman's avatar
Bill Hoffman committed
24 25 26 27 28 29 30 31 32 33
#=============================================================================
# Copyright 2008-2009 Kitware, Inc.
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
34
# (To distribute this file outside of CMake, substitute the full
Bill Hoffman's avatar
Bill Hoffman committed
35 36 37
#  License text for the above reference.)


38
# crt_version:
39 40 41 42 43
# function to extract the CRT version from a file
# this can be passed a .exe, .dll, or a .manifest file
# it will put the list of versions found into the variable
# specified by list_var
function(crt_version file list_var)
44
  file(STRINGS "${file}" strings REGEX "Microsoft.VC...CRT" NEWLINE_CONSUME)
45 46 47
  foreach(s ${strings})
    set(has_match 1)
    string(REGEX
48
      REPLACE ".*<assembly.*\"Microsoft.VC...CRT\".*version=\"([^\"]*)\".*</assembly>.*$" "\\1"
49 50 51 52 53 54
      version "${s}")
    if(NOT "${version}" STREQUAL "")
      list(APPEND version_list ${version})
    else()
      message(FATAL_ERROR "Parse error could not find version in [${s}]")
    endif()
55
  endforeach()
56
  if(NOT DEFINED has_match)
57
    message("Information: no embedded manifest in: ${file}")
58 59 60 61 62 63 64
    return()
  endif()
  list(APPEND version_list ${${list_var}})
  list(REMOVE_DUPLICATES version_list)
  if(version_list)
    set(${list_var} ${version_list} PARENT_SCOPE)
  endif()
65
endfunction()
66
set(fatal_error FALSE)
67 68

# check_version:
69
#
70 71 72 73 74 75
# test a file against the shipped manifest versions
# for a directory
function(check_version file manifest_versions)
  set(manifest_versions ${manifest_versions} ${allow_versions})
  # collect versions for a given file
  crt_version(${file} file_versions)
76
  # see if the versions
77 78 79
  foreach(ver ${file_versions})
    list(FIND manifest_versions "${ver}" found_version)
    if("${found_version}" EQUAL -1)
80
      message("ERROR: ${file} uses ${ver} not found in shipped manifests:[${manifest_versions}].")
81 82
      set(fatal_error TRUE PARENT_SCOPE)
    endif()
83
  endforeach()
84 85 86 87 88 89 90 91 92 93 94 95
  list(LENGTH file_versions len)
  if(${len} GREATER 1)
    message("WARNING: found more than one version of MICROSOFT.VC80.CRT referenced in ${file}: [${file_versions}]")
  endif()
endfunction()

# collect up the versions of CRT that are shipped
# in .manifest files
set(manifest_version_list )
file(GLOB_RECURSE manifest_files "*.manifest")
foreach(f ${manifest_files})
  crt_version("${f}" manifest_version_list)
96
endforeach()
97 98 99 100
list(LENGTH manifest_version_list LEN)
if(LEN EQUAL 0)
  message(FATAL_ERROR "No .manifest files found, no version check can be done.")
endif()
101
message("Versions found in ${manifest_files}: ${manifest_version_list}")
Bill Hoffman's avatar
Bill Hoffman committed
102 103 104
if(DEFINED allow_versions)
  message("Extra versions allowed: ${allow_versions}")
endif()
105 106 107 108 109 110 111

# now find all .exe and .dll files
# and call check_version on each of them
file(GLOB_RECURSE exe_files "*.exe")
file(GLOB_RECURSE dll_files "*.dll")
set(exe_files ${exe_files} ${dll_files})
foreach(f ${exe_files})
112
  check_version(${f} "${manifest_version_list}")
113 114 115 116 117
endforeach()

# report a fatal error if there were any so that cmake will return
# a non zero value
if(fatal_error)
118 119
  message(FATAL_ERROR "This distribution embeds dll "
    " versions that it does not ship, and may not work on other machines.")
120
endif()