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

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

Issue 1418243003: Add GN template for android_assets(). Use it in content_shell_apk. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: review comments & two-pass _AddAssets Created 5 years, 1 month 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
« no previous file with comments | « no previous file | build/android/gyp/write_build_config.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # 2 #
3 # Copyright (c) 2015 The Chromium Authors. All rights reserved. 3 # Copyright (c) 2015 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 """Adds the code parts to a resource APK.""" 7 """Adds the code parts to a resource APK."""
8 8
9 import argparse 9 import argparse
10 import itertools
10 import os 11 import os
11 import shutil 12 import shutil
12 import sys 13 import sys
13 import zipfile 14 import zipfile
14 15
15 from util import build_utils 16 from util import build_utils
16 17
17 18
19 # Taken from aapt's Package.cpp:
20 _NO_COMPRESS_EXTENSIONS = ('.jpg', '.jpeg', '.png', '.gif', '.wav', '.mp2',
21 '.mp3', '.ogg', '.aac', '.mpg', '.mpeg', '.mid',
22 '.midi', '.smf', '.jet', '.rtttl', '.imy', '.xmf',
23 '.mp4', '.m4a', '.m4v', '.3gp', '.3gpp', '.3g2',
24 '.3gpp2', '.amr', '.awb', '.wma', '.wmv')
25
26
18 def _ParseArgs(args): 27 def _ParseArgs(args):
19 parser = argparse.ArgumentParser() 28 parser = argparse.ArgumentParser()
20 build_utils.AddDepfileOption(parser) 29 build_utils.AddDepfileOption(parser)
30 parser.add_argument('--assets',
31 help='GYP-list of files to add as assets in the form '
32 '"srcPath:zipPath", where ":zipPath" is optional.',
33 default='[]')
34 parser.add_argument('--uncompressed-assets',
35 help='Same as --assets, except disables compression.',
36 default='[]')
21 parser.add_argument('--resource-apk', 37 parser.add_argument('--resource-apk',
22 help='An .ap_ file built using aapt', 38 help='An .ap_ file built using aapt',
23 required=True) 39 required=True)
24 parser.add_argument('--output-apk', 40 parser.add_argument('--output-apk',
25 help='Path to the output file', 41 help='Path to the output file',
26 required=True) 42 required=True)
27 parser.add_argument('--dex-file', 43 parser.add_argument('--dex-file',
28 help='Path to the classes.dex to use') 44 help='Path to the classes.dex to use')
29 # TODO(agrieve): Switch this to be a list of files rather than a directory. 45 # TODO(agrieve): Switch this to be a list of files rather than a directory.
30 parser.add_argument('--native-libs-dir', 46 parser.add_argument('--native-libs-dir',
31 help='Directory containing native libraries to include', 47 help='Directory containing native libraries to include',
32 default=[]) 48 default=[])
33 parser.add_argument('--android-abi', 49 parser.add_argument('--android-abi',
34 help='Android architecture to use for native libraries') 50 help='Android architecture to use for native libraries')
35 parser.add_argument('--create-placeholder-lib', 51 parser.add_argument('--create-placeholder-lib',
36 action='store_true', 52 action='store_true',
37 help='Whether to add a dummy library file') 53 help='Whether to add a dummy library file')
38 options = parser.parse_args(args) 54 options = parser.parse_args(args)
39 if not options.android_abi and (options.native_libs_dir or 55 if not options.android_abi and (options.native_libs_dir or
40 options.create_placeholder_lib): 56 options.create_placeholder_lib):
41 raise Exception('Must specify --android-abi with --native-libs-dir') 57 raise Exception('Must specify --android-abi with --native-libs-dir')
58 options.assets = build_utils.ParseGypList(options.assets)
59 options.uncompressed_assets = build_utils.ParseGypList(
60 options.uncompressed_assets)
42 return options 61 return options
43 62
44 63
45 def _ListSubPaths(path): 64 def _ListSubPaths(path):
46 """Returns a list of full paths to all files in the given path.""" 65 """Returns a list of full paths to all files in the given path."""
47 return [os.path.join(path, name) for name in os.listdir(path)] 66 return [os.path.join(path, name) for name in os.listdir(path)]
48 67
49 68
69 def _SplitAssetPath(path):
70 """Returns (src, dest) given an asset path in the form src[:dest]."""
71 path_parts = path.split(':')
72 src_path = path_parts[0]
73 if len(path_parts) > 1:
74 dest_path = path_parts[1]
75 else:
76 dest_path = os.path.basename(src_path)
77 return src_path, dest_path
78
79
80 def _AddAssets(apk, paths, disable_compression=False):
81 """Adds the given paths to the apk.
82
83 Args:
84 apk: ZipFile to write to.
85 paths: List of paths (with optional :zipPath suffix) to add.
86 disable_compression: Whether to disable compression.
87 """
88 # Group all uncompressed assets together in the hope that it will increase
89 # locality of mmap'ed files.
90 for target_compress_type in (zipfile.ZIP_STORED, zipfile.ZIP_DEFLATED):
91 for path in paths:
92 src_path, dest_path = _SplitAssetPath(path)
93
94 compress_type = zipfile.ZIP_DEFLATED
95 if disable_compression or (
96 os.path.splitext(src_path)[1] in _NO_COMPRESS_EXTENSIONS):
97 compress_type = zipfile.ZIP_STORED
98
99 if target_compress_type == compress_type:
100 apk_path = 'assets/' + dest_path
101 try:
102 apk.getinfo(apk_path)
103 # Should never happen since write_build_config.py handles merging.
104 raise Exception('Multiple targets specified the asset path: %s' %
105 apk_path)
106 except KeyError:
107 apk.write(src_path, apk_path, compress_type)
108
109
50 def main(args): 110 def main(args):
51 args = build_utils.ExpandFileArgs(args) 111 args = build_utils.ExpandFileArgs(args)
52 options = _ParseArgs(args) 112 options = _ParseArgs(args)
53 113
54 native_libs = [] 114 native_libs = []
55 if options.native_libs_dir: 115 if options.native_libs_dir:
56 native_libs = _ListSubPaths(options.native_libs_dir) 116 native_libs = _ListSubPaths(options.native_libs_dir)
57 117
58 input_paths = [options.resource_apk] + native_libs 118 input_paths = [options.resource_apk, __file__] + native_libs
59 if options.dex_file: 119 if options.dex_file:
60 input_paths.append(options.dex_file) 120 input_paths.append(options.dex_file)
61 121
122 input_strings = [options.create_placeholder_lib, options.android_abi]
123
124 for path in itertools.chain(options.assets, options.uncompressed_assets):
125 src_path, dest_path = _SplitAssetPath(path)
126 input_paths.append(src_path)
127 input_strings.append(dest_path)
128
62 def on_stale_md5(): 129 def on_stale_md5():
63 tmp_apk = options.output_apk + '.tmp' 130 tmp_apk = options.output_apk + '.tmp'
64 try: 131 try:
65 # Use a temp file to avoid creating an output if anything goes wrong. 132 # Use a temp file to avoid creating an output if anything goes wrong.
66 shutil.copyfile(options.resource_apk, tmp_apk) 133 shutil.copyfile(options.resource_apk, tmp_apk)
67 134
68 # TODO(agrieve): It would be more efficient to combine this step 135 # TODO(agrieve): It would be more efficient to combine this step
69 # with finalize_apk(), which sometimes aligns and uncompresses the 136 # with finalize_apk(), which sometimes aligns and uncompresses the
70 # native libraries. 137 # native libraries.
71 with zipfile.ZipFile(tmp_apk, 'a', zipfile.ZIP_DEFLATED) as apk: 138 with zipfile.ZipFile(tmp_apk, 'a', zipfile.ZIP_DEFLATED) as apk:
139 _AddAssets(apk, options.assets, disable_compression=False)
140 _AddAssets(apk, options.uncompressed_assets, disable_compression=True)
72 for path in native_libs: 141 for path in native_libs:
73 basename = os.path.basename(path) 142 basename = os.path.basename(path)
74 apk.write(path, 'lib/%s/%s' % (options.android_abi, basename)) 143 apk.write(path, 'lib/%s/%s' % (options.android_abi, basename))
75 if options.create_placeholder_lib: 144 if options.create_placeholder_lib:
76 # Make it non-empty so that its checksum is non-zero and is not 145 # Make it non-empty so that its checksum is non-zero and is not
77 # ignored by md5_check. 146 # ignored by md5_check.
78 apk.writestr('lib/%s/libplaceholder.so' % options.android_abi, ':-)') 147 apk.writestr('lib/%s/libplaceholder.so' % options.android_abi, ':-)')
79 if options.dex_file: 148 if options.dex_file:
80 apk.write(options.dex_file, 'classes.dex') 149 apk.write(options.dex_file, 'classes.dex')
81 150
82 shutil.move(tmp_apk, options.output_apk) 151 shutil.move(tmp_apk, options.output_apk)
83 finally: 152 finally:
84 if os.path.exists(tmp_apk): 153 if os.path.exists(tmp_apk):
85 os.unlink(tmp_apk) 154 os.unlink(tmp_apk)
86 155
87 build_utils.CallAndWriteDepfileIfStale( 156 build_utils.CallAndWriteDepfileIfStale(
88 on_stale_md5, 157 on_stale_md5,
89 options, 158 options,
90 input_paths=input_paths, 159 input_paths=input_paths,
91 input_strings=[options.create_placeholder_lib, options.android_abi], 160 input_strings=input_strings,
92 output_paths=[options.output_apk]) 161 output_paths=[options.output_apk])
93 162
94 163
95 if __name__ == '__main__': 164 if __name__ == '__main__':
96 main(sys.argv[1:]) 165 main(sys.argv[1:])
OLDNEW
« no previous file with comments | « no previous file | build/android/gyp/write_build_config.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698