Files
build_soong/scripts/check_boot_jars/check_boot_jars.py
Paul Duffin 9a89a2a0ea Move boot jars package check from make
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
2020-10-29 17:20:06 +00:00

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:]))