xref: /aosp_15_r20/external/nullaway/jar-infer/scripts/android-jar.py (revision f50c306653bc89b8210ce6c9e0b0b44fc134bc03)
1*f50c3066SAndroid Build Coastguard Workerimport sys, os, subprocess, ConfigParser
2*f50c3066SAndroid Build Coastguard Workerfrom optparse import OptionParser
3*f50c3066SAndroid Build Coastguard Worker
4*f50c3066SAndroid Build Coastguard Workerclass2jar = dict()
5*f50c3066SAndroid Build Coastguard Workerjars_to_process = set()
6*f50c3066SAndroid Build Coastguard Worker
7*f50c3066SAndroid Build Coastguard Workeropt_parser = OptionParser()
8*f50c3066SAndroid Build Coastguard Workeropt_parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=False, help="set verbosity")
9*f50c3066SAndroid Build Coastguard Workeropt_parser.add_option("-c", "--config", dest="config", default=os.path.dirname(sys.argv[0])+"/android-jar.conf", help="configuration file path")
10*f50c3066SAndroid Build Coastguard Worker(options, args) = opt_parser.parse_args()
11*f50c3066SAndroid Build Coastguard Workerif not os.path.isfile(options.config):
12*f50c3066SAndroid Build Coastguard Worker  sys.exit('Error! No configuration file at: '+options.config)
13*f50c3066SAndroid Build Coastguard Workerconfig_parser = ConfigParser.SafeConfigParser()
14*f50c3066SAndroid Build Coastguard Workerconfig_parser.read(options.config)
15*f50c3066SAndroid Build Coastguard Workerajars_dir = config_parser.get('android-paths', 'aosp-out-dir')
16*f50c3066SAndroid Build Coastguard Workerstubs_jar = config_parser.get('android-paths', 'android-stubs-jar')
17*f50c3066SAndroid Build Coastguard Workerjarinfer = config_parser.get('jar-infer-paths', 'jar-infer-path')
18*f50c3066SAndroid Build Coastguard Workerwrk_dir = config_parser.get('android-model', 'wrk-dir')
19*f50c3066SAndroid Build Coastguard Workerastubx_file = config_parser.get('android-model', 'astubx-path')
20*f50c3066SAndroid Build Coastguard Worker
21*f50c3066SAndroid Build Coastguard Worker### Finding android libraries ###
22*f50c3066SAndroid Build Coastguard Workerprint "> Finding android libraries..."
23*f50c3066SAndroid Build Coastguard Worker# Since SDK 31, the directory structure mixes classes.jar and classes-header.jar files, we use
24*f50c3066SAndroid Build Coastguard Worker# only the former, as classes-header.jar files are missing methods' bytecode.
25*f50c3066SAndroid Build Coastguard Workercmd = "find " + ajars_dir + " -name \"*.jar\" | grep -v classes-header.jar"
26*f50c3066SAndroid Build Coastguard Workerajars = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True).stdout.read().splitlines()
27*f50c3066SAndroid Build Coastguard Workerfor ajar in ajars:
28*f50c3066SAndroid Build Coastguard Worker  cmd = "jar tvf " + ajar + " | grep \"\.class$\" | awk '{print $8}'"
29*f50c3066SAndroid Build Coastguard Worker  ajar_classes = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True).stdout.read().splitlines()
30*f50c3066SAndroid Build Coastguard Worker  for ajar_class in ajar_classes:
31*f50c3066SAndroid Build Coastguard Worker    if ajar_class in class2jar:
32*f50c3066SAndroid Build Coastguard Worker      if options.verbose:
33*f50c3066SAndroid Build Coastguard Worker        print "[Warn] Same class in multiple jars : " + ajar_class + " in " + class2jar[ajar_class] + " , " + ajar
34*f50c3066SAndroid Build Coastguard Worker    else:
35*f50c3066SAndroid Build Coastguard Worker      class2jar[ajar_class] = ajar
36*f50c3066SAndroid Build Coastguard Workercmd = "jar tvf " + stubs_jar + " | grep \"\.class$\" | awk '{print $8}'"
37*f50c3066SAndroid Build Coastguard Workerajar_classes = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True).stdout.read().splitlines()
38*f50c3066SAndroid Build Coastguard Workerfound = 0
39*f50c3066SAndroid Build Coastguard Workerfor ajar_class in ajar_classes:
40*f50c3066SAndroid Build Coastguard Worker  if ajar_class in class2jar:
41*f50c3066SAndroid Build Coastguard Worker    found += 1
42*f50c3066SAndroid Build Coastguard Worker    jars_to_process.add(class2jar[ajar_class])
43*f50c3066SAndroid Build Coastguard Worker  else:
44*f50c3066SAndroid Build Coastguard Worker    if options.verbose:
45*f50c3066SAndroid Build Coastguard Worker      print "[Warn] Class not found in any jar : " + ajar_class
46*f50c3066SAndroid Build Coastguard Workerprint ",".join(list(jars_to_process))
47*f50c3066SAndroid Build Coastguard Workerprint "Found " + str(found) + " / " + str(len(ajar_classes)) + " in " + str(len(jars_to_process)) + " jars"
48*f50c3066SAndroid Build Coastguard Worker
49*f50c3066SAndroid Build Coastguard Worker### Running jarinfer ###
50*f50c3066SAndroid Build Coastguard Workerprint "> Running jarinfer on android jars..."
51*f50c3066SAndroid Build Coastguard Workercmd = "java -jar " + jarinfer + " -i " + ",".join(list(jars_to_process)) + " -o " + wrk_dir + "/" + astubx_file
52*f50c3066SAndroid Build Coastguard Workerif options.verbose:
53*f50c3066SAndroid Build Coastguard Worker  cmd += " -dv"
54*f50c3066SAndroid Build Coastguard Workerprint cmd
55*f50c3066SAndroid Build Coastguard Workerreturncode = subprocess.call(cmd, shell=True)
56*f50c3066SAndroid Build Coastguard Workersys.exit(returncode)
57