#!/usr/bin/env python3 # # Copyright 2016 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.
"""Processes an Android AAR file."""
import argparse import os import posixpath import re import shutil import sys from xml.etree import ElementTree import zipfile
def _GetManifestPackage(doc): """Returns the package specified in the manifest.
Args:
doc: an XML tree parsed by ElementTree
Returns:
String representing the package name. """ return doc.attrib['package']
def _IsManifestEmpty(doc): """Decides whether the given manifest has merge-worthy elements.
E.g.: <activity>, <service>, etc.
Args:
doc: an XML tree parsed by ElementTree
Returns:
Whether the manifest has merge-worthy elements. """ for node in doc: if node.tag == 'application': if list(node): returnFalse elif node.tag != 'uses-sdk': returnFalse
returnTrue
def _CreateInfo(aar_file): """Extracts and return .info data from an .aar file.
for name in z.namelist(): if name.endswith('/'): continue if name.startswith('aidl/'):
data['aidl'].append(name) elif name.startswith('res/'):
data['resources'].append(name) elif name.startswith('libs/') and name.endswith('.jar'):
label = posixpath.basename(name)[:-4]
label = re.sub(r'[^a-zA-Z0-9._]', '_', label)
data['subjars'].append(name)
data['subjar_tuples'].append([label, name]) elif name.startswith('assets/'):
data['assets'].append(name) elif name.startswith('jni/'):
data['has_native_libraries'] = True if'native_libraries'in data:
data['native_libraries'].append(name) else:
data['native_libraries'] = [name] elif name == 'classes.jar':
data['has_classes_jar'] = True elif name == _PROGUARD_TXT:
data['has_proguard_flags'] = True elif name == 'R.txt': # Some AARs, e.g. gvr_controller_java, have empty R.txt. Such AARs # have no resources as well. We treat empty R.txt as having no R.txt.
data['has_r_text_file'] = bool(z.read('R.txt').strip())
return data
def _PerformExtract(aar_file, output_dir, name_allowlist): with build_utils.TempDir() as tmp_dir:
tmp_dir = os.path.join(tmp_dir, 'staging')
os.mkdir(tmp_dir)
build_utils.ExtractAll(
aar_file, path=tmp_dir, predicate=name_allowlist.__contains__) # Write a breadcrumb so that SuperSize can attribute files back to the .aar. with open(os.path.join(tmp_dir, 'source.info'), 'w') as f:
f.write('source={}\n'.format(aar_file))
def _AddCommonArgs(parser):
parser.add_argument( 'aar_file', help='Path to the AAR file.', type=os.path.normpath)
def main():
parser = argparse.ArgumentParser(description=__doc__)
command_parsers = parser.add_subparsers(dest='command')
subp = command_parsers.add_parser( 'list', help='Output a GN scope describing the contents of the .aar.')
_AddCommonArgs(subp)
subp.add_argument('--output', help='Output file.', default='-')
subp = command_parsers.add_parser('extract', help='Extracts the .aar')
_AddCommonArgs(subp)
subp.add_argument( '--output-dir',
help='Output directory for the extracted files.',
required=True,
type=os.path.normpath)
subp.add_argument( '--assert-info-file',
help='Path to .info file. Asserts that it matches what ' '"list" would output.',
type=argparse.FileType('r'))
subp.add_argument( '--ignore-resources',
action='store_true',
help='Whether to skip extraction of res/')
args = parser.parse_args()
aar_info = _CreateInfo(args.aar_file)
formatted_info = """\ # Generated by //build/android/gyp/aar.py # To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen".
if args.command == 'extract': if args.assert_info_file:
cached_info = args.assert_info_file.read() if formatted_info != cached_info: raise Exception('android_aar_prebuilt() cached .info file is ' 'out-of-date. Run gn gen with ' 'update_android_aar_prebuilts=true to update it.')
with zipfile.ZipFile(args.aar_file) as zf:
names = zf.namelist() if args.ignore_resources:
names = [n for n in names ifnot n.startswith('res')]
elif args.command == 'list':
aar_output_present = args.output != '-'and os.path.isfile(args.output) if aar_output_present: # Some .info files are read-only, for examples the cipd-controlled ones # under third_party/android_deps/repositoty. To deal with these, first # that its content is correct, and if it is, exit without touching # the file system.
file_info = open(args.output, 'r').read() if file_info == formatted_info: return
# Try to write the file. This may fail for read-only ones that were # not updated. try: with open(args.output, 'w') as f:
f.write(formatted_info) except IOError as e: ifnot aar_output_present: raise e raise Exception('Could not update output file: %s\n%s\n' %
(args.output, e))
if __name__ == '__main__':
sys.exit(main())
Messung V0.5
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.