• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2# Copyright (c) 2012 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
7from __future__ import print_function
8import os
9import shutil
10import subprocess
11import sys
12import tempfile
13
14
15def _Usage():
16  print('Usage: merge_static_libs OUTPUT_LIB INPUT_LIB [INPUT_LIB]*')
17  sys.exit(1)
18
19
20def MergeLibs(in_libs, out_lib):
21  """ Merges multiple static libraries into one.
22
23  in_libs: list of paths to static libraries to be merged
24  out_lib: path to the static library which will be created from in_libs
25  """
26  if os.name == 'posix':
27    tempdir = tempfile.mkdtemp()
28    abs_in_libs = []
29    for in_lib in in_libs:
30      abs_in_libs.append(os.path.abspath(in_lib))
31    curdir = os.getcwd()
32    os.chdir(tempdir)
33    objects = []
34    ar = os.environ.get('AR', 'ar')
35    for in_lib in abs_in_libs:
36      proc = subprocess.Popen([ar, '-t', in_lib], stdout=subprocess.PIPE)
37      proc.wait()
38      obj_str = proc.communicate()[0]
39      current_objects = obj_str.rstrip().split('\n')
40      proc = subprocess.Popen([ar, '-x', in_lib], stdout=subprocess.PIPE,
41                              stderr=subprocess.STDOUT)
42      proc.wait()
43      if proc.poll() == 0:
44        # The static library is non-thin, and we extracted objects
45        for obj in current_objects:
46          objects.append(os.path.abspath(obj))
47      elif 'thin archive' in proc.communicate()[0]:
48        # The static library is thin, so it contains the paths to its objects
49        for obj in current_objects:
50          objects.append(obj)
51      else:
52        raise Exception('Failed to extract objects from %s.' % in_lib)
53    os.chdir(curdir)
54    if not subprocess.call([ar, '-crs', out_lib] + objects) == 0:
55      raise Exception('Failed to add object files to %s' % out_lib)
56    shutil.rmtree(tempdir)
57  elif os.name == 'nt':
58    subprocess.call(['lib', '/OUT:%s' % out_lib] + in_libs)
59  else:
60    raise Exception('Error: Your platform is not supported')
61
62
63def Main():
64  if len(sys.argv) < 3:
65    _Usage()
66  out_lib = sys.argv[1]
67  in_libs = sys.argv[2:]
68  MergeLibs(in_libs, out_lib)
69
70
71if '__main__' == __name__:
72  sys.exit(Main())
73