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