15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#!/usr/bin/env python 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Copyright (c) 2011 The Chromium Authors. All rights reserved. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# found in the LICENSE file. 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# TODO(slightlyoff): move to using shared version of this script. 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)'''This script makes it easy to combine libs and object files to a new lib, 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)optionally removing some of the object files in the input libs by regular 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)expression matching. 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)For usage information, run the script with a --help argument. 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)''' 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import optparse 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import os 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import re 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import subprocess 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import sys 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def Shell(*args): 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '''Runs the program and args in args, returns the output from the program.''' 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) process = subprocess.Popen(args, 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stdin = None, 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stdout = subprocess.PIPE, 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stderr = subprocess.STDOUT) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output = process.stdout.readlines() 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) process.wait() 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) retcode = process.returncode 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if retcode != 0: 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise RuntimeError('%s exited with status %d' % (args[0], retcode)) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return output 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def CollectRemovals(remove_re, inputs): 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '''Returns a list of all object files in inputs that match remove_re.''' 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) removals = [] 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for input in inputs: 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output = Shell('lib.exe', '/list', input) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for line in output: 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) line = line.rstrip() 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if remove_re.search(line): 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) removals.append(line) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return removals 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def CombineLibraries(output, remove_re, inputs): 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '''Combines all the libraries and objects in inputs, while removing any 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) object files that match remove_re. 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ''' 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) removals = [] 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if remove_re: 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) removals = CollectRemovals(remove_re, inputs) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print removals 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args = ['lib.exe', '/out:%s' % output] 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args += ['/remove:%s' % obj for obj in removals] 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args += inputs 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Shell(*args) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)USAGE = '''usage: %prog [options] <lib or obj>+ 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Combines input libraries or objects into an output library, while removing 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)any object file (in the input libraries) that matches a given regular 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)expression. 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)''' 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def GetOptionParser(): 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parser = optparse.OptionParser(USAGE) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parser.add_option('-o', '--output', dest = 'output', 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) help = 'write to this output library') 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parser.add_option('-r', '--remove', dest = 'remove', 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) help = 'object files matching this regexp will be removed ' 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'from the output library') 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return parser 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def Main(): 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '''Main function for this script''' 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parser = GetOptionParser() 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (opt, args) = parser.parse_args() 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output = opt.output 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remove = opt.remove 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not output: 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parser.error('You must specify an output file') 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not args: 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parser.error('You must specify at least one object or library') 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output = output.strip() 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remove = remove.strip() 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if remove: 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remove_re = re.compile(opt.remove) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except: 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parser.error('%s is not a valid regular expression' % opt.remove) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remove_re = None 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if sys.platform != 'win32' and sys.platform != 'cygwin': 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parser.error('this script only works on Windows for now') 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # If this is set, we can't capture lib.exe's output. 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if 'VS_UNICODE_OUTPUT' in os.environ: 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) del os.environ['VS_UNICODE_OUTPUT'] 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CombineLibraries(output, remove_re, args) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if __name__ == '__main__': 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sys.exit(Main()) 117