Home | History | Annotate | Download | only in win
      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