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

Unified 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, 9 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 side-by-side diff with in-line comments
Download patch
Index: build/android/write_ordered_libraries.py
diff --git a/build/android/write_ordered_libraries.py b/build/android/write_ordered_libraries.py
index e887672e2900b6c4dbf704f6f3357869ce5f773e..30622708219b99aa9b9dc4c00b9a56df2f8ed87f 100755
--- a/build/android/write_ordered_libraries.py
+++ b/build/android/write_ordered_libraries.py
@@ -7,29 +7,95 @@
"""Writes dependency ordered list of native libraries.
This list of libraries is used for several steps of building an APK.
+In the component build, the --input-libraries only needs to be the top-level
+library (i.e. libcontent_shell_content_view). This will then use readelf to
+inspect the shared libraries and determine the full list of (non-system)
+libraries that should be included in the APK.
"""
+# TODO(cjhopman): See if we can expose the list of library dependencies from
+# gyp, rather than calculating it ourselves.
+# 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.
+
import json
import optparse
import os
+import re
import sys
from pylib import build_utils
+options = None
Yaron 2013/04/02 01:30:35 globals should be prefixed with "_"
cjhopman 2013/04/02 20:47:31 Done.
+libraries_dir = None
+
+def FullLibraryPath(library_name):
+ return '%s/%s' % (libraries_dir, library_name)
+
+
+def IsSystemLibrary(library_name):
+ return not os.path.exists(FullLibraryPath(library_name))
+
+
+def CallReadElf(library_name):
+ readelf_cmd = [options.readelf,
+ '-d',
+ FullLibraryPath(library_name)]
+ return build_utils.CheckCallDie(readelf_cmd)
+
+
+def GetDependencies(library_name):
Yaron 2013/04/02 01:30:35 GetNonSystemLibraryDependencies
cjhopman 2013/04/02 20:47:31 Done.
+ elf = CallReadElf(library_name)
+ 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.
+ '.*NEEDED.*Shared library: \[(?P<library_name>[\w/.]+)\]')
+ matches = library_re.findall(elf)
+ 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
+
+
+def GetSortedTransitiveDependencies(libraries):
+ """Returns all transitive library dependencies in dependency order."""
+ def GraphNode(library):
+ return (library, GetDependencies(library))
+
+ # First: find all library dependencies.
+ unchecked_deps = libraries
+ all_deps = set(libraries)
+ while unchecked_deps:
+ lib = unchecked_deps.pop()
+ new_deps = GetDependencies(lib).difference(all_deps)
+ unchecked_deps.extend(new_deps)
+ all_deps = all_deps.union(new_deps)
+
+ # Then: simple, slow topological sort.
+ sorted_deps = []
+ unsorted_deps = dict(map(GraphNode, all_deps))
+ while unsorted_deps:
+ 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.
+ if not dependencies.intersection(unsorted_deps.keys()):
+ sorted_deps.append(library)
+ del unsorted_deps[library]
+
+ return sorted_deps
+
def main(argv):
parser = optparse.OptionParser()
parser.add_option('--input-libraries',
help='A list of top-level input libraries')
+ parser.add_option('--readelf')
Yaron 2013/04/02 01:30:35 Add help
cjhopman 2013/04/02 20:47:31 Done.
parser.add_option('--output', help='Path to the generated .json file')
parser.add_option('--stamp', help='Path to touch on success')
+ global options
options, _ = parser.parse_args()
libraries = build_utils.ParseGypList(options.input_libraries)
+ global libraries_dir
+ libraries_dir = os.path.dirname(libraries[0])
libraries = [os.path.basename(lib) for lib in libraries]
+ libraries = GetSortedTransitiveDependencies(libraries)
+
with open(options.output, 'w') as outfile:
json.dump(libraries, outfile)

Powered by Google App Engine
This is Rietveld 408576698