Home | History | Annotate | Download | only in chrome_frame
      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 # TODO(slightlyoff): move to using shared version of this script.
      7 
      8 '''This script makes it easy to combine libs and object files to a new lib,
      9 optionally removing some of the object files in the input libs by regular
     10 expression matching.
     11 For usage information, run the script with a --help argument.
     12 '''
     13 import optparse
     14 import os
     15 import re
     16 import subprocess
     17 import sys
     18 
     19 
     20 def Shell(*args):
     21   '''Runs the program and args in args, returns the output from the program.'''
     22   process = subprocess.Popen(args,
     23                              stdin = None,
     24                              stdout = subprocess.PIPE,
     25                              stderr = subprocess.STDOUT)
     26   output = process.stdout.readlines()
     27   process.wait()
     28   retcode = process.returncode
     29   if retcode != 0:
     30     raise RuntimeError('%s exited with status %d' % (args[0], retcode))
     31   return output
     32 
     33 
     34 def CollectRemovals(remove_re, inputs):
     35   '''Returns a list of all object files in inputs that match remove_re.'''
     36   removals = []
     37   for input in inputs:
     38     output = Shell('lib.exe', '/list', input)
     39 
     40     for line in output:
     41       line = line.rstrip()
     42       if remove_re.search(line):
     43         removals.append(line)
     44 
     45   return removals
     46 
     47 
     48 def CombineLibraries(output, remove_re, inputs):
     49   '''Combines all the libraries and objects in inputs, while removing any
     50   object files that match remove_re.
     51   '''
     52   removals = []
     53   if remove_re:
     54     removals = CollectRemovals(remove_re, inputs)
     55 
     56   print removals
     57 
     58   args = ['lib.exe', '/out:%s' % output]
     59   args += ['/remove:%s' % obj for obj in removals]
     60   args += inputs
     61   Shell(*args)
     62 
     63 
     64 USAGE = '''usage: %prog [options] <lib or obj>+
     65 
     66 Combines input libraries or objects into an output library, while removing
     67 any object file (in the input libraries) that matches a given regular
     68 expression.
     69 '''
     70 
     71 def GetOptionParser():
     72   parser = optparse.OptionParser(USAGE)
     73   parser.add_option('-o', '--output', dest = 'output',
     74                     help = 'write to this output library')
     75   parser.add_option('-r', '--remove', dest = 'remove',
     76                     help = 'object files matching this regexp will be removed '
     77                             'from the output library')
     78   return parser
     79 
     80 
     81 def Main():
     82   '''Main function for this script'''
     83   parser = GetOptionParser()
     84   (opt, args) = parser.parse_args()
     85   output = opt.output
     86   remove = opt.remove
     87   if not output:
     88     parser.error('You must specify an output file')
     89 
     90   if not args:
     91     parser.error('You must specify at least one object or library')
     92 
     93   output = output.strip()
     94   remove = remove.strip()
     95 
     96   if remove:
     97     try:
     98       remove_re = re.compile(opt.remove)
     99     except:
    100       parser.error('%s is not a valid regular expression' % opt.remove)
    101   else:
    102     remove_re = None
    103 
    104   if sys.platform != 'win32' and sys.platform != 'cygwin':
    105     parser.error('this script only works on Windows for now')
    106 
    107   # If this is set, we can't capture lib.exe's output.
    108   if 'VS_UNICODE_OUTPUT' in os.environ:
    109     del os.environ['VS_UNICODE_OUTPUT']
    110 
    111   CombineLibraries(output, remove_re, args)
    112   return 0
    113 
    114 
    115 if __name__ == '__main__':
    116   sys.exit(Main())
    117