Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 """Prints the size of each given file and optionally computes the size of | 6 """Prints the size of each given file and optionally computes the size of |
| 7 libchrome.so without the dependencies added for building with android NDK. | 7 libchrome.so without the dependencies added for building with android NDK. |
| 8 Also breaks down the contents of the APK to determine the installed size | 8 Also breaks down the contents of the APK to determine the installed size |
| 9 and assign size contributions to different classes of file. | 9 and assign size contributions to different classes of file. |
| 10 """ | 10 """ |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 104 'benchmark_name': 'resource_sizes', | 104 'benchmark_name': 'resource_sizes', |
| 105 'benchmark_description': 'APK resource size information.', | 105 'benchmark_description': 'APK resource size information.', |
| 106 'trace_rerun_options': [], | 106 'trace_rerun_options': [], |
| 107 'charts': {} | 107 'charts': {} |
| 108 } | 108 } |
| 109 _DUMP_STATIC_INITIALIZERS_PATH = os.path.join( | 109 _DUMP_STATIC_INITIALIZERS_PATH = os.path.join( |
| 110 host_paths.DIR_SOURCE_ROOT, 'tools', 'linux', 'dump-static-initializers.py') | 110 host_paths.DIR_SOURCE_ROOT, 'tools', 'linux', 'dump-static-initializers.py') |
| 111 # Pragma exists when enable_resource_whitelist_generation=true. | 111 # Pragma exists when enable_resource_whitelist_generation=true. |
| 112 _RC_HEADER_RE = re.compile( | 112 _RC_HEADER_RE = re.compile( |
| 113 r'^#define (?P<name>\w+) (?:_Pragma\(.*?\) )?(?P<id>\d+)$') | 113 r'^#define (?P<name>\w+) (?:_Pragma\(.*?\) )?(?P<id>\d+)$') |
| 114 _RE_NON_LANGUAGE_PAK = re.compile(r'^assets/.*(resources|percent)\.pak$') | |
| 115 _RE_COMPRESSED_LANGUAGE_PAK = re.compile( | |
| 116 r'\.lpak$|^assets/(?!stored-locales/).*(?!resources|percent)\.pak$') | |
| 117 _RE_STORED_LANGUAGE_PAK = re.compile(r'^assets/stored-locales/.*\.pak$') | |
| 114 _READELF_SIZES_METRICS = { | 118 _READELF_SIZES_METRICS = { |
| 115 'text': ['.text'], | 119 'text': ['.text'], |
| 116 'data': ['.data', '.rodata', '.data.rel.ro', '.data.rel.ro.local'], | 120 'data': ['.data', '.rodata', '.data.rel.ro', '.data.rel.ro.local'], |
| 117 'relocations': ['.rel.dyn', '.rel.plt', '.rela.dyn', '.rela.plt'], | 121 'relocations': ['.rel.dyn', '.rel.plt', '.rela.dyn', '.rela.plt'], |
| 118 'unwind': ['.ARM.extab', '.ARM.exidx', '.eh_frame', '.eh_frame_hdr',], | 122 'unwind': ['.ARM.extab', '.ARM.exidx', '.eh_frame', '.eh_frame_hdr',], |
| 119 'symbols': ['.dynsym', '.dynstr', '.dynamic', '.shstrtab', '.got', '.plt', | 123 'symbols': ['.dynsym', '.dynstr', '.dynamic', '.shstrtab', '.got', '.plt', |
| 120 '.got.plt', '.hash'], | 124 '.got.plt', '.hash'], |
| 121 'bss': ['.bss'], | 125 'bss': ['.bss'], |
| 122 'other': ['.init_array', '.fini_array', '.comment', '.note.gnu.gold-version', | 126 'other': ['.init_array', '.fini_array', '.comment', '.note.gnu.gold-version', |
| 123 '.ARM.attributes', '.note.gnu.build-id', '.gnu.version', | 127 '.ARM.attributes', '.note.gnu.build-id', '.gnu.version', |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 158 return section_sizes | 162 return section_sizes |
| 159 | 163 |
| 160 | 164 |
| 161 def _ParseLibBuildId(so_path, tools_prefix): | 165 def _ParseLibBuildId(so_path, tools_prefix): |
| 162 """Returns the Build ID of the given native library.""" | 166 """Returns the Build ID of the given native library.""" |
| 163 stdout = _RunReadelf(so_path, ['-n'], tools_prefix) | 167 stdout = _RunReadelf(so_path, ['-n'], tools_prefix) |
| 164 match = re.search(r'Build ID: (\w+)', stdout) | 168 match = re.search(r'Build ID: (\w+)', stdout) |
| 165 return match.group(1) if match else None | 169 return match.group(1) if match else None |
| 166 | 170 |
| 167 | 171 |
| 172 def _ParseManifestAttributes(apk_path): | |
| 173 # Check if the manifest specifies whether or not to extract native libs. | |
| 174 skip_extract_lib = False | |
| 175 output = cmd_helper.GetCmdOutput([ | |
| 176 _AAPT_PATH.read(), 'd', 'xmltree', apk_path, 'AndroidManifest.xml']) | |
| 177 m = re.search(r'extractNativeLibs\(.*\)=\(.*\)(\w)', output) | |
| 178 if m: | |
| 179 skip_extract_lib = not bool(int(m.group(1))) | |
| 180 | |
| 181 m = re.search(r'android:minSdkVersion\(\w+\)=\(type \w+\)(\w+)\n', output) | |
| 182 sdk_version = int(m.group(1), 16) | |
| 183 # Dex decompression overhead varies by Android version. | |
| 184 if sdk_version < 21: | |
| 185 dex_multiplier = 1 | |
| 186 elif sdk_version < 24: | |
| 187 dex_multiplier = 3 | |
| 188 elif 'monochrome' in apk_path.lower(): | |
| 189 # Monochrome consists of WebView and Chrome packaged into a single APK, so | |
|
agrieve
2017/06/16 01:37:16
It's not that both apps extract the dex, it's that
estevenson
2017/06/16 14:56:19
Ahhh yes that's what it is, couldn't remember. Fix
| |
| 190 # we need to account for both apps extracting the dex file. | |
| 191 dex_multiplier = 2 | |
| 192 else: | |
| 193 dex_multiplier = 1 | |
| 194 | |
| 195 return dex_multiplier, skip_extract_lib | |
| 196 | |
| 197 | |
| 168 def CountStaticInitializers(so_path, tools_prefix): | 198 def CountStaticInitializers(so_path, tools_prefix): |
| 169 # Static initializers expected in official builds. Note that this list is | 199 # Static initializers expected in official builds. Note that this list is |
| 170 # built using 'nm' on libchrome.so which results from a GCC official build | 200 # built using 'nm' on libchrome.so which results from a GCC official build |
| 171 # (i.e. Clang is not supported currently). | 201 # (i.e. Clang is not supported currently). |
| 172 def get_elf_section_size(readelf_stdout, section_name): | 202 def get_elf_section_size(readelf_stdout, section_name): |
| 173 # Matches: .ctors PROGBITS 000000000516add0 5169dd0 000010 00 WA 0 0 8 | 203 # Matches: .ctors PROGBITS 000000000516add0 5169dd0 000010 00 WA 0 0 8 |
| 174 match = re.search(r'\.%s.*$' % re.escape(section_name), | 204 match = re.search(r'\.%s.*$' % re.escape(section_name), |
| 175 readelf_stdout, re.MULTILINE) | 205 readelf_stdout, re.MULTILINE) |
| 176 if not match: | 206 if not match: |
| 177 return (False, -1) | 207 return (False, -1) |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 200 return si_count | 230 return si_count |
| 201 | 231 |
| 202 | 232 |
| 203 def GetStaticInitializers(so_path, tools_prefix): | 233 def GetStaticInitializers(so_path, tools_prefix): |
| 204 output = cmd_helper.GetCmdOutput([_DUMP_STATIC_INITIALIZERS_PATH, '-d', | 234 output = cmd_helper.GetCmdOutput([_DUMP_STATIC_INITIALIZERS_PATH, '-d', |
| 205 so_path, '-t', tools_prefix]) | 235 so_path, '-t', tools_prefix]) |
| 206 summary = re.search(r'Found \d+ static initializers in (\d+) files.', output) | 236 summary = re.search(r'Found \d+ static initializers in (\d+) files.', output) |
| 207 return output.splitlines()[:-1], int(summary.group(1)) | 237 return output.splitlines()[:-1], int(summary.group(1)) |
| 208 | 238 |
| 209 | 239 |
| 240 def _NormalizeLanguagePaks(translations, normalized_apk_size, factor): | |
| 241 english_pak = translations.FindByPattern(r'.*/en[-_][Uu][Ss]\.l?pak') | |
| 242 num_translations = translations.GetNumEntries() | |
| 243 if english_pak: | |
| 244 normalized_apk_size -= translations.ComputeZippedSize() | |
| 245 normalized_apk_size += int( | |
| 246 english_pak.compress_size * num_translations * factor) | |
| 247 return normalized_apk_size | |
| 248 | |
| 249 | |
| 210 def _NormalizeResourcesArsc(apk_path): | 250 def _NormalizeResourcesArsc(apk_path): |
| 211 """Estimates the expected overhead of untranslated strings in resources.arsc. | 251 """Estimates the expected overhead of untranslated strings in resources.arsc. |
| 212 | 252 |
| 213 See http://crbug.com/677966 for why this is necessary. | 253 See http://crbug.com/677966 for why this is necessary. |
| 214 """ | 254 """ |
| 215 aapt_output = _RunAaptDumpResources(apk_path) | 255 aapt_output = _RunAaptDumpResources(apk_path) |
| 216 | 256 |
| 217 # en-rUS is in the default config and may be cluttered with non-translatable | 257 # en-rUS is in the default config and may be cluttered with non-translatable |
| 218 # strings, so en-rGB is a better baseline for finding missing translations. | 258 # strings, so en-rGB is a better baseline for finding missing translations. |
| 219 en_strings = _CreateResourceIdValueMap(aapt_output, 'en-rGB') | 259 en_strings = _CreateResourceIdValueMap(aapt_output, 'en-rGB') |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 275 perf_tests_results_helper.PrintPerfResult( | 315 perf_tests_results_helper.PrintPerfResult( |
| 276 graph_title, trace_title, [value], units) | 316 graph_title, trace_title, [value], units) |
| 277 | 317 |
| 278 | 318 |
| 279 class _FileGroup(object): | 319 class _FileGroup(object): |
| 280 """Represents a category that apk files can fall into.""" | 320 """Represents a category that apk files can fall into.""" |
| 281 | 321 |
| 282 def __init__(self, name): | 322 def __init__(self, name): |
| 283 self.name = name | 323 self.name = name |
| 284 self._zip_infos = [] | 324 self._zip_infos = [] |
| 285 self._extracted = [] | 325 self._extracted_multipliers = [] |
| 286 | 326 |
| 287 def AddZipInfo(self, zip_info, extracted=False): | 327 def AddZipInfo(self, zip_info, extracted_multiplier=0): |
| 288 self._zip_infos.append(zip_info) | 328 self._zip_infos.append(zip_info) |
| 289 self._extracted.append(extracted) | 329 self._extracted_multipliers.append(extracted_multiplier) |
| 290 | 330 |
| 291 def AllEntries(self): | 331 def AllEntries(self): |
| 292 return iter(self._zip_infos) | 332 return iter(self._zip_infos) |
| 293 | 333 |
| 294 def GetNumEntries(self): | 334 def GetNumEntries(self): |
| 295 return len(self._zip_infos) | 335 return len(self._zip_infos) |
| 296 | 336 |
| 297 def FindByPattern(self, pattern): | 337 def FindByPattern(self, pattern): |
| 298 return next((i for i in self._zip_infos if re.match(pattern, i.filename)), | 338 return next((i for i in self._zip_infos if re.match(pattern, i.filename)), |
| 299 None) | 339 None) |
| 300 | 340 |
| 301 def FindLargest(self): | 341 def FindLargest(self): |
| 302 if not self._zip_infos: | 342 if not self._zip_infos: |
| 303 return None | 343 return None |
| 304 return max(self._zip_infos, key=lambda i: i.file_size) | 344 return max(self._zip_infos, key=lambda i: i.file_size) |
| 305 | 345 |
| 306 def ComputeZippedSize(self): | 346 def ComputeZippedSize(self): |
| 307 return sum(i.compress_size for i in self._zip_infos) | 347 return sum(i.compress_size for i in self._zip_infos) |
| 308 | 348 |
| 309 def ComputeUncompressedSize(self): | 349 def ComputeUncompressedSize(self): |
| 310 return sum(i.file_size for i in self._zip_infos) | 350 return sum(i.file_size for i in self._zip_infos) |
| 311 | 351 |
| 312 def ComputeExtractedSize(self): | 352 def ComputeExtractedSize(self): |
| 313 ret = 0 | 353 ret = 0 |
| 314 for zi, extracted in zip(self._zip_infos, self._extracted): | 354 for zi, multiplier in zip(self._zip_infos, self._extracted_multipliers): |
| 315 if extracted: | 355 ret += zi.file_size * multiplier |
| 316 ret += zi.file_size | |
| 317 return ret | 356 return ret |
| 318 | 357 |
| 319 def ComputeInstallSize(self): | 358 def ComputeInstallSize(self): |
| 320 return self.ComputeExtractedSize() + self.ComputeZippedSize() | 359 return self.ComputeExtractedSize() + self.ComputeZippedSize() |
| 321 | 360 |
| 322 | 361 |
| 323 def PrintApkAnalysis(apk_filename, tools_prefix, chartjson=None): | 362 def PrintApkAnalysis(apk_filename, tools_prefix, chartjson=None): |
| 324 """Analyse APK to determine size contributions of different file classes.""" | 363 """Analyse APK to determine size contributions of different file classes.""" |
| 325 file_groups = [] | 364 file_groups = [] |
| 326 | 365 |
| 327 def make_group(name): | 366 def make_group(name): |
| 328 group = _FileGroup(name) | 367 group = _FileGroup(name) |
| 329 file_groups.append(group) | 368 file_groups.append(group) |
| 330 return group | 369 return group |
| 331 | 370 |
| 332 native_code = make_group('Native code') | 371 native_code = make_group('Native code') |
| 333 java_code = make_group('Java code') | 372 java_code = make_group('Java code') |
| 334 native_resources_no_translations = make_group('Native resources (no l10n)') | 373 native_resources_no_translations = make_group('Native resources (no l10n)') |
| 335 translations = make_group('Native resources (l10n)') | 374 translations = make_group('Native resources (l10n)') |
| 375 stored_translations = make_group('Native resources stored (l10n)') | |
| 336 icu_data = make_group('ICU (i18n library) data') | 376 icu_data = make_group('ICU (i18n library) data') |
| 337 v8_snapshots = make_group('V8 Snapshots') | 377 v8_snapshots = make_group('V8 Snapshots') |
| 338 png_drawables = make_group('PNG drawables') | 378 png_drawables = make_group('PNG drawables') |
| 339 res_directory = make_group('Non-compiled Android resources') | 379 res_directory = make_group('Non-compiled Android resources') |
| 340 arsc = make_group('Compiled Android resources') | 380 arsc = make_group('Compiled Android resources') |
| 341 metadata = make_group('Package metadata') | 381 metadata = make_group('Package metadata') |
| 342 unknown = make_group('Unknown files') | 382 unknown = make_group('Unknown files') |
| 343 notices = make_group('licenses.notice file') | 383 notices = make_group('licenses.notice file') |
| 344 | 384 |
| 345 apk = zipfile.ZipFile(apk_filename, 'r') | 385 apk = zipfile.ZipFile(apk_filename, 'r') |
| 346 try: | 386 try: |
| 347 apk_contents = apk.infolist() | 387 apk_contents = apk.infolist() |
| 348 finally: | 388 finally: |
| 349 apk.close() | 389 apk.close() |
| 350 | 390 |
| 391 dex_multiplier, skip_extract_lib = _ParseManifestAttributes(apk_filename) | |
| 351 total_apk_size = os.path.getsize(apk_filename) | 392 total_apk_size = os.path.getsize(apk_filename) |
| 352 apk_basename = os.path.basename(apk_filename) | 393 apk_basename = os.path.basename(apk_filename) |
| 353 | |
| 354 for member in apk_contents: | 394 for member in apk_contents: |
| 355 filename = member.filename | 395 filename = member.filename |
| 356 if filename.endswith('/'): | 396 if filename.endswith('/'): |
| 357 continue | 397 continue |
| 358 | |
| 359 if filename.endswith('.so'): | 398 if filename.endswith('.so'): |
| 360 native_code.AddZipInfo(member, 'crazy' not in filename) | 399 should_extract_lib = not (skip_extract_lib or 'crazy' in filename) |
| 400 native_code.AddZipInfo(member, int(should_extract_lib)) | |
| 361 elif filename.endswith('.dex'): | 401 elif filename.endswith('.dex'): |
| 362 java_code.AddZipInfo(member, True) | 402 java_code.AddZipInfo(member, dex_multiplier) |
| 363 elif re.search(r'^assets/.*(resources|percent)\.pak$', filename): | 403 elif re.search(_RE_NON_LANGUAGE_PAK, filename): |
| 364 native_resources_no_translations.AddZipInfo(member) | 404 native_resources_no_translations.AddZipInfo(member) |
| 365 elif re.search(r'\.lpak$|^assets/.*(?!resources|percent)\.pak$', filename): | 405 elif re.search(_RE_COMPRESSED_LANGUAGE_PAK, filename): |
| 366 translations.AddZipInfo(member, 'en_' in filename or 'en-' in filename) | 406 translations.AddZipInfo(member) |
| 407 elif re.search(_RE_STORED_LANGUAGE_PAK, filename): | |
| 408 stored_translations.AddZipInfo( | |
| 409 member, 'en_' in filename or 'en-' in filename) | |
|
agrieve
2017/06/16 01:37:16
add int()
estevenson
2017/06/16 14:56:19
Oops, must have mixed these up. Added int() to the
| |
| 367 elif filename == 'assets/icudtl.dat': | 410 elif filename == 'assets/icudtl.dat': |
| 368 icu_data.AddZipInfo(member) | 411 icu_data.AddZipInfo(member) |
| 369 elif filename.endswith('.bin'): | 412 elif filename.endswith('.bin'): |
| 370 v8_snapshots.AddZipInfo(member) | 413 v8_snapshots.AddZipInfo(member) |
| 371 elif filename.endswith('.png') or filename.endswith('.webp'): | 414 elif filename.endswith('.png') or filename.endswith('.webp'): |
| 372 png_drawables.AddZipInfo(member) | 415 png_drawables.AddZipInfo(member) |
| 373 elif filename.startswith('res/'): | 416 elif filename.startswith('res/'): |
| 374 res_directory.AddZipInfo(member) | 417 res_directory.AddZipInfo(member) |
| 375 elif filename.endswith('.arsc'): | 418 elif filename.endswith('.arsc'): |
| 376 arsc.AddZipInfo(member) | 419 arsc.AddZipInfo(member) |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 431 | 474 |
| 432 # Main metric that we want to monitor for jumps. | 475 # Main metric that we want to monitor for jumps. |
| 433 normalized_apk_size = total_apk_size | 476 normalized_apk_size = total_apk_size |
| 434 # Always look at uncompressed .dex & .so. | 477 # Always look at uncompressed .dex & .so. |
| 435 normalized_apk_size -= java_code.ComputeZippedSize() | 478 normalized_apk_size -= java_code.ComputeZippedSize() |
| 436 normalized_apk_size += java_code.ComputeUncompressedSize() | 479 normalized_apk_size += java_code.ComputeUncompressedSize() |
| 437 normalized_apk_size -= native_code.ComputeZippedSize() | 480 normalized_apk_size -= native_code.ComputeZippedSize() |
| 438 normalized_apk_size += native_code.ComputeUncompressedSize() | 481 normalized_apk_size += native_code.ComputeUncompressedSize() |
| 439 # Avoid noise caused when strings change and translations haven't yet been | 482 # Avoid noise caused when strings change and translations haven't yet been |
| 440 # updated. | 483 # updated. |
| 441 english_pak = translations.FindByPattern(r'.*/en[-_][Uu][Ss]\.l?pak') | |
| 442 num_translations = translations.GetNumEntries() | 484 num_translations = translations.GetNumEntries() |
| 443 if english_pak and num_translations > 1: | 485 if num_translations > 1: |
| 444 normalized_apk_size -= translations.ComputeZippedSize() | 486 # Multipliers found by looking at MonochromePublic.apk and seeing how much |
| 445 # 1.17 found by looking at Chrome.apk and seeing how much smaller en-US.pak | 487 # smaller en-US.pak is relative to the average locale.pak. |
| 446 # is relative to the average locale .pak. | 488 normalized_apk_size = _NormalizeLanguagePaks( |
| 447 normalized_apk_size += int( | 489 translations, normalized_apk_size, 1.17) |
| 448 english_pak.compress_size * num_translations * 1.17) | 490 normalized_apk_size = _NormalizeLanguagePaks( |
| 491 stored_translations, normalized_apk_size, 1.43) | |
| 449 normalized_apk_size += int(_NormalizeResourcesArsc(apk_filename)) | 492 normalized_apk_size += int(_NormalizeResourcesArsc(apk_filename)) |
| 450 | 493 |
| 451 ReportPerfResult(chartjson, apk_basename + '_Specifics', | 494 ReportPerfResult(chartjson, apk_basename + '_Specifics', |
| 452 'normalized apk size', normalized_apk_size, 'bytes') | 495 'normalized apk size', normalized_apk_size, 'bytes') |
| 453 | 496 |
| 454 ReportPerfResult(chartjson, apk_basename + '_Specifics', | 497 ReportPerfResult(chartjson, apk_basename + '_Specifics', |
| 455 'file count', len(apk_contents), 'zip entries') | 498 'file count', len(apk_contents), 'zip entries') |
| 456 | 499 |
| 457 for info in unknown.AllEntries(): | 500 for info in unknown.AllEntries(): |
| 458 print 'Unknown entry:', info.filename, info.compress_size | 501 print 'Unknown entry:', info.filename, info.compress_size |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 755 default=apk_downloader.DEFAULT_BUILDER, | 798 default=apk_downloader.DEFAULT_BUILDER, |
| 756 help='Builder name to use for reference APK for patch ' | 799 help='Builder name to use for reference APK for patch ' |
| 757 'size estimates.') | 800 'size estimates.') |
| 758 argparser.add_argument('--reference-apk-bucket', | 801 argparser.add_argument('--reference-apk-bucket', |
| 759 default=apk_downloader.DEFAULT_BUCKET, | 802 default=apk_downloader.DEFAULT_BUCKET, |
| 760 help='Storage bucket holding reference APKs.') | 803 help='Storage bucket holding reference APKs.') |
| 761 argparser.add_argument('apk', help='APK file path.') | 804 argparser.add_argument('apk', help='APK file path.') |
| 762 args = argparser.parse_args() | 805 args = argparser.parse_args() |
| 763 | 806 |
| 764 chartjson = _BASE_CHART.copy() if args.chartjson else None | 807 chartjson = _BASE_CHART.copy() if args.chartjson else None |
| 765 | |
| 766 if args.chromium_output_directory: | 808 if args.chromium_output_directory: |
| 767 constants.SetOutputDirectory(args.chromium_output_directory) | 809 constants.SetOutputDirectory(args.chromium_output_directory) |
| 768 if not args.no_output_dir: | 810 if not args.no_output_dir: |
| 769 constants.CheckOutputDirectory() | 811 constants.CheckOutputDirectory() |
| 770 devil_chromium.Initialize() | 812 devil_chromium.Initialize() |
| 771 build_vars = _ReadBuildVars(constants.GetOutDirectory()) | 813 build_vars = _ReadBuildVars(constants.GetOutDirectory()) |
| 772 tools_prefix = os.path.join(constants.GetOutDirectory(), | 814 tools_prefix = os.path.join(constants.GetOutDirectory(), |
| 773 build_vars['android_tool_prefix']) | 815 build_vars['android_tool_prefix']) |
| 774 else: | 816 else: |
| 775 tools_prefix = '' | 817 tools_prefix = '' |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 786 chartjson=chartjson) | 828 chartjson=chartjson) |
| 787 if chartjson: | 829 if chartjson: |
| 788 results_path = os.path.join(args.output_dir, 'results-chart.json') | 830 results_path = os.path.join(args.output_dir, 'results-chart.json') |
| 789 logging.critical('Dumping json to %s', results_path) | 831 logging.critical('Dumping json to %s', results_path) |
| 790 with open(results_path, 'w') as json_file: | 832 with open(results_path, 'w') as json_file: |
| 791 json.dump(chartjson, json_file) | 833 json.dump(chartjson, json_file) |
| 792 | 834 |
| 793 | 835 |
| 794 if __name__ == '__main__': | 836 if __name__ == '__main__': |
| 795 sys.exit(main()) | 837 sys.exit(main()) |
| OLD | NEW |