Adds a singleton that traverses the module variants finding the ones that are in the list (updatable and non-updatable) of boot jars and add a ninja rule to ensure that they only contain packages from an allowed list. Replaces a hack that ignored any prebuilt boot jars supplied as dex file with an equivalent one to ensure that they are still ignored. A follow up change that switches to checking dex jars will allow the hack to be removed. The boot jars check can be strict or lax. If strict then all the boot jars listed in the configuration must be found, otherwise it will only check the ones it finds. It is strict by default unless TARGET_BUILD_UNBUNDLED=true or ALLOW_MISSING_DEPENDENCIES=true. Moves the script and data file from build/make. Test: m check-boot-jars - for failing and passing cases SKIP_BOOT_JARS_CHECK=true - no check-boot-jars target created ALLOW_MISSING_DEPENDENCIES=true - not strict TARGET_BUILD_UNBUNDLED=true - not strict verified manually that apart from path differences the same files (same check sum) were checked in both old make checks and the new Soong ones EMMA_INSTRUMENT=true EMMA_INSTRUMENT_FRAMEWORK=true m check-boot-jars Bug: 171479578 Change-Id: I9d81d6650ba64fc0d48d2dab4ba5a3ba8dd03dec
90 lines
2.1 KiB
Python
Executable File
90 lines
2.1 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
"""
|
|
Check boot jars.
|
|
|
|
Usage: check_boot_jars.py <package_allow_list_file> <jar1> <jar2> ...
|
|
"""
|
|
import logging
|
|
import os.path
|
|
import re
|
|
import subprocess
|
|
import sys
|
|
|
|
|
|
# The compiled allow list RE.
|
|
allow_list_re = None
|
|
|
|
|
|
def LoadAllowList(filename):
|
|
""" Load and compile allow list regular expressions from filename.
|
|
"""
|
|
lines = []
|
|
with open(filename, 'r') as f:
|
|
for line in f:
|
|
line = line.strip()
|
|
if not line or line.startswith('#'):
|
|
continue
|
|
lines.append(line)
|
|
combined_re = r'^(%s)$' % '|'.join(lines)
|
|
global allow_list_re
|
|
try:
|
|
allow_list_re = re.compile(combined_re)
|
|
except re.error:
|
|
logging.exception(
|
|
'Cannot compile package allow list regular expression: %r',
|
|
combined_re)
|
|
allow_list_re = None
|
|
return False
|
|
return True
|
|
|
|
|
|
def CheckJar(allow_list_path, jar):
|
|
"""Check a jar file.
|
|
"""
|
|
# Get the list of files inside the jar file.
|
|
p = subprocess.Popen(args='jar tf %s' % jar,
|
|
stdout=subprocess.PIPE, shell=True)
|
|
stdout, _ = p.communicate()
|
|
if p.returncode != 0:
|
|
return False
|
|
items = stdout.split()
|
|
classes = 0
|
|
for f in items:
|
|
if f.endswith('.class'):
|
|
classes += 1
|
|
package_name = os.path.dirname(f)
|
|
package_name = package_name.replace('/', '.')
|
|
if not package_name or not allow_list_re.match(package_name):
|
|
print >> sys.stderr, ('Error: %s contains class file %s, whose package name %s is empty or'
|
|
' not in the allow list %s of packages allowed on the bootclasspath.'
|
|
% (jar, f, package_name, allow_list_path))
|
|
return False
|
|
if classes == 0:
|
|
print >> sys.stderr, ('Error: %s does not contain any class files.' % jar)
|
|
return False
|
|
return True
|
|
|
|
|
|
def main(argv):
|
|
if len(argv) < 2:
|
|
print __doc__
|
|
return 1
|
|
allow_list_path = argv[0]
|
|
|
|
if not LoadAllowList(allow_list_path):
|
|
return 1
|
|
|
|
passed = True
|
|
for jar in argv[1:]:
|
|
if not CheckJar(allow_list_path, jar):
|
|
passed = False
|
|
if not passed:
|
|
return 1
|
|
|
|
return 0
|
|
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(main(sys.argv[1:]))
|