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

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

Issue 14322004: [Android] Fix forwarder for the component build (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: change distribution folder to fowarder_dist to avoid colliding with forwarder (1) 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 | Annotate | Revision Log
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
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 The list excludes any Android system libraries, as those are not bundled with 9 The list excludes any Android system libraries, as those are not bundled with
10 the APK. 10 the APK.
(...skipping 10 matching lines...) Expand all
21 # http://crbug.com/225558 21 # http://crbug.com/225558
22 22
23 import json 23 import json
24 import optparse 24 import optparse
25 import os 25 import os
26 import re 26 import re
27 import sys 27 import sys
28 28
29 from util import build_utils 29 from util import build_utils
30 30
31
32 _options = None 31 _options = None
33 _libraries_dir = None
34 _library_re = re.compile( 32 _library_re = re.compile(
35 '.*NEEDED.*Shared library: \[(?P<library_name>[\w/.]+)\]') 33 '.*NEEDED.*Shared library: \[(?P<library_name>[\w/.]+)\]')
36 34
37 35
38 def FullLibraryPath(library_name): 36 def FullLibraryPath(library_name):
39 return '%s/%s' % (_libraries_dir, library_name) 37 return '%s/%s' % (_options.libraries_dir, library_name)
40 38
41 39
42 def IsSystemLibrary(library_name): 40 def IsSystemLibrary(library_name):
43 # If the library doesn't exist in the libraries directory, assume that it is 41 # If the library doesn't exist in the libraries directory, assume that it is
44 # an Android system library. 42 # an Android system library.
45 return not os.path.exists(FullLibraryPath(library_name)) 43 return not os.path.exists(FullLibraryPath(library_name))
46 44
47 45
48 def CallReadElf(library_name): 46 def CallReadElf(library_or_executable):
49 readelf_cmd = [_options.readelf, 47 readelf_cmd = [_options.readelf,
50 '-d', 48 '-d',
51 FullLibraryPath(library_name)] 49 library_or_executable]
52 return build_utils.CheckCallDie(readelf_cmd, suppress_output=True) 50 return build_utils.CheckCallDie(readelf_cmd, suppress_output=True)
53 51
54 52
55 def GetDependencies(library_name): 53 def GetDependencies(library_or_executable):
56 elf = CallReadElf(library_name) 54 elf = CallReadElf(library_or_executable)
57 return set(_library_re.findall(elf)) 55 return set(_library_re.findall(elf))
58 56
59 57
60 def GetNonSystemDependencies(library_name): 58 def GetNonSystemDependencies(library_name):
61 all_deps = GetDependencies(library_name) 59 all_deps = GetDependencies(FullLibraryPath(library_name))
62 return set((lib for lib in all_deps if not IsSystemLibrary(lib))) 60 return set((lib for lib in all_deps if not IsSystemLibrary(lib)))
63 61
64 62
65 def GetSortedTransitiveDependencies(libraries): 63 def GetSortedTransitiveDependencies(libraries):
66 """Returns all transitive library dependencies in dependency order.""" 64 """Returns all transitive library dependencies in dependency order."""
67 def GraphNode(library): 65 def GraphNode(library):
68 return (library, GetNonSystemDependencies(library)) 66 return (library, GetNonSystemDependencies(library))
69 67
70 # First: find all library dependencies. 68 # First: find all library dependencies.
71 unchecked_deps = libraries 69 unchecked_deps = libraries
72 all_deps = set(libraries) 70 all_deps = set(libraries)
73 while unchecked_deps: 71 while unchecked_deps:
74 lib = unchecked_deps.pop() 72 lib = unchecked_deps.pop()
75 new_deps = GetNonSystemDependencies(lib).difference(all_deps) 73 new_deps = GetNonSystemDependencies(lib).difference(all_deps)
76 unchecked_deps.extend(new_deps) 74 unchecked_deps.extend(new_deps)
77 all_deps = all_deps.union(new_deps) 75 all_deps = all_deps.union(new_deps)
78 76
79 # Then: simple, slow topological sort. 77 # Then: simple, slow topological sort.
80 sorted_deps = [] 78 sorted_deps = []
81 unsorted_deps = dict(map(GraphNode, all_deps)) 79 unsorted_deps = dict(map(GraphNode, all_deps))
82 while unsorted_deps: 80 while unsorted_deps:
83 for library, dependencies in unsorted_deps.items(): 81 for library, dependencies in unsorted_deps.items():
84 if not dependencies.intersection(unsorted_deps.keys()): 82 if not dependencies.intersection(unsorted_deps.keys()):
85 sorted_deps.append(library) 83 sorted_deps.append(library)
86 del unsorted_deps[library] 84 del unsorted_deps[library]
87 85
88 return sorted_deps 86 return sorted_deps
89 87
88 def GetSortedTransitiveDependenciesForExecutable(executable):
89 """Returns all transitive library dependencies in dependency order."""
90 all_deps = GetDependencies(executable)
91 libraries = [lib for lib in all_deps if not IsSystemLibrary(lib)]
92 return GetSortedTransitiveDependencies(libraries)
93
90 94
91 def main(argv): 95 def main(argv):
92 parser = optparse.OptionParser() 96 parser = optparse.OptionParser()
93 97
94 parser.add_option('--input-libraries', 98 parser.add_option('--input-libraries',
95 help='A list of top-level input libraries.') 99 help='A list of top-level input libraries.')
100 parser.add_option('--libraries-dir',
101 help='The directory which contains shared libraries.')
96 parser.add_option('--readelf', help='Path to the readelf binary.') 102 parser.add_option('--readelf', help='Path to the readelf binary.')
97 parser.add_option('--output', help='Path to the generated .json file.') 103 parser.add_option('--output', help='Path to the generated .json file.')
98 parser.add_option('--stamp', help='Path to touch on success.') 104 parser.add_option('--stamp', help='Path to touch on success.')
99 105
100 global _options 106 global _options
101 _options, _ = parser.parse_args() 107 _options, _ = parser.parse_args()
102 108
103 libraries = build_utils.ParseGypList(_options.input_libraries) 109 libraries = build_utils.ParseGypList(_options.input_libraries)
104 global _libraries_dir 110 if libraries[0].endswith('.so'):
105 _libraries_dir = os.path.dirname(libraries[0]) 111 libraries = [os.path.basename(lib) for lib in libraries]
106 libraries = [os.path.basename(lib) for lib in libraries] 112 libraries = GetSortedTransitiveDependencies(libraries)
107 113 else:
108 libraries = GetSortedTransitiveDependencies(libraries) 114 libraries = GetSortedTransitiveDependenciesForExecutable(libraries[0])
109 115
110 with open(_options.output, 'w') as outfile: 116 with open(_options.output, 'w') as outfile:
111 json.dump(libraries, outfile) 117 json.dump(libraries, outfile)
112 118
113 if _options.stamp: 119 if _options.stamp:
114 build_utils.Touch(_options.stamp) 120 build_utils.Touch(_options.stamp)
115 121
116 122
117 if __name__ == '__main__': 123 if __name__ == '__main__':
118 sys.exit(main(sys.argv)) 124 sys.exit(main(sys.argv))
119 125
120 126
OLDNEW
« no previous file with comments | « build/android/gyp/strip_library_for_device.py ('k') | build/android/native_app_dependencies.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698