OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # | 2 # |
3 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 3 # Copyright (c) 2012 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 # On Android we build unit test bundles as shared libraries. To run | 7 # On Android we build unit test bundles as shared libraries. To run |
8 # tests, we launch a special "test runner" apk which loads the library | 8 # tests, we launch a special "test runner" apk which loads the library |
9 # then jumps into it. Since java is required for many tests | 9 # then jumps into it. Since java is required for many tests |
10 # (e.g. PathUtils.java), a "pure native" test bundle is inadequate. | 10 # (e.g. PathUtils.java), a "pure native" test bundle is inadequate. |
11 # | 11 # |
12 # This script, generate_native_test.py, is used to generate the source | 12 # This script, generate_native_test.py, is used to generate the source |
13 # for an apk that wraps a unit test shared library bundle. That | 13 # for an apk that wraps a unit test shared library bundle. That |
14 # allows us to have a single boiler-plate application be used across | 14 # allows us to have a single boiler-plate application be used across |
15 # all unit test bundles. | 15 # all unit test bundles. |
16 | 16 |
17 import logging | 17 import logging |
18 import optparse | 18 import optparse |
19 import os | 19 import os |
20 import re | 20 import re |
21 import shutil | |
22 import subprocess | 21 import subprocess |
23 import sys | 22 import sys |
24 | 23 |
25 # cmd_helper.py is under ../../build/android/ | 24 # cmd_helper.py is under ../../build/android/ |
26 sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', | 25 sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', |
27 '..', 'build', 'android'))) | 26 '..', 'build', 'android'))) |
28 from pylib import cmd_helper # pylint: disable=F0401 | 27 from pylib import cmd_helper # pylint: disable=F0401 |
29 | 28 |
30 | 29 |
31 class NativeTestApkGenerator(object): | 30 class NativeTestApkGenerator(object): |
(...skipping 13 matching lines...) Expand all Loading... |
45 ] | 44 ] |
46 | 45 |
47 # Files in the destion directory that have a "replaceme" string | 46 # Files in the destion directory that have a "replaceme" string |
48 # which should be replaced by the basename of the shared library. | 47 # which should be replaced by the basename of the shared library. |
49 # Note we also update the filename if 'replaceme' is itself found in | 48 # Note we also update the filename if 'replaceme' is itself found in |
50 # the filename. | 49 # the filename. |
51 _REPLACEME_FILES = ['AndroidManifest.xml', | 50 _REPLACEME_FILES = ['AndroidManifest.xml', |
52 'native_test_apk.xml', | 51 'native_test_apk.xml', |
53 'res/values/strings.xml'] | 52 'res/values/strings.xml'] |
54 | 53 |
55 def __init__(self, native_library, jars, strip_binary, output_directory, | 54 def __init__(self, native_library, strip_binary, output_directory, |
56 target_abi): | 55 target_abi): |
57 self._native_library = native_library | 56 self._native_library = native_library |
58 self._jars = jars | |
59 self._strip_binary = strip_binary | 57 self._strip_binary = strip_binary |
60 self._output_directory = os.path.abspath(output_directory) | 58 self._output_directory = os.path.abspath(output_directory) |
61 self._target_abi = target_abi | 59 self._target_abi = target_abi |
62 self._root_name = None | 60 self._root_name = None |
63 if self._native_library: | 61 if self._native_library: |
64 self._root_name = self._LibraryRoot() | 62 self._root_name = self._LibraryRoot() |
65 logging.warn('root name: %s', self._root_name) | 63 logging.warn('root name: %s', self._root_name) |
66 | 64 |
67 def _LibraryRoot(self): | 65 def _LibraryRoot(self): |
68 """Return a root name for a shared library. | 66 """Return a root name for a shared library. |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 if not self._root_name: | 101 if not self._root_name: |
104 return | 102 return |
105 logging.warn('Replacing "replaceme" with ' + self._root_name) | 103 logging.warn('Replacing "replaceme" with ' + self._root_name) |
106 for f in self._REPLACEME_FILES: | 104 for f in self._REPLACEME_FILES: |
107 dest = os.path.join(self._output_directory, f) | 105 dest = os.path.join(self._output_directory, f) |
108 contents = open(dest).read() | 106 contents = open(dest).read() |
109 contents = contents.replace('replaceme', self._root_name) | 107 contents = contents.replace('replaceme', self._root_name) |
110 dest = dest.replace('replaceme', self._root_name) # update the filename! | 108 dest = dest.replace('replaceme', self._root_name) # update the filename! |
111 open(dest, 'w').write(contents) | 109 open(dest, 'w').write(contents) |
112 | 110 |
113 def _CopyLibraryAndJars(self): | 111 def _CopyLibrary(self): |
114 """Copy the shlib and jars into the apk source tree (if relevant).""" | 112 """Copy the shlib into the apk source tree (if relevant).""" |
115 if self._native_library: | 113 if self._native_library: |
116 destdir = os.path.join(self._output_directory, 'libs/' + self._target_abi) | 114 destdir = os.path.join(self._output_directory, 'libs/' + self._target_abi) |
117 if not os.path.exists(destdir): | 115 if not os.path.exists(destdir): |
118 os.makedirs(destdir) | 116 os.makedirs(destdir) |
119 dest = os.path.join(destdir, os.path.basename(self._native_library)) | 117 dest = os.path.join(destdir, os.path.basename(self._native_library)) |
120 logging.warn('strip %s --> %s', self._native_library, dest) | 118 logging.warn('strip %s --> %s', self._native_library, dest) |
121 cmd_helper.RunCmd( | 119 cmd_helper.RunCmd( |
122 [self._strip_binary, '--strip-unneeded', self._native_library, '-o', | 120 [self._strip_binary, '--strip-unneeded', self._native_library, '-o', |
123 dest]) | 121 dest]) |
124 if self._jars: | |
125 destdir = os.path.join(self._output_directory, 'java/libs') | |
126 if not os.path.exists(destdir): | |
127 os.makedirs(destdir) | |
128 for jar in self._jars: | |
129 dest = os.path.join(destdir, os.path.basename(jar)) | |
130 logging.warn('%s --> %s', jar, dest) | |
131 shutil.copyfile(jar, dest) | |
132 | 122 |
133 def CreateBundle(self): | 123 def CreateBundle(self): |
134 """Create the apk bundle source and assemble components.""" | 124 """Create the apk bundle source and assemble components.""" |
135 self._CopyTemplateFilesAndClearDir() | 125 self._CopyTemplateFilesAndClearDir() |
136 self._ReplaceStrings() | 126 self._ReplaceStrings() |
137 self._CopyLibraryAndJars() | 127 self._CopyLibrary() |
138 | 128 |
139 def Compile(self, ant_args): | 129 def Compile(self, ant_args): |
140 """Build the generated apk with ant. | 130 """Build the generated apk with ant. |
141 | 131 |
142 Args: | 132 Args: |
143 ant_args: extra args to pass to ant | 133 ant_args: extra args to pass to ant |
144 """ | 134 """ |
145 cmd = ['ant'] | 135 cmd = ['ant'] |
146 if ant_args: | 136 if ant_args: |
147 cmd.extend(ant_args) | 137 cmd.extend(ant_args) |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
182 raise Exception('No output directory specified for generated files') | 172 raise Exception('No output directory specified for generated files') |
183 | 173 |
184 if options.verbose: | 174 if options.verbose: |
185 logging.basicConfig(level=logging.DEBUG, format=' %(message)s') | 175 logging.basicConfig(level=logging.DEBUG, format=' %(message)s') |
186 | 176 |
187 if not options.strip_binary: | 177 if not options.strip_binary: |
188 options.strip_binary = os.getenv('STRIP') | 178 options.strip_binary = os.getenv('STRIP') |
189 if not options.strip_binary: | 179 if not options.strip_binary: |
190 raise Exception('No tool for stripping the libraries has been supplied') | 180 raise Exception('No tool for stripping the libraries has been supplied') |
191 | 181 |
192 # Remove all quotes from the jars string | 182 # Remove all quotes from the jars string and pass the list to ant as |
| 183 # INPUT_JARS_PATHS. |
| 184 # TODO(cjhopman): Remove this when all targets pass the list of jars as an |
| 185 # ant-arg directly. |
193 jar_list = [] | 186 jar_list = [] |
194 if options.jars: | 187 if options.jars: |
195 jar_list = options.jars.replace('"', '').split() | 188 jar_list = options.jars.replace('"', '').split() |
| 189 options.ant_args.append('-DINPUT_JARS_PATHS=' + " ".join(jar_list)) |
| 190 |
196 | 191 |
197 ntag = NativeTestApkGenerator(native_library=options.native_library, | 192 ntag = NativeTestApkGenerator(native_library=options.native_library, |
198 jars=jar_list, | |
199 strip_binary=options.strip_binary, | 193 strip_binary=options.strip_binary, |
200 output_directory=options.output, | 194 output_directory=options.output, |
201 target_abi=options.app_abi) | 195 target_abi=options.app_abi) |
202 ntag.CreateBundle() | 196 ntag.CreateBundle() |
203 ntag.Compile(options.ant_args) | 197 ntag.Compile(options.ant_args) |
204 logging.warn('COMPLETE.') | 198 logging.warn('COMPLETE.') |
205 | 199 |
206 if __name__ == '__main__': | 200 if __name__ == '__main__': |
207 sys.exit(main(sys.argv)) | 201 sys.exit(main(sys.argv)) |
OLD | NEW |