1 #!/usr/bin/env python 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. 3 # Use of this source code is governed by a BSD-style license that can be 4 # found in the LICENSE file. 5 6 """Script used to scan for server DLLs at build time and build a header 7 included by setup.exe. This header contains an array of the names of 8 the DLLs that need registering at install time. 9 """ 10 11 import ConfigParser 12 import glob 13 import optparse 14 import os 15 import sys 16 17 CHROME_DIR = "Chrome-bin" 18 SERVERS_DIR = "servers" 19 GENERATED_DLL_INCLUDE_FILE_NAME = "registered_dlls.h" 20 GENERATED_DLL_INCLUDE_FILE_CONTENTS = """ 21 // This file is automatically generated by scan_server_dlls.py. 22 // It contains the list of COM server dlls that need registering at 23 // install time. 24 #include "base/basictypes.h" 25 26 namespace { 27 const wchar_t* kDllsToRegister[] = { %s }; 28 const int kNumDllsToRegister = %d; 29 } 30 """ 31 32 33 def Readconfig(output_dir, input_file): 34 """Reads config information from input file after setting default value of 35 global variabes. 36 """ 37 variables = {} 38 variables['ChromeDir'] = CHROME_DIR 39 # Use a bogus version number, we don't really care what it is, we just 40 # want to find the files that would get picked up from chrome.release, 41 # and don't care where the installer archive task ends up putting them. 42 variables['VersionDir'] = os.path.join(variables['ChromeDir'], 43 '0.0.0.0') 44 config = ConfigParser.SafeConfigParser(variables) 45 46 print "Reading input_file: " + input_file 47 48 config.read(input_file) 49 return config 50 51 52 def CreateRegisteredDllIncludeFile(registered_dll_list, header_output_dir): 53 """ Outputs the header file included by the setup project that 54 contains the names of the DLLs to be registered at installation 55 time. 56 """ 57 output_file = os.path.join(header_output_dir, GENERATED_DLL_INCLUDE_FILE_NAME) 58 59 dll_array_string = "" 60 for dll in registered_dll_list: 61 dll.replace("\\", "\\\\") 62 if dll_array_string: 63 dll_array_string += ', ' 64 dll_array_string += "L\"%s\"" % dll 65 66 if len(registered_dll_list) == 0: 67 contents = GENERATED_DLL_INCLUDE_FILE_CONTENTS % ("L\"\"", 0) 68 else: 69 contents = GENERATED_DLL_INCLUDE_FILE_CONTENTS % (dll_array_string, 70 len(registered_dll_list)) 71 72 # Don't rewrite the header file if we don't need to. 73 try: 74 old_file = open(output_file, 'r') 75 except EnvironmentError: 76 old_contents = None 77 else: 78 old_contents = old_file.read() 79 old_file.close() 80 81 if contents != old_contents: 82 print 'Updating server dll header: ' + str(output_file) 83 open(output_file, 'w').write(contents) 84 85 86 def ScanServerDlls(config, distribution, output_dir): 87 """Scans for DLLs in the specified section of config that are in the 88 subdirectory of output_dir named SERVERS_DIR. Returns a list of only the 89 filename components of the paths to all matching DLLs. 90 """ 91 92 print "Scanning for server DLLs in " + output_dir 93 94 registered_dll_list = [] 95 ScanDllsInSection(config, 'GENERAL', output_dir, registered_dll_list) 96 if distribution: 97 if len(distribution) > 1 and distribution[0] == '_': 98 distribution = distribution[1:] 99 ScanDllsInSection(config, distribution.upper(), output_dir, 100 registered_dll_list) 101 102 return registered_dll_list 103 104 105 def ScanDllsInSection(config, section, output_dir, registered_dll_list): 106 """Scans for DLLs in the specified section of config that are in the 107 subdirectory of output_dir named SERVERS_DIR. Appends the file name of all 108 matching dlls to registered_dll_list. 109 """ 110 for option in config.options(section): 111 if option.endswith('dir'): 112 continue 113 114 dst = config.get(section, option) 115 (x, src_folder) = os.path.split(dst) 116 117 for file in glob.glob(os.path.join(output_dir, option)): 118 if option.startswith(SERVERS_DIR): 119 (x, file_name) = os.path.split(file) 120 if file_name.lower().endswith('.dll'): 121 print "Found server DLL file: " + file_name 122 registered_dll_list.append(file_name) 123 124 125 def RunSystemCommand(cmd): 126 if (os.system(cmd) != 0): 127 raise "Error while running cmd: %s" % cmd 128 129 130 def main(): 131 """Main method that reads input file, scans <build_output>\servers for 132 matches to files described in the input file. A header file for the 133 setup project is then generated. 134 """ 135 option_parser = optparse.OptionParser() 136 option_parser.add_option('-o', '--output_dir', help='Build Output directory') 137 option_parser.add_option('-x', '--header_output_dir', 138 help='Location where the generated header file will be placed.') 139 option_parser.add_option('-i', '--input_file', help='Input file') 140 option_parser.add_option('-d', '--distribution', 141 help='Name of Chromium Distribution. Optional.') 142 143 options, args = option_parser.parse_args() 144 config = Readconfig(options.output_dir, options.input_file) 145 registered_dll_list = ScanServerDlls(config, options.distribution, 146 options.output_dir) 147 CreateRegisteredDllIncludeFile(registered_dll_list, 148 options.header_output_dir) 149 return 0 150 151 152 if '__main__' == __name__: 153 sys.exit(main()) 154