Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / build / android / gyp / write_ordered_libraries.py
1 #!/usr/bin/env python
2 #
3 # Copyright 2013 The Chromium Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file.
6
7 """Writes dependency ordered list of native libraries.
8
9 The list excludes any Android system libraries, as those are not bundled with
10 the APK.
11
12 This list of libraries is used for several steps of building an APK.
13 In the component build, the --input-libraries only needs to be the top-level
14 library (i.e. libcontent_shell_content_view). This will then use readelf to
15 inspect the shared libraries and determine the full list of (non-system)
16 libraries that should be included in the APK.
17 """
18
19 # TODO(cjhopman): See if we can expose the list of library dependencies from
20 # gyp, rather than calculating it ourselves.
21 # http://crbug.com/225558
22
23 import optparse
24 import os
25 import re
26 import sys
27
28 from util import build_utils
29
30 _readelf = None
31 _library_dirs = None
32
33 _library_re = re.compile(
34     '.*NEEDED.*Shared library: \[(?P<library_name>[\w/.]+)\]')
35
36
37 def SetReadelfPath(path):
38   global _readelf
39   _readelf = path
40
41
42 def SetLibraryDirs(dirs):
43   global _library_dirs
44   _library_dirs = dirs
45
46
47 def FullLibraryPath(library_name):
48   assert _library_dirs is not None
49   for directory in _library_dirs:
50     path = '%s/%s' % (directory, library_name)
51     if os.path.exists(path):
52       return path
53   return library_name
54
55
56 def IsSystemLibrary(library_name):
57   # If the library doesn't exist in the libraries directory, assume that it is
58   # an Android system library.
59   return not os.path.exists(FullLibraryPath(library_name))
60
61
62 def CallReadElf(library_or_executable):
63   assert _readelf is not None
64   readelf_cmd = [_readelf,
65                  '-d',
66                  FullLibraryPath(library_or_executable)]
67   return build_utils.CheckOutput(readelf_cmd)
68
69
70 def GetDependencies(library_or_executable):
71   elf = CallReadElf(library_or_executable)
72   return set(_library_re.findall(elf))
73
74
75 def GetNonSystemDependencies(library_name):
76   all_deps = GetDependencies(FullLibraryPath(library_name))
77   return set((lib for lib in all_deps if not IsSystemLibrary(lib)))
78
79
80 def GetSortedTransitiveDependencies(libraries):
81   """Returns all transitive library dependencies in dependency order."""
82   return build_utils.GetSortedTransitiveDependencies(
83       libraries, GetNonSystemDependencies)
84
85
86 def GetSortedTransitiveDependenciesForBinaries(binaries):
87   if binaries[0].endswith('.so'):
88     libraries = [os.path.basename(lib) for lib in binaries]
89   else:
90     assert len(binaries) == 1
91     all_deps = GetDependencies(binaries[0])
92     libraries = [lib for lib in all_deps if not IsSystemLibrary(lib)]
93
94   return GetSortedTransitiveDependencies(libraries)
95
96
97 def main():
98   parser = optparse.OptionParser()
99   build_utils.AddDepfileOption(parser)
100
101   parser.add_option('--input-libraries',
102       help='A list of top-level input libraries.')
103   parser.add_option('--libraries-dir',
104       help='The directory which contains shared libraries.')
105   parser.add_option('--readelf', help='Path to the readelf binary.')
106   parser.add_option('--output', help='Path to the generated .json file.')
107   parser.add_option('--stamp', help='Path to touch on success.')
108
109   options, _ = parser.parse_args()
110
111   SetReadelfPath(options.readelf)
112   SetLibraryDirs(options.libraries_dir.split(','))
113
114   libraries = build_utils.ParseGypList(options.input_libraries)
115   if len(libraries):
116     libraries = GetSortedTransitiveDependenciesForBinaries(libraries)
117
118   # Convert to "base" library names: e.g. libfoo.so -> foo
119   java_libraries_list = (
120       '{%s}' % ','.join(['"%s"' % s[3:-3] for s in libraries]))
121
122   build_utils.WriteJson(
123       {'libraries': libraries, 'java_libraries_list': java_libraries_list},
124       options.output,
125       only_if_changed=True)
126
127   if options.stamp:
128     build_utils.Touch(options.stamp)
129
130   if options.depfile:
131     print libraries
132     build_utils.WriteDepfile(
133         options.depfile,
134         libraries + build_utils.GetPythonDependencies())
135
136
137 if __name__ == '__main__':
138   sys.exit(main())
139
140