summaryrefslogtreecommitdiffstats
path: root/build
diff options
context:
space:
mode:
authorcjhopman@chromium.org <cjhopman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-02 20:36:13 +0000
committercjhopman@chromium.org <cjhopman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-02 20:36:13 +0000
commit46aac2e9c09e577aea1190fa5356fbc4cef3be18 (patch)
tree11246a1b318d2aafbbed1e815e01043606d92f8e /build
parent66476cfc14e697bed75fa90161b3de800f639d76 (diff)
downloadchromium_src-46aac2e9c09e577aea1190fa5356fbc4cef3be18.zip
chromium_src-46aac2e9c09e577aea1190fa5356fbc4cef3be18.tar.gz
chromium_src-46aac2e9c09e577aea1190fa5356fbc4cef3be18.tar.bz2
Push native libraries separately when gyp manages install
When an APK is installed, any native libraries it contains are extracted to the APK's lib folder on the device. It is actually possible to add, change, or remove libraries in that folder directly. This means, that when gyp is managing the install of APKs, the APK does not actually need to include the native library, and that can be pushed separately. This does several nice things: libraries can be pushed while a .apk is building .apk no longer needs to be rebuilt+reinstalled when a library changes if native library isn't changed, it doesn't need to be zipped+installed w/ component build, only changed libraries will need to be reinstalled BUG=158821 Review URL: https://chromiumcodereview.appspot.com/13334003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@191888 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'build')
-rwxr-xr-xbuild/android/gyp/create_device_library_links.py72
-rwxr-xr-xbuild/android/gyp/push_libraries.py55
-rwxr-xr-xbuild/android/process_resources.py4
-rw-r--r--build/android/pylib/build_utils.py12
-rw-r--r--build/java_apk.gypi66
5 files changed, 200 insertions, 9 deletions
diff --git a/build/android/gyp/create_device_library_links.py b/build/android/gyp/create_device_library_links.py
new file mode 100755
index 0000000..f569f4b
--- /dev/null
+++ b/build/android/gyp/create_device_library_links.py
@@ -0,0 +1,72 @@
+#!/usr/bin/env python
+#
+# 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.
+
+"""Creates symlinks to native libraries for an APK.
+
+The native libraries should have previously been pushed to the device (in
+options.target_dir). This script then creates links in an apk's lib/ folder to
+those native libraries.
+"""
+
+import json
+import optparse
+import os
+import sys
+
+BUILD_ANDROID_DIR = os.path.join(os.path.dirname(__file__), '..')
+sys.path.append(BUILD_ANDROID_DIR)
+
+from pylib import android_commands
+from pylib import build_utils
+from pylib.utils import apk_helper
+
+
+def CreateLinks(options):
+ libraries = build_utils.ReadJson(options.libraries_json)
+ apk_package = apk_helper.GetPackageName(options.apk)
+
+ # There is a large (~100ms) overhead for each call to adb.RunShellCommand. To
+ # avoid this overhead, craft a single command that creates all the links.
+ link = '/data/data/' + apk_package + '/lib/$f'
+ target = options.target_dir + '/$f'
+ names = ' '.join(libraries)
+ cmd = (
+ 'for f in ' + names + '; do \n' +
+ 'rm ' + link + ' > /dev/null 2>&1 \n' +
+ 'ln -s ' + target + ' ' + link + '\n' +
+ 'done'
+ )
+
+ adb = android_commands.AndroidCommands()
+ result = adb.RunShellCommand(cmd)
+
+ if result:
+ raise Exception(
+ 'Unexpected output creating links on device.\n' +
+ '\n'.join(result))
+
+
+def main(argv):
+ parser = optparse.OptionParser()
+ parser.add_option('--apk', help='Path to the apk.')
+ parser.add_option('--libraries-json',
+ help='Path to the json list of native libraries.')
+ parser.add_option('--target-dir',
+ help='Device directory that contains the target libraries for symlinks.')
+ parser.add_option('--stamp', help='Path to touch on success.')
+ options, _ = parser.parse_args()
+
+ required_options = ['apk', 'libraries_json', 'target_dir']
+ build_utils.CheckOptions(options, parser, required=required_options)
+
+ CreateLinks(options)
+
+ if options.stamp:
+ build_utils.Touch(options.stamp)
+
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv))
diff --git a/build/android/gyp/push_libraries.py b/build/android/gyp/push_libraries.py
new file mode 100755
index 0000000..9c7366e
--- /dev/null
+++ b/build/android/gyp/push_libraries.py
@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+#
+# 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.
+
+"""Pushes native libraries to a device.
+
+"""
+
+import json
+import optparse
+import os
+import sys
+
+BUILD_ANDROID_DIR = os.path.join(os.path.dirname(__file__), '..')
+sys.path.append(BUILD_ANDROID_DIR)
+
+from pylib import android_commands
+from pylib import build_utils
+
+
+def DoPush(options):
+ libraries = build_utils.ReadJson(options.libraries_json)
+
+ adb = android_commands.AndroidCommands()
+ adb.RunShellCommand('mkdir ' + options.device_dir)
+ for lib in libraries:
+ device_path = os.path.join(options.device_dir, lib)
+ host_path = os.path.join(options.libraries_dir, lib)
+ adb.PushIfNeeded(host_path, device_path)
+
+
+def main(argv):
+ parser = optparse.OptionParser()
+ parser.add_option('--libraries-dir',
+ help='Directory that contains stripped libraries.')
+ parser.add_option('--device-dir',
+ help='Device directory to push the libraries to.')
+ parser.add_option('--libraries-json',
+ help='Path to the json list of native libraries.')
+ parser.add_option('--stamp', help='Path to touch on success.')
+ options, _ = parser.parse_args()
+
+ required_options = ['libraries_dir', 'device_dir', 'libraries_json']
+ build_utils.CheckOptions(options, parser, required=required_options)
+
+ DoPush(options)
+
+ if options.stamp:
+ build_utils.Touch(options.stamp)
+
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv))
diff --git a/build/android/process_resources.py b/build/android/process_resources.py
index 541fb56..a39ac1a 100755
--- a/build/android/process_resources.py
+++ b/build/android/process_resources.py
@@ -45,9 +45,7 @@ def ParseArgs():
# Check that required options have been provided.
required_options = ('android_sdk', 'android_sdk_tools', 'R_dir', 'res_dirs',
'crunch_input_dir', 'crunch_output_dir')
- for option_name in required_options:
- if not getattr(options, option_name):
- parser.error('--%s is required' % option_name.replace('_', '-'))
+ build_utils.CheckOptions(options, parser, required=required_options)
return options
diff --git a/build/android/pylib/build_utils.py b/build/android/pylib/build_utils.py
index ce7ed9e..8a2c7615 100644
--- a/build/android/pylib/build_utils.py
+++ b/build/android/pylib/build_utils.py
@@ -3,6 +3,7 @@
# found in the LICENSE file.
import fnmatch
+import json
import os
import pipes
import shlex
@@ -55,6 +56,17 @@ def ParseGypList(gyp_string):
return shlex.split(gyp_string)
+def CheckOptions(options, parser, required=[]):
+ for option_name in required:
+ if not getattr(options, option_name):
+ parser.error('--%s is required' % option_name.replace('_', '-'))
+
+
+def ReadJson(path):
+ with open(path, 'r') as jsonfile:
+ return json.load(jsonfile)
+
+
# This can be used in most cases like subprocess.check_call. The output,
# particularly when the command fails, better highlights the command's failure.
# This call will directly exit on a failure in the subprocess so that no python
diff --git a/build/java_apk.gypi b/build/java_apk.gypi
index 54d55ff..cf8dd49 100644
--- a/build/java_apk.gypi
+++ b/build/java_apk.gypi
@@ -73,8 +73,8 @@
'intermediate_dir': '<(PRODUCT_DIR)/<(_target_name)',
'asset_location%': '<(intermediate_dir)/assets',
'codegen_stamp': '<(intermediate_dir)/codegen.stamp',
- 'compile_input_paths': [ ],
- 'package_input_paths': [ ],
+ 'compile_input_paths': [],
+ 'package_input_paths': [],
'ordered_libraries_file': '<(intermediate_dir)/native_libraries.json',
# TODO(cjhopman): build/ shouldn't refer to content/. The libraryloader and
# nativelibraries template should be moved out of content/ (to base/?).
@@ -97,6 +97,8 @@
'obfuscated_jar_path': '<(intermediate_dir)/obfuscated.jar',
'dex_path': '<(intermediate_dir)/classes.dex',
'android_manifest': '<(java_in_dir)/AndroidManifest.xml',
+ 'push_stamp': '<(intermediate_dir)/push.stamp',
+ 'link_stamp': '<(intermediate_dir)/link.stamp',
'codegen_input_paths': [],
'final_apk_path': '<(PRODUCT_DIR)/apks/<(apk_name).apk',
'apk_install_stamp': '<(intermediate_dir)/apk_install.stamp',
@@ -128,7 +130,6 @@
'variables': {
'compile_input_paths': [ '<(native_libraries_java_stamp)' ],
'generated_src_dirs': [ '<(native_libraries_java_dir)' ],
- 'package_input_paths': [ '<(strip_stamp)' ],
},
'actions': [
{
@@ -189,9 +190,6 @@
{
'action_name': 'strip_native_libraries',
'message': 'Stripping libraries for <(_target_name)',
- 'variables': {
- 'apk_libraries_dir': '<(intermediate_dir)/libs/<(android_app_abi)',
- },
'inputs': [
'<(DEPTH)/build/android/pylib/build_utils.py',
'<(DEPTH)/build/android/strip_library_for_apk.py',
@@ -211,6 +209,62 @@
],
},
],
+ 'conditions': [
+ ['gyp_managed_install == 1', {
+ 'variables': {
+ 'apk_libraries_dir': '<(intermediate_dir)/lib.stripped/',
+ 'device_library_dir': '/data/local/tmp/chromium/lib.stripped/<(_target_name)',
+ },
+ 'dependencies': [
+ '<(DEPTH)/tools/android/md5sum/md5sum.gyp:md5sum',
+ ],
+ 'actions': [
+ {
+ 'action_name': 'push_libraries_<(_target_name)',
+ 'message': 'Pushing libraries to device for <(_target_name)',
+ 'inputs': [
+ '<(DEPTH)/build/android/pylib/build_utils.py',
+ '<(DEPTH)/build/android/gyp/push_libraries.py',
+ '<(strip_stamp)',
+ ],
+ 'outputs': [
+ '<(push_stamp)'
+ ],
+ '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)',
+ ],
+ },
+ {
+ 'action_name': 'create_library_links',
+ 'message': 'Creating links on device for <(_target_name).',
+ 'inputs': [
+ '<(DEPTH)/build/android/gyp/create_device_library_links.py',
+ '<(apk_install_stamp)',
+ '<(push_stamp)'
+ ],
+ 'outputs': [
+ '<(link_stamp)'
+ ],
+ 'action': [
+ 'python', '<(DEPTH)/build/android/gyp/create_device_library_links.py',
+ '--apk=<(final_apk_path)',
+ '--libraries-json=<(ordered_libraries_file)',
+ '--target-dir=<(device_library_dir)',
+ '--stamp=<(link_stamp)',
+ ],
+ },
+ ],
+ }, {
+ 'variables': {
+ 'apk_libraries_dir': '<(intermediate_dir)/libs/<(android_app_abi)',
+ 'package_input_paths': [ '<(strip_stamp)' ],
+ },
+ }],
+ ],
}], # native_libs_paths != []
['java_strings_grd != ""', {
'variables': {