1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
build / android / gyp / validate_static_library_dex_references.py [blame]
#!/usr/bin/env python3
# Copyright 2019 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import argparse
import os
import re
import sys
import zipfile
sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir))
from pylib.dex import dex_parser
from util import build_utils
import action_helpers # build_utils adds //build to sys.path.
_FLAGS_PATH = (
'//chrome/android/java/static_library_dex_reference_workarounds.flags')
def _FindIllegalStaticLibraryReferences(static_lib_dex_files,
main_apk_dex_files):
main_apk_defined_types = set()
for dex_file in main_apk_dex_files:
for class_def_item in dex_file.class_def_item_list:
main_apk_defined_types.add(
dex_file.GetTypeString(class_def_item.class_idx))
static_lib_referenced_types = set()
for dex_file in static_lib_dex_files:
for type_item in dex_file.type_item_list:
static_lib_referenced_types.add(
dex_file.GetString(type_item.descriptor_idx))
return main_apk_defined_types.intersection(static_lib_referenced_types)
def _DexFilesFromPath(path):
if zipfile.is_zipfile(path):
with zipfile.ZipFile(path) as z:
return [
dex_parser.DexFile(bytearray(z.read(name))) for name in z.namelist()
if re.match(r'.*classes[0-9]*\.dex$', name)
]
else:
with open(path) as f:
return dex_parser.DexFile(bytearray(f.read()))
def main(args):
args = build_utils.ExpandFileArgs(args)
parser = argparse.ArgumentParser()
action_helpers.add_depfile_arg(parser)
parser.add_argument(
'--stamp', required=True, help='Path to file to touch upon success.')
parser.add_argument(
'--static-library-dex',
required=True,
help='classes.dex or classes.zip for the static library APK that was '
'proguarded with other dependent APKs')
parser.add_argument(
'--static-library-dependent-dex',
required=True,
action='append',
dest='static_library_dependent_dexes',
help='classes.dex or classes.zip for the APKs that use the static '
'library APK')
args = parser.parse_args(args)
static_library_dexfiles = _DexFilesFromPath(args.static_library_dex)
for path in args.static_library_dependent_dexes:
dependent_dexfiles = _DexFilesFromPath(path)
illegal_references = _FindIllegalStaticLibraryReferences(
static_library_dexfiles, dependent_dexfiles)
if illegal_references:
msg = 'Found illegal references from {} to {}\n'.format(
args.static_library_dex, path)
msg += 'Add a -keep rule to avoid this. '
msg += 'See {} for an example and why this is necessary.\n'.format(
_FLAGS_PATH)
msg += 'The illegal references are:\n'
msg += '\n'.join(illegal_references)
sys.stderr.write(msg)
sys.exit(1)
input_paths = [args.static_library_dex] + args.static_library_dependent_dexes
build_utils.Touch(args.stamp)
action_helpers.write_depfile(args.depfile, args.stamp, inputs=input_paths)
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))