| #!/usr/bin/env python |
| # Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| # TODO(slightlyoff): move to using shared version of this script. |
| '''This script makes it easy to combine libs and object files to a new lib, |
| optionally removing some of the object files in the input libs by regular |
| expression matching. |
| For usage information, run the script with a --help argument. |
| ''' |
| from __future__ import absolute_import |
| from __future__ import print_function |
| import optparse |
| import os |
| import re |
| import subprocess |
| import sys |
| |
| |
| def Shell(*args): |
| '''Runs the program and args in args, returns the output from the program.''' |
| process = subprocess.Popen( |
| args, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) |
| output = process.stdout.readlines() |
| process.wait() |
| retcode = process.returncode |
| if retcode != 0: |
| raise RuntimeError('%s exited with status %d' % (args[0], retcode)) |
| return output |
| |
| |
| def CollectRemovals(remove_re, inputs): |
| '''Returns a list of all object files in inputs that match remove_re.''' |
| removals = [] |
| for input in inputs: |
| output = Shell('lib.exe', '/list', input) |
| |
| for line in output: |
| line = line.rstrip() |
| if remove_re.search(line): |
| removals.append(line) |
| |
| return removals |
| |
| |
| def CombineLibraries(output, remove_re, inputs): |
| '''Combines all the libraries and objects in inputs, while removing any |
| object files that match remove_re. |
| ''' |
| removals = [] |
| if remove_re: |
| removals = CollectRemovals(remove_re, inputs) |
| |
| if len(removals) > 0: |
| print('Removals: ', removals) |
| |
| args = ['lib.exe', '/out:%s' % output] |
| args += ['/remove:%s' % obj for obj in removals] |
| args += inputs |
| Shell(*args) |
| |
| |
| USAGE = '''usage: %prog [options] <lib or obj>+ |
| |
| Combines input libraries or objects into an output library, while removing |
| any object file (in the input libraries) that matches a given regular |
| expression. |
| ''' |
| |
| |
| def GetOptionParser(): |
| parser = optparse.OptionParser(USAGE) |
| parser.add_option( |
| '-o', '--output', dest='output', help='write to this output library') |
| parser.add_option( |
| '-r', |
| '--remove', |
| dest='remove', |
| help='object files matching this regexp will be removed ' |
| 'from the output library') |
| return parser |
| |
| |
| def Main(): |
| '''Main function for this script''' |
| parser = GetOptionParser() |
| (opt, args) = parser.parse_args() |
| output = opt.output |
| remove = opt.remove |
| if not output: |
| parser.error('You must specify an output file') |
| |
| if not args: |
| parser.error('You must specify at least one object or library') |
| |
| output = output.strip() |
| if remove: |
| remove = remove.strip() |
| |
| if remove: |
| try: |
| remove_re = re.compile(opt.remove) |
| except: |
| parser.error('%s is not a valid regular expression' % opt.remove) |
| else: |
| remove_re = None |
| |
| if sys.platform != 'win32' and sys.platform != 'cygwin': |
| parser.error('this script only works on Windows for now') |
| |
| # If this is set, we can't capture lib.exe's output. |
| if 'VS_UNICODE_OUTPUT' in os.environ: |
| del os.environ['VS_UNICODE_OUTPUT'] |
| |
| CombineLibraries(output, remove_re, args) |
| return 0 |
| |
| |
| if __name__ == '__main__': |
| sys.exit(Main()) |