diff options
author | yfriedman@chromium.org <yfriedman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-18 07:23:26 +0000 |
---|---|---|
committer | yfriedman@chromium.org <yfriedman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-18 07:23:26 +0000 |
commit | 7beabebff197b32fcb8c8ddcbc638ac80c908df7 (patch) | |
tree | 3879e9d625e1671e17df92bc9e6e17d8325a61fa | |
parent | 82cafd94d689e4779840c78c842ba36f63c55efc (diff) | |
download | chromium_src-7beabebff197b32fcb8c8ddcbc638ac80c908df7.zip chromium_src-7beabebff197b32fcb8c8ddcbc638ac80c908df7.tar.gz chromium_src-7beabebff197b32fcb8c8ddcbc638ac80c908df7.tar.bz2 |
[Android] Fix forwarder for the component build
Repurposes the gyp scripts for processing native libraries for an apk and use them for a native library (i.e. forwarder).
Additionally, adjusts the forwarder python script to set LD_LIBRARY_PATH when invoking the forwarder.
BUG=158821
Review URL: https://chromiumcodereview.appspot.com/14322004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@194833 0039d316-1c4b-4281-b951-d872f2087c98
-rwxr-xr-x | build/android/gyp/strip_library_for_device.py (renamed from build/android/gyp/strip_library_for_apk.py) | 0 | ||||
-rwxr-xr-x | build/android/gyp/write_ordered_libraries.py | 32 | ||||
-rw-r--r-- | build/android/native_app_dependencies.gypi | 64 | ||||
-rw-r--r-- | build/android/push_libraries.gypi | 48 | ||||
-rw-r--r-- | build/android/pylib/forwarder.py | 17 | ||||
-rw-r--r-- | build/android/strip_native_libraries.gypi | 45 | ||||
-rw-r--r-- | build/android/write_ordered_libraries.gypi | 42 | ||||
-rw-r--r-- | build/java_apk.gypi | 83 | ||||
-rw-r--r-- | tools/android/forwarder2/forwarder.gyp | 7 |
9 files changed, 248 insertions, 90 deletions
diff --git a/build/android/gyp/strip_library_for_apk.py b/build/android/gyp/strip_library_for_device.py index 05eacfe..05eacfe 100755 --- a/build/android/gyp/strip_library_for_apk.py +++ b/build/android/gyp/strip_library_for_device.py diff --git a/build/android/gyp/write_ordered_libraries.py b/build/android/gyp/write_ordered_libraries.py index dfa7d20..11f12e0 100755 --- a/build/android/gyp/write_ordered_libraries.py +++ b/build/android/gyp/write_ordered_libraries.py @@ -28,15 +28,13 @@ import sys from util import build_utils - _options = None -_libraries_dir = None _library_re = re.compile( '.*NEEDED.*Shared library: \[(?P<library_name>[\w/.]+)\]') def FullLibraryPath(library_name): - return '%s/%s' % (_libraries_dir, library_name) + return '%s/%s' % (_options.libraries_dir, library_name) def IsSystemLibrary(library_name): @@ -45,20 +43,20 @@ def IsSystemLibrary(library_name): return not os.path.exists(FullLibraryPath(library_name)) -def CallReadElf(library_name): +def CallReadElf(library_or_executable): readelf_cmd = [_options.readelf, '-d', - FullLibraryPath(library_name)] + library_or_executable] return build_utils.CheckCallDie(readelf_cmd, suppress_output=True) -def GetDependencies(library_name): - elf = CallReadElf(library_name) +def GetDependencies(library_or_executable): + elf = CallReadElf(library_or_executable) return set(_library_re.findall(elf)) def GetNonSystemDependencies(library_name): - all_deps = GetDependencies(library_name) + all_deps = GetDependencies(FullLibraryPath(library_name)) return set((lib for lib in all_deps if not IsSystemLibrary(lib))) @@ -87,12 +85,20 @@ def GetSortedTransitiveDependencies(libraries): return sorted_deps +def GetSortedTransitiveDependenciesForExecutable(executable): + """Returns all transitive library dependencies in dependency order.""" + all_deps = GetDependencies(executable) + libraries = [lib for lib in all_deps if not IsSystemLibrary(lib)] + return GetSortedTransitiveDependencies(libraries) + def main(argv): parser = optparse.OptionParser() parser.add_option('--input-libraries', help='A list of top-level input libraries.') + parser.add_option('--libraries-dir', + help='The directory which contains shared libraries.') parser.add_option('--readelf', help='Path to the readelf binary.') parser.add_option('--output', help='Path to the generated .json file.') parser.add_option('--stamp', help='Path to touch on success.') @@ -101,11 +107,11 @@ def main(argv): _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) + if libraries[0].endswith('.so'): + libraries = [os.path.basename(lib) for lib in libraries] + libraries = GetSortedTransitiveDependencies(libraries) + else: + libraries = GetSortedTransitiveDependenciesForExecutable(libraries[0]) build_utils.WriteJson(libraries, _options.output, only_if_changed=True) diff --git a/build/android/native_app_dependencies.gypi b/build/android/native_app_dependencies.gypi new file mode 100644 index 0000000..f54dda7 --- /dev/null +++ b/build/android/native_app_dependencies.gypi @@ -0,0 +1,64 @@ +# Copyright 2013 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# This file is meant to be included into a target to provide a rule +# to strip and place dependent shared libraries required by a native binary in a +# single folder that can later be pushed to the device. +# +# NOTE: consider packaging your binary as an apk instead of running a native +# library. +# +# To use this, create a gyp target with the following form: +# { +# 'target_name': 'target_that_depends_on_my_binary', +# 'type': 'none', +# 'dependencies': [ +# 'my_binary', +# ], +# 'variables': { +# 'native_binary': '<(PRODUCT_DIR)/my_binary', +# 'output_dir': 'location to place binary and dependent libraries' +# }, +# 'includes': [ '../../build/android/native_app_dependencies.gypi' ], +# }, +# + +{ + 'variables': { + 'intermediate_dir': '<(PRODUCT_DIR)/<(_target_name)', + 'ordered_libraries_file': '<(intermediate_dir)/native_libraries.json', + 'stripped_libraries_dir%': '<(output_dir)', + 'strip_stamp': '<(intermediate_dir)/strip.stamp', + }, + 'copies': [ + { + 'destination': '<(output_dir)', + 'files': [ '<(native_binary)' ], + } + ], + 'conditions': [ + ['component == "shared_library"', { + 'dependencies': [ + '<(DEPTH)/build/android/setup.gyp:copy_system_libraries', + ], + 'variables': { + 'intermediate_dir': '<(PRODUCT_DIR)/<(_target_name)', + 'ordered_libraries_file': '<(intermediate_dir)/native_libraries.json', + 'stripped_libraries_dir%': '<(output_dir)', + 'strip_stamp': '<(intermediate_dir)/strip.stamp', + }, + 'actions': [ + { + 'variables': { + 'input_libraries': ['<(native_binary)'], + }, + 'includes': ['../../build/android/write_ordered_libraries.gypi'], + }, + { + 'includes': ['../../build/android/strip_native_libraries.gypi'], + }, + ], + }], + ], +} diff --git a/build/android/push_libraries.gypi b/build/android/push_libraries.gypi new file mode 100644 index 0000000..17f479d --- /dev/null +++ b/build/android/push_libraries.gypi @@ -0,0 +1,48 @@ +# Copyright 2013 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# This file is meant to be included into an action to provide a rule that +# pushes stripped shared libraries to the attached Android device. This should +# only be used with the gyp_managed_install flag set. +# +# To use this, create a gyp target with the following form: +# { +# 'actions': [ +# 'variables': { +# 'ordered_libraries_file': 'file generated by write_ordered_libraries' +# 'strip_stamp': 'stamp from strip action to block on' +# 'libraries_source_dir': 'location where stripped libraries are stored' +# 'device_library_dir': 'location on the device where to put pushed libraries', +# 'push_stamp': 'file to touch when the action is complete' +# }, +# 'includes': [ '../../build/android/push_libraries.gypi' ], +# ], +# }, +# + +{ + 'action_name': 'push_libraries_<(_target_name)', + 'message': 'Pushing libraries to device for <(_target_name)', + 'inputs': [ + '<(DEPTH)/build/android/gyp/util/build_utils.py', + '<(DEPTH)/build/android/gyp/util/md5_check.py', + '<(DEPTH)/build/android/gyp/push_libraries.py', + '<(strip_stamp)', + ], + 'outputs': [ + '<(push_stamp)', + # If a user switches the connected device, new libraries may + # need to be pushed even if there have been no changes. To + # ensure that the libraries on the device are always + # up-to-date, this step should always be triggered. + '<(push_stamp).fake', + ], + 'action': [ + 'python', '<(DEPTH)/build/android/gyp/push_libraries.py', + '--libraries-dir=<(libraries_source_dir)', + '--device-dir=<(device_library_dir)', + '--libraries-json=<(ordered_libraries_file)', + '--stamp=<(push_stamp)', + ], +} diff --git a/build/android/pylib/forwarder.py b/build/android/pylib/forwarder.py index 5a527fe..b808bfd 100644 --- a/build/android/pylib/forwarder.py +++ b/build/android/pylib/forwarder.py @@ -27,7 +27,11 @@ class Forwarder(object): _DEVICE_ADB_CONTROL_PORT = 'chrome_device_forwarder' _TIMEOUT_SECS = 30 - _DEVICE_FORWARDER_PATH = constants.TEST_EXECUTABLE_DIR + '/device_forwarder' + _DEVICE_FORWARDER_FOLDER = (constants.TEST_EXECUTABLE_DIR + + '/forwarder/') + _DEVICE_FORWARDER_PATH = (constants.TEST_EXECUTABLE_DIR + + '/forwarder/device_forwarder') + _LD_LIBRARY_PATH = 'LD_LIBRARY_PATH=%s' % _DEVICE_FORWARDER_FOLDER def __init__(self, adb, build_type): """Forwards TCP ports on the device back to the host. @@ -43,8 +47,8 @@ class Forwarder(object): self._host_to_device_port_map = dict() self._device_process = None self._host_forwarder_path = _MakeBinaryPath(build_type, 'host_forwarder') - self._device_forwarder_path = _MakeBinaryPath( - build_type, 'device_forwarder') + self._device_forwarder_path_on_host = os.path.join( + cmd_helper.OutDirectory.get(), build_type, 'forwarder_dist') def Run(self, port_pairs, tool, host_name): """Runs the forwarder. @@ -67,7 +71,7 @@ class Forwarder(object): if not host_adb_control_port: raise Exception('Failed to allocate a TCP port in the host machine.') self._adb.PushIfNeeded( - self._device_forwarder_path, Forwarder._DEVICE_FORWARDER_PATH) + self._device_forwarder_path_on_host, Forwarder._DEVICE_FORWARDER_FOLDER) redirection_commands = [ '%d:%d:%d:%s' % (host_adb_control_port, device, host, host_name) for device, host in port_pairs] @@ -81,8 +85,9 @@ class Forwarder(object): raise Exception('Error while running adb forward.') (exit_code, output) = self._adb.GetShellCommandStatusAndOutput( - '%s %s %s' % (tool.GetUtilWrapper(), Forwarder._DEVICE_FORWARDER_PATH, - Forwarder._DEVICE_ADB_CONTROL_PORT)) + '%s %s %s %s' % (tool.GetUtilWrapper(), Forwarder._LD_LIBRARY_PATH, + Forwarder._DEVICE_FORWARDER_PATH, + Forwarder._DEVICE_ADB_CONTROL_PORT)) if exit_code != 0: raise Exception( 'Failed to start device forwarder:\n%s' % '\n'.join(output)) diff --git a/build/android/strip_native_libraries.gypi b/build/android/strip_native_libraries.gypi new file mode 100644 index 0000000..bcf282f --- /dev/null +++ b/build/android/strip_native_libraries.gypi @@ -0,0 +1,45 @@ +# Copyright 2013 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# This file is meant to be included into an action to provide a rule that strips +# native libraries. +# +# To use this, create a gyp target with the following form: +# { +# 'actions': [ +# 'variables': { +# 'ordered_libraries_file': 'file generated by write_ordered_libraries' +# 'strip_stamp': 'file to touch when the action is complete' +# 'stripped_libraries_dir': 'directory to store stripped libraries', +# }, +# 'includes': [ '../../build/android/strip_native_libraries.gypi' ], +# ], +# }, +# + +{ + 'action_name': 'strip_native_libraries', + 'message': 'Stripping libraries for <(_target_name)', + 'inputs': [ + '<(DEPTH)/build/android/gyp/util/build_utils.py', + '<(DEPTH)/build/android/gyp/strip_library_for_device.py', + '<(ordered_libraries_file)' + ], + 'outputs': [ + '<(strip_stamp)', + # Add a fake output to force the build to always re-run this step. This + # is required because the real inputs are not known at gyp-time and + # changing base.so may not trigger changes to dependent libraries. + '<(strip_stamp).fake', + ], + 'action': [ + 'python', '<(DEPTH)/build/android/gyp/strip_library_for_device.py', + '--android-strip=<(android_strip)', + '--android-strip-arg=--strip-unneeded', + '--stripped-libraries-dir=<(stripped_libraries_dir)', + '--libraries-dir=<(SHARED_LIB_DIR)', + '--libraries-file=<(ordered_libraries_file)', + '--stamp=<(strip_stamp)', + ], +} diff --git a/build/android/write_ordered_libraries.gypi b/build/android/write_ordered_libraries.gypi new file mode 100644 index 0000000..2b24500 --- /dev/null +++ b/build/android/write_ordered_libraries.gypi @@ -0,0 +1,42 @@ +# Copyright 2013 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# This file is meant to be included into an action to provide a rule that +# generates a json file with the list of dependent libraries needed for a given +# shared library or executable. +# +# To use this, create a gyp target with the following form: +# { +# 'actions': [ +# 'variables': { +# 'input_libraries': 'shared library or executable to process', +# 'ordered_libraries_file': 'file to generate' +# }, +# 'includes': [ '../../build/android/write_ordered_libraries.gypi' ], +# ], +# }, +# + +{ + 'action_name': 'ordered_libraries_<(_target_name)', + 'message': 'Writing dependency ordered libraries for <(_target_name).', + 'variables': { + 'input_libraries%': [], + }, + 'inputs': [ + '<(DEPTH)/build/android/gyp/util/build_utils.py', + '<(DEPTH)/build/android/gyp/write_ordered_libraries.py', + '<@(input_libraries)', + ], + 'outputs': [ + '<(ordered_libraries_file)', + ], + 'action': [ + 'python', '<(DEPTH)/build/android/gyp/write_ordered_libraries.py', + '--input-libraries=<(input_libraries)', + '--libraries-dir=<(SHARED_LIB_DIR)', + '--readelf=<(android_readelf)', + '--output=<(ordered_libraries_file)', + ], +} diff --git a/build/java_apk.gypi b/build/java_apk.gypi index 8521742..ecf5474 100644 --- a/build/java_apk.gypi +++ b/build/java_apk.gypi @@ -107,7 +107,6 @@ 'final_apk_path%': '<(PRODUCT_DIR)/apks/<(apk_name).apk', 'source_dir': '<(java_in_dir)/src', 'apk_install_stamp': '<(intermediate_dir)/apk_install.stamp', - 'strip_output_paths': [], 'apk_package_native_libs_dir': '<(intermediate_dir)/libs', }, # Pass the jar path to the apk's "fake" jar target. This would be better as @@ -137,14 +136,6 @@ 'dependencies': [ '<(DEPTH)/build/android/setup.gyp:copy_system_libraries', ], - 'variables': { - # Add a fake output to force the build to always re-run this step. This - # is required because the real inputs are not known at gyp-time and - # changing base.so may not trigger changes to dependent libraries. - 'strip_output_paths': [ - '<(intermediate_dir)/<(strip_stamp).fake', - ], - }, }], ['native_lib_target != ""', { 'variables': { @@ -154,22 +145,10 @@ }, 'actions': [ { - 'action_name': 'ordered_libraries_<(_target_name)', - 'message': 'Writing dependency ordered libraries for <(_target_name).', - 'inputs': [ - '<(DEPTH)/build/android/gyp/util/build_utils.py', - '<(DEPTH)/build/android/gyp/write_ordered_libraries.py', - '<@(native_libs_paths)', - ], - 'outputs': [ - '<(ordered_libraries_file)', - ], - 'action': [ - 'python', '<(DEPTH)/build/android/gyp/write_ordered_libraries.py', - '--input-libraries=<(native_libs_paths)', - '--readelf=<(android_readelf)', - '--output=<(ordered_libraries_file)', - ], + 'variables': { + 'input_libraries': ['<@(native_libs_paths)'], + }, + 'includes': ['../build/android/write_ordered_libraries.gypi'], }, { 'action_name': 'native_libraries_template_data_<(_target_name)', @@ -210,32 +189,16 @@ ], }, { - 'action_name': 'strip_native_libraries', - 'message': 'Stripping libraries for <(_target_name)', - 'inputs': [ - '<(DEPTH)/build/android/gyp/util/build_utils.py', - '<(DEPTH)/build/android/gyp/strip_library_for_apk.py', - '<(ordered_libraries_file)' - ], - 'outputs': [ - '<(strip_stamp)', - '<@(strip_output_paths)', - ], - 'action': [ - 'python', '<(DEPTH)/build/android/gyp/strip_library_for_apk.py', - '--android-strip=<(android_strip)', - '--android-strip-arg=--strip-unneeded', - '--stripped-libraries-dir=<(apk_libraries_dir)', - '--libraries-dir=<(SHARED_LIB_DIR)', - '--libraries-file=<(ordered_libraries_file)', - '--stamp=<(strip_stamp)', - ], + 'variables': { + 'stripped_libraries_dir': '<(libraries_source_dir)', + }, + 'includes': ['../build/android/strip_native_libraries.gypi'], }, ], 'conditions': [ ['gyp_managed_install == 1', { 'variables': { - 'apk_libraries_dir': '<(intermediate_dir)/lib.stripped/<(android_app_abi)', + 'libraries_source_dir': '<(intermediate_dir)/lib.stripped/<(android_app_abi)', 'apk_package_native_libs_dir': '<(intermediate_dir)/libs.managed', 'device_library_dir': '/data/local/tmp/chromium/lib.stripped/<(_target_name)', }, @@ -244,29 +207,7 @@ ], 'actions': [ { - 'action_name': 'push_libraries_<(_target_name)', - 'message': 'Pushing libraries to device for <(_target_name)', - 'inputs': [ - '<(DEPTH)/build/android/gyp/util/build_utils.py', - '<(DEPTH)/build/android/gyp/util/md5_check.py', - '<(DEPTH)/build/android/gyp/push_libraries.py', - '<(strip_stamp)', - ], - 'outputs': [ - '<(push_stamp)', - # If a user switches the connected device, new libraries may - # need to be pushed even if there have been no changes. To - # ensure that the libraries on the device are always - # up-to-date, this step should always be triggered. - '<(push_stamp).fake', - ], - 'action': [ - 'python', '<(DEPTH)/build/android/gyp/push_libraries.py', - '--libraries-dir=<(apk_libraries_dir)', - '--device-dir=<(device_library_dir)', - '--libraries-json=<(ordered_libraries_file)', - '--stamp=<(push_stamp)', - ], + 'includes': ['../build/android/push_libraries.gypi'], }, { 'action_name': 'create_library_links', @@ -283,7 +224,7 @@ 'python', '<(DEPTH)/build/android/gyp/create_device_library_links.py', '--apk=<(final_apk_path)', '--libraries-json=<(ordered_libraries_file)', - '--libraries-dir=<(apk_libraries_dir)', + '--libraries-dir=<(libraries_source_dir)', '--target-dir=<(device_library_dir)', '--stamp=<(link_stamp)', ], @@ -292,7 +233,7 @@ }, { # gyp_managed_install != 1 'variables': { - 'apk_libraries_dir': '<(apk_package_native_libs_dir)/<(android_app_abi)', + 'libraries_source_dir': '<(apk_package_native_libs_dir)/<(android_app_abi)', 'package_input_paths': [ '<(strip_stamp)' ], }, }], diff --git a/tools/android/forwarder2/forwarder.gyp b/tools/android/forwarder2/forwarder.gyp index db21208..ddf36be 100644 --- a/tools/android/forwarder2/forwarder.gyp +++ b/tools/android/forwarder2/forwarder.gyp @@ -11,6 +11,13 @@ 'device_forwarder', 'host_forwarder#host', ], + # For the component build, ensure dependent shared libraries are stripped + # and put alongside forwarder to simplify pushing to the device. + 'variables': { + 'output_dir': '<(PRODUCT_DIR)/forwarder_dist/', + 'native_binary': '<(PRODUCT_DIR)/device_forwarder', + }, + 'includes': ['../../../build/android/native_app_dependencies.gypi'], }, { 'target_name': 'device_forwarder', |