Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1438)

Side by Side Diff: build/android/write_ordered_libraries.py

Issue 13261024: Make write_library_dependencies.py find all transitive dependencies (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@pushlib
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
Yaron 2013/04/02 01:30:35 Move to build/android/gyp
cjhopman 2013/04/02 20:47:31 Done.
2 # 2 #
3 # Copyright 2013 The Chromium Authors. All rights reserved. 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 4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file. 5 # found in the LICENSE file.
6 6
7 """Writes dependency ordered list of native libraries. 7 """Writes dependency ordered list of native libraries.
8 8
9 This list of libraries is used for several steps of building an APK. 9 This list of libraries is used for several steps of building an APK.
10 In the component build, the --input-libraries only needs to be the top-level
11 library (i.e. libcontent_shell_content_view). This will then use readelf to
12 inspect the shared libraries and determine the full list of (non-system)
13 libraries that should be included in the APK.
10 """ 14 """
11 15
16 # TODO(cjhopman): See if we can expose the list of library dependencies from
17 # gyp, rather than calculating it ourselves.
18 # http://crbug.com/2255588
Yaron 2013/04/02 01:30:35 That link doesn't work for me. Wrong #? And ya, s
cjhopman 2013/04/02 20:47:31 Done.
19
12 import json 20 import json
13 import optparse 21 import optparse
14 import os 22 import os
23 import re
15 import sys 24 import sys
16 25
17 from pylib import build_utils 26 from pylib import build_utils
18 27
28 options = None
Yaron 2013/04/02 01:30:35 globals should be prefixed with "_"
cjhopman 2013/04/02 20:47:31 Done.
29 libraries_dir = None
30
31 def FullLibraryPath(library_name):
32 return '%s/%s' % (libraries_dir, library_name)
33
34
35 def IsSystemLibrary(library_name):
36 return not os.path.exists(FullLibraryPath(library_name))
37
38
39 def CallReadElf(library_name):
40 readelf_cmd = [options.readelf,
41 '-d',
42 FullLibraryPath(library_name)]
43 return build_utils.CheckCallDie(readelf_cmd)
44
45
46 def GetDependencies(library_name):
Yaron 2013/04/02 01:30:35 GetNonSystemLibraryDependencies
cjhopman 2013/04/02 20:47:31 Done.
47 elf = CallReadElf(library_name)
48 library_re = re.compile(
Yaron 2013/04/02 01:30:35 compile this once at module level
cjhopman 2013/04/02 20:47:31 Done.
49 '.*NEEDED.*Shared library: \[(?P<library_name>[\w/.]+)\]')
50 matches = library_re.findall(elf)
51 return set([lib for lib in matches if not IsSystemLibrary(lib)])
Yaron 2013/04/02 01:30:35 If you're always excluding system libraries, how a
cjhopman 2013/04/02 20:47:31 Added this to the file-level comment. System libra
Yaron 2013/04/02 21:00:41 Heh, of course. So you don't need to System.loadLi
52
53
54 def GetSortedTransitiveDependencies(libraries):
55 """Returns all transitive library dependencies in dependency order."""
56 def GraphNode(library):
57 return (library, GetDependencies(library))
58
59 # First: find all library dependencies.
60 unchecked_deps = libraries
61 all_deps = set(libraries)
62 while unchecked_deps:
63 lib = unchecked_deps.pop()
64 new_deps = GetDependencies(lib).difference(all_deps)
65 unchecked_deps.extend(new_deps)
66 all_deps = all_deps.union(new_deps)
67
68 # Then: simple, slow topological sort.
69 sorted_deps = []
70 unsorted_deps = dict(map(GraphNode, all_deps))
71 while unsorted_deps:
72 for (library, dependencies) in unsorted_deps.items():
Yaron 2013/04/02 01:30:35 nit: no parens
cjhopman 2013/04/02 20:47:31 Done.
73 if not dependencies.intersection(unsorted_deps.keys()):
74 sorted_deps.append(library)
75 del unsorted_deps[library]
76
77 return sorted_deps
78
19 79
20 def main(argv): 80 def main(argv):
21 parser = optparse.OptionParser() 81 parser = optparse.OptionParser()
22 82
23 parser.add_option('--input-libraries', 83 parser.add_option('--input-libraries',
24 help='A list of top-level input libraries') 84 help='A list of top-level input libraries')
85 parser.add_option('--readelf')
Yaron 2013/04/02 01:30:35 Add help
cjhopman 2013/04/02 20:47:31 Done.
25 parser.add_option('--output', help='Path to the generated .json file') 86 parser.add_option('--output', help='Path to the generated .json file')
26 parser.add_option('--stamp', help='Path to touch on success') 87 parser.add_option('--stamp', help='Path to touch on success')
27 88
89 global options
28 options, _ = parser.parse_args() 90 options, _ = parser.parse_args()
29 91
30 libraries = build_utils.ParseGypList(options.input_libraries) 92 libraries = build_utils.ParseGypList(options.input_libraries)
93 global libraries_dir
94 libraries_dir = os.path.dirname(libraries[0])
31 libraries = [os.path.basename(lib) for lib in libraries] 95 libraries = [os.path.basename(lib) for lib in libraries]
32 96
97 libraries = GetSortedTransitiveDependencies(libraries)
98
33 with open(options.output, 'w') as outfile: 99 with open(options.output, 'w') as outfile:
34 json.dump(libraries, outfile) 100 json.dump(libraries, outfile)
35 101
36 if options.stamp: 102 if options.stamp:
37 build_utils.Touch(options.stamp) 103 build_utils.Touch(options.stamp)
38 104
39 105
40 if __name__ == '__main__': 106 if __name__ == '__main__':
41 sys.exit(main(sys.argv)) 107 sys.exit(main(sys.argv))
42 108
43 109
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698