#!/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, build_dir, inputs): '''Returns a list of all object files in inputs that match remove_re.''' removals = [] for input in inputs: output = Shell('lib.exe', '/list', os.path.join(build_dir, input)) for line in output: line = line.rstrip() if remove_re.search(line): removals.append(line) return removals def CombineLibraries(build_dir, 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, build_dir, inputs) if len(removals) > 0: print('Removals: ', removals) args = ['lib.exe', '/out:%s' % output] args += ['/remove:%s' % obj for obj in removals] args += [os.path.join(build_dir, input) for input in inputs] Shell(*args) USAGE = '''usage: %prog [options] + 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( '-b', '--build-dir', dest='build_dir', help='build directory') 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() build_dir = opt.build_dir 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(build_dir, output, remove_re, args) return 0 if __name__ == '__main__': sys.exit(Main())