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: 5CMakeVerifyManifest 6------------------- 7 8 9 10CMakeVerifyManifest.cmake 11 12This script is used to verify that embedded manifests and side by side 13manifests for a project match. To run this script, cd to a directory 14and run the script with cmake -P. On the command line you can pass in 15versions that are OK even if not found in the .manifest files. For 16example, cmake -Dallow_versions=8.0.50608.0 17-PCmakeVerifyManifest.cmake could be used to allow an embedded manifest 18of 8.0.50608.0 to be used in a project even if that version was not 19found in the .manifest file. 20#]=======================================================================] 21 22# This script first recursively globs *.manifest files from 23# the current directory. Then globs *.exe and *.dll. Each 24# .exe and .dll is scanned for embedded manifests and the versions 25# of CRT are compared to those found in the .manifest files 26# from the first glob. 27 28# crt_version: 29# function to extract the CRT version from a file 30# this can be passed a .exe, .dll, or a .manifest file 31# it will put the list of versions found into the variable 32# specified by list_var 33function(crt_version file list_var) 34 file(STRINGS "${file}" strings REGEX "Microsoft.VC...CRT" NEWLINE_CONSUME) 35 foreach(s ${strings}) 36 set(has_match 1) 37 string(REGEX 38 REPLACE ".*<assembly.*\"Microsoft.VC...CRT\".*version=\"([^\"]*)\".*</assembly>.*$" "\\1" 39 version "${s}") 40 if(NOT "${version}" STREQUAL "") 41 list(APPEND version_list ${version}) 42 else() 43 message(FATAL_ERROR "Parse error could not find version in [${s}]") 44 endif() 45 endforeach() 46 if(NOT DEFINED has_match) 47 message("Information: no embedded manifest in: ${file}") 48 return() 49 endif() 50 list(APPEND version_list ${${list_var}}) 51 list(REMOVE_DUPLICATES version_list) 52 if(version_list) 53 set(${list_var} ${version_list} PARENT_SCOPE) 54 endif() 55endfunction() 56set(fatal_error FALSE) 57 58# check_version: 59# 60# test a file against the shipped manifest versions 61# for a directory 62function(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() 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() 78endfunction() 79 80# collect up the versions of CRT that are shipped 81# in .manifest files 82set(manifest_version_list ) 83file(GLOB_RECURSE manifest_files "*.manifest") 84foreach(f ${manifest_files}) 85 crt_version("${f}" manifest_version_list) 86endforeach() 87list(LENGTH manifest_version_list LEN) 88if(LEN EQUAL 0) 89 message(FATAL_ERROR "No .manifest files found, no version check can be done.") 90endif() 91message("Versions found in ${manifest_files}: ${manifest_version_list}") 92if(DEFINED allow_versions) 93 message("Extra versions allowed: ${allow_versions}") 94endif() 95 96# now find all .exe and .dll files 97# and call check_version on each of them 98file(GLOB_RECURSE exe_files "*.exe") 99file(GLOB_RECURSE dll_files "*.dll") 100set(exe_files ${exe_files} ${dll_files}) 101foreach(f ${exe_files}) 102 check_version(${f} "${manifest_version_list}") 103endforeach() 104 105# report a fatal error if there were any so that cmake will return 106# a non zero value 107if(fatal_error) 108 message(FATAL_ERROR "This distribution embeds dll " 109 " versions that it does not ship, and may not work on other machines.") 110endif() 111