| 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. |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 | 53 |
| 54 def __init__(self, native_library, strip_binary, output_directory, | 54 def __init__(self, native_library, strip_binary, output_directory, |
| 55 target_abi): | 55 target_abi): |
| 56 self._native_library = native_library | 56 self._native_library = native_library |
| 57 self._strip_binary = strip_binary | 57 self._strip_binary = strip_binary |
| 58 self._output_directory = os.path.abspath(output_directory) | 58 self._output_directory = os.path.abspath(output_directory) |
| 59 self._target_abi = target_abi | 59 self._target_abi = target_abi |
| 60 self._root_name = None | 60 self._root_name = None |
| 61 if self._native_library: | 61 if self._native_library: |
| 62 self._root_name = self._LibraryRoot() | 62 self._root_name = self._LibraryRoot() |
| 63 logging.warn('root name: %s', self._root_name) | 63 logging.info('root name: %s', self._root_name) |
| 64 | 64 |
| 65 def _LibraryRoot(self): | 65 def _LibraryRoot(self): |
| 66 """Return a root name for a shared library. | 66 """Return a root name for a shared library. |
| 67 | 67 |
| 68 The root name should be suitable for substitution in apk files | 68 The root name should be suitable for substitution in apk files |
| 69 like the manifest. For example, blah/foo/libbase_unittests.so | 69 like the manifest. For example, blah/foo/libbase_unittests.so |
| 70 becomes base_unittests. | 70 becomes base_unittests. |
| 71 """ | 71 """ |
| 72 rootfinder = re.match('.?lib(.+).so', | 72 rootfinder = re.match('.?lib(.+).so', |
| 73 os.path.basename(self._native_library)) | 73 os.path.basename(self._native_library)) |
| 74 if rootfinder: | 74 if rootfinder: |
| 75 return rootfinder.group(1) | 75 return rootfinder.group(1) |
| 76 else: | 76 else: |
| 77 return None | 77 return None |
| 78 | 78 |
| 79 def _CopyTemplateFilesAndClearDir(self): | 79 def _CopyTemplateFilesAndClearDir(self): |
| 80 """Copy files needed to build a new apk. | 80 """Copy files needed to build a new apk. |
| 81 | 81 |
| 82 Uses rsync to avoid unnecessary io. This call also clears outstanding | 82 Uses rsync to avoid unnecessary io. This call also clears outstanding |
| 83 files in the directory. | 83 files in the directory. |
| 84 """ | 84 """ |
| 85 srcdir = os.path.abspath(os.path.dirname(__file__)) | 85 srcdir = os.path.abspath(os.path.dirname(__file__)) |
| 86 destdir = self._output_directory | 86 destdir = self._output_directory |
| 87 if not os.path.exists(destdir): | 87 if not os.path.exists(destdir): |
| 88 os.makedirs(destdir) | 88 os.makedirs(destdir) |
| 89 elif not '/out/' in destdir: | 89 elif not '/out/' in destdir: |
| 90 raise Exception('Unbelievable output directory; bailing for safety') | 90 raise Exception('Unbelievable output directory; bailing for safety') |
| 91 logging.warning('rsync %s --> %s', self._SOURCE_FILES, destdir) | 91 logging.info('rsync %s --> %s', self._SOURCE_FILES, destdir) |
| 92 logging.info(cmd_helper.GetCmdOutput( | 92 logging.info(cmd_helper.GetCmdOutput( |
| 93 ['rsync', '-aRv', '--delete', '--exclude', '.svn'] + | 93 ['rsync', '-aRv', '--delete', '--exclude', '.svn'] + |
| 94 self._SOURCE_FILES + [destdir], cwd=srcdir)) | 94 self._SOURCE_FILES + [destdir], cwd=srcdir)) |
| 95 | 95 |
| 96 def _ReplaceStrings(self): | 96 def _ReplaceStrings(self): |
| 97 """Replace 'replaceme' strings in generated files with a root libname. | 97 """Replace 'replaceme' strings in generated files with a root libname. |
| 98 | 98 |
| 99 If we have no root libname (e.g. no shlib was specified), do nothing. | 99 If we have no root libname (e.g. no shlib was specified), do nothing. |
| 100 """ | 100 """ |
| 101 if not self._root_name: | 101 if not self._root_name: |
| 102 return | 102 return |
| 103 logging.warn('Replacing "replaceme" with ' + self._root_name) | 103 logging.info('Replacing "replaceme" with ' + self._root_name) |
| 104 for f in self._REPLACEME_FILES: | 104 for f in self._REPLACEME_FILES: |
| 105 dest = os.path.join(self._output_directory, f) | 105 dest = os.path.join(self._output_directory, f) |
| 106 contents = open(dest).read() | 106 contents = open(dest).read() |
| 107 contents = contents.replace('replaceme', self._root_name) | 107 contents = contents.replace('replaceme', self._root_name) |
| 108 dest = dest.replace('replaceme', self._root_name) # update the filename! | 108 dest = dest.replace('replaceme', self._root_name) # update the filename! |
| 109 open(dest, 'w').write(contents) | 109 open(dest, 'w').write(contents) |
| 110 | 110 |
| 111 def _CopyLibrary(self): | 111 def _CopyLibrary(self): |
| 112 """Copy the shlib into the apk source tree (if relevant).""" | 112 """Copy the shlib into the apk source tree (if relevant).""" |
| 113 if self._native_library: | 113 if self._native_library: |
| 114 destdir = os.path.join(self._output_directory, 'libs/' + self._target_abi) | 114 destdir = os.path.join(self._output_directory, 'libs/' + self._target_abi) |
| 115 if not os.path.exists(destdir): | 115 if not os.path.exists(destdir): |
| 116 os.makedirs(destdir) | 116 os.makedirs(destdir) |
| 117 dest = os.path.join(destdir, os.path.basename(self._native_library)) | 117 dest = os.path.join(destdir, os.path.basename(self._native_library)) |
| 118 logging.warn('strip %s --> %s', self._native_library, dest) | 118 logging.info('strip %s --> %s', self._native_library, dest) |
| 119 cmd_helper.RunCmd( | 119 cmd_helper.RunCmd( |
| 120 [self._strip_binary, '--strip-unneeded', self._native_library, '-o', | 120 [self._strip_binary, '--strip-unneeded', self._native_library, '-o', |
| 121 dest]) | 121 dest]) |
| 122 | 122 |
| 123 def CreateBundle(self): | 123 def CreateBundle(self): |
| 124 """Create the apk bundle source and assemble components.""" | 124 """Create the apk bundle source and assemble components.""" |
| 125 self._CopyTemplateFilesAndClearDir() | 125 self._CopyTemplateFilesAndClearDir() |
| 126 self._ReplaceStrings() | 126 self._ReplaceStrings() |
| 127 self._CopyLibrary() | 127 self._CopyLibrary() |
| 128 | 128 |
| 129 def Compile(self, ant_args): | 129 def Compile(self, ant_args): |
| 130 """Build the generated apk with ant. | 130 """Build the generated apk with ant. |
| 131 | 131 |
| 132 Args: | 132 Args: |
| 133 ant_args: extra args to pass to ant | 133 ant_args: extra args to pass to ant |
| 134 """ | 134 """ |
| 135 cmd = ['ant'] | 135 cmd = ['ant'] |
| 136 if ant_args: | 136 if ant_args: |
| 137 cmd.extend(ant_args) | 137 cmd.extend(ant_args) |
| 138 cmd.append("-DAPP_ABI=" + self._target_abi) | 138 cmd.append("-DAPP_ABI=" + self._target_abi) |
| 139 cmd.extend(['-buildfile', | 139 cmd.extend(['-buildfile', |
| 140 os.path.join(self._output_directory, 'native_test_apk.xml')]) | 140 os.path.join(self._output_directory, 'native_test_apk.xml')]) |
| 141 logging.warn(cmd) | 141 logging.info(cmd) |
| 142 p = subprocess.Popen(cmd, stderr=subprocess.STDOUT) | 142 p = subprocess.Popen(cmd, stderr=subprocess.STDOUT) |
| 143 (stdout, _) = p.communicate() | 143 (stdout, _) = p.communicate() |
| 144 logging.warn(stdout) | 144 logging.info(stdout) |
| 145 if p.returncode != 0: | 145 if p.returncode != 0: |
| 146 logging.error('Ant return code %d', p.returncode) | 146 logging.error('Ant return code %d', p.returncode) |
| 147 sys.exit(p.returncode) | 147 sys.exit(p.returncode) |
| 148 | 148 |
| 149 def main(argv): | 149 def main(argv): |
| 150 parser = optparse.OptionParser() | 150 parser = optparse.OptionParser() |
| 151 parser.add_option('--verbose', | 151 parser.add_option('--verbose', |
| 152 help='Be verbose') | 152 help='Be verbose') |
| 153 parser.add_option('--native_library', | 153 parser.add_option('--native_library', |
| 154 help='Full name of native shared library test bundle') | 154 help='Full name of native shared library test bundle') |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 188 jar_list = options.jars.replace('"', '').split() | 188 jar_list = options.jars.replace('"', '').split() |
| 189 options.ant_args.append('-DINPUT_JARS_PATHS=' + " ".join(jar_list)) | 189 options.ant_args.append('-DINPUT_JARS_PATHS=' + " ".join(jar_list)) |
| 190 | 190 |
| 191 | 191 |
| 192 ntag = NativeTestApkGenerator(native_library=options.native_library, | 192 ntag = NativeTestApkGenerator(native_library=options.native_library, |
| 193 strip_binary=options.strip_binary, | 193 strip_binary=options.strip_binary, |
| 194 output_directory=options.output, | 194 output_directory=options.output, |
| 195 target_abi=options.app_abi) | 195 target_abi=options.app_abi) |
| 196 ntag.CreateBundle() | 196 ntag.CreateBundle() |
| 197 ntag.Compile(options.ant_args) | 197 ntag.Compile(options.ant_args) |
| 198 logging.warn('COMPLETE.') | 198 logging.info('COMPLETE.') |
| 199 | 199 |
| 200 if __name__ == '__main__': | 200 if __name__ == '__main__': |
| 201 sys.exit(main(sys.argv)) | 201 sys.exit(main(sys.argv)) |
| OLD | NEW |