• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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'''This script makes it easy to combine libs and object files to a new lib,
8optionally removing some of the object files in the input libs by regular
9expression matching.
10For usage information, run the script with a --help argument.
11'''
12from __future__ import absolute_import
13from __future__ import print_function
14import optparse
15import os
16import re
17import subprocess
18import sys
19
20
21def Shell(*args):
22  '''Runs the program and args in args, returns the output from the program.'''
23  process = subprocess.Popen(
24      args, stdin=None, stdout=subprocess.PIPE, 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
33def 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
47def 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  if len(removals) > 0:
56    print('Removals: ', 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
64USAGE = '''usage: %prog [options] <lib or obj>+
65
66Combines input libraries or objects into an output library, while removing
67any object file (in the input libraries) that matches a given regular
68expression.
69'''
70
71
72def GetOptionParser():
73  parser = optparse.OptionParser(USAGE)
74  parser.add_option(
75      '-o', '--output', dest='output', help='write to this output library')
76  parser.add_option(
77      '-r',
78      '--remove',
79      dest='remove',
80      help='object files matching this regexp will be removed '
81      'from the output library')
82  return parser
83
84
85def Main():
86  '''Main function for this script'''
87  parser = GetOptionParser()
88  (opt, args) = parser.parse_args()
89  output = opt.output
90  remove = opt.remove
91  if not output:
92    parser.error('You must specify an output file')
93
94  if not args:
95    parser.error('You must specify at least one object or library')
96
97  output = output.strip()
98  if remove:
99    remove = remove.strip()
100
101  if remove:
102    try:
103      remove_re = re.compile(opt.remove)
104    except:
105      parser.error('%s is not a valid regular expression' % opt.remove)
106  else:
107    remove_re = None
108
109  if sys.platform != 'win32' and sys.platform != 'cygwin':
110    parser.error('this script only works on Windows for now')
111
112  # If this is set, we can't capture lib.exe's output.
113  if 'VS_UNICODE_OUTPUT' in os.environ:
114    del os.environ['VS_UNICODE_OUTPUT']
115
116  CombineLibraries(output, remove_re, args)
117  return 0
118
119
120if __name__ == '__main__':
121  sys.exit(Main())
122