xref: /aosp_15_r20/system/apex/tools/apexer_with_trim_preprocessing.py (revision 33f3758387333dbd2962d7edbd98681940d895da)
1*33f37583SAndroid Build Coastguard Worker#!/usr/bin/env python3
2*33f37583SAndroid Build Coastguard Worker
3*33f37583SAndroid Build Coastguard Worker"""This is a wrapper function of apexer. It provides opportunity to do
4*33f37583SAndroid Build Coastguard Workersome artifact preprocessing before calling into apexer. Some of these
5*33f37583SAndroid Build Coastguard Workerartifact preprocessing are difficult or impossible to do in soong or
6*33f37583SAndroid Build Coastguard Workerbazel such as trimming the apex native shared libs. It is better to do
7*33f37583SAndroid Build Coastguard Workerthese in a binary so that the preprocessing logic can be reused regardless
8*33f37583SAndroid Build Coastguard Workerof the build system
9*33f37583SAndroid Build Coastguard Worker"""
10*33f37583SAndroid Build Coastguard Worker
11*33f37583SAndroid Build Coastguard Workerimport argparse
12*33f37583SAndroid Build Coastguard Workerfrom glob import glob
13*33f37583SAndroid Build Coastguard Workerimport os
14*33f37583SAndroid Build Coastguard Workerimport re
15*33f37583SAndroid Build Coastguard Workerimport shutil
16*33f37583SAndroid Build Coastguard Workerimport sys
17*33f37583SAndroid Build Coastguard Workerimport tempfile
18*33f37583SAndroid Build Coastguard Worker
19*33f37583SAndroid Build Coastguard Workerimport apex_manifest_pb2
20*33f37583SAndroid Build Coastguard Workerimport apexer_wrapper_utils
21*33f37583SAndroid Build Coastguard Worker
22*33f37583SAndroid Build Coastguard Workerdef ParseArgs(argv):
23*33f37583SAndroid Build Coastguard Worker  parser = argparse.ArgumentParser(
24*33f37583SAndroid Build Coastguard Worker      description='wrapper to run apexer with native shared lib trimming')
25*33f37583SAndroid Build Coastguard Worker  parser.add_argument(
26*33f37583SAndroid Build Coastguard Worker      '--apexer',
27*33f37583SAndroid Build Coastguard Worker      help='path to apexer binary')
28*33f37583SAndroid Build Coastguard Worker  parser.add_argument(
29*33f37583SAndroid Build Coastguard Worker      '--canned_fs_config',
30*33f37583SAndroid Build Coastguard Worker      help='path to canned_fs_config file')
31*33f37583SAndroid Build Coastguard Worker  parser.add_argument(
32*33f37583SAndroid Build Coastguard Worker      '--manifest',
33*33f37583SAndroid Build Coastguard Worker      help='path to apex_manifest.pb file')
34*33f37583SAndroid Build Coastguard Worker  parser.add_argument(
35*33f37583SAndroid Build Coastguard Worker      '--libs_to_trim',
36*33f37583SAndroid Build Coastguard Worker      help='native shared libraries to trim')
37*33f37583SAndroid Build Coastguard Worker  parser.add_argument(
38*33f37583SAndroid Build Coastguard Worker      'input_dir',
39*33f37583SAndroid Build Coastguard Worker      metavar='INPUT_DIR',
40*33f37583SAndroid Build Coastguard Worker      help='the directory having files to be packaged')
41*33f37583SAndroid Build Coastguard Worker  parser.add_argument(
42*33f37583SAndroid Build Coastguard Worker      'output',
43*33f37583SAndroid Build Coastguard Worker      metavar='OUTPUT',
44*33f37583SAndroid Build Coastguard Worker      help='name of the APEX file')
45*33f37583SAndroid Build Coastguard Worker  parser.add_argument(
46*33f37583SAndroid Build Coastguard Worker      'rest_args',
47*33f37583SAndroid Build Coastguard Worker      nargs='*',
48*33f37583SAndroid Build Coastguard Worker      help='remaining flags that will be passed as-is to apexer')
49*33f37583SAndroid Build Coastguard Worker  return parser.parse_args(argv)
50*33f37583SAndroid Build Coastguard Worker
51*33f37583SAndroid Build Coastguard Workerdef TrimNativeSharedLibs(image_dir: str, canned_fs_config: str,
52*33f37583SAndroid Build Coastguard Worker                         manifest: str, libs_to_trim: list[str]):
53*33f37583SAndroid Build Coastguard Worker  """Place native shared libs for trimmed variant in a special way.
54*33f37583SAndroid Build Coastguard Worker
55*33f37583SAndroid Build Coastguard Worker  Traditional apex has native shared libs placed under /lib(64)? inside
56*33f37583SAndroid Build Coastguard Worker  the apex. However, for trimmed variant, for the libs to trim, they will
57*33f37583SAndroid Build Coastguard Worker  be replaced with a sym link to
58*33f37583SAndroid Build Coastguard Worker
59*33f37583SAndroid Build Coastguard Worker  /apex/sharedlibs/lib(64)?/foo.so/[sha512 foo.so]/foo.so
60*33f37583SAndroid Build Coastguard Worker  """
61*33f37583SAndroid Build Coastguard Worker
62*33f37583SAndroid Build Coastguard Worker  libs_trimmed = set()
63*33f37583SAndroid Build Coastguard Worker  with open(canned_fs_config, 'r') as f:
64*33f37583SAndroid Build Coastguard Worker    lines = f.readlines()
65*33f37583SAndroid Build Coastguard Worker  for line in lines:
66*33f37583SAndroid Build Coastguard Worker    segs = line.split(' ')
67*33f37583SAndroid Build Coastguard Worker    if segs[0].endswith('.so'):
68*33f37583SAndroid Build Coastguard Worker      if any(segs[0].endswith(v) for v in libs_to_trim):
69*33f37583SAndroid Build Coastguard Worker        lib_relative_path = segs[0][1:]
70*33f37583SAndroid Build Coastguard Worker        lib_absolute_path = os.path.join(image_dir, lib_relative_path)
71*33f37583SAndroid Build Coastguard Worker        lib_name = os.path.basename(lib_relative_path)
72*33f37583SAndroid Build Coastguard Worker        libs_trimmed.add(lib_name)
73*33f37583SAndroid Build Coastguard Worker        digest = apexer_wrapper_utils.GetDigest(lib_absolute_path)
74*33f37583SAndroid Build Coastguard Worker        os.remove(lib_absolute_path)
75*33f37583SAndroid Build Coastguard Worker        link = os.path.join('/apex/sharedlibs', lib_relative_path, digest, lib_name)
76*33f37583SAndroid Build Coastguard Worker        os.symlink(link, lib_absolute_path)
77*33f37583SAndroid Build Coastguard Worker
78*33f37583SAndroid Build Coastguard Worker  manifest_pb = apex_manifest_pb2.ApexManifest()
79*33f37583SAndroid Build Coastguard Worker  with open(manifest, 'rb') as f:
80*33f37583SAndroid Build Coastguard Worker    manifest_pb.ParseFromString(f.read())
81*33f37583SAndroid Build Coastguard Worker
82*33f37583SAndroid Build Coastguard Worker  # bump version code
83*33f37583SAndroid Build Coastguard Worker  # google mainline module logic, for trimmed variant, the variant digit is 2
84*33f37583SAndroid Build Coastguard Worker  manifest_pb.version = 10*(manifest_pb.version // 10) + 2
85*33f37583SAndroid Build Coastguard Worker
86*33f37583SAndroid Build Coastguard Worker  # setting requireSharedApexLibs
87*33f37583SAndroid Build Coastguard Worker  del manifest_pb.requireSharedApexLibs[:]
88*33f37583SAndroid Build Coastguard Worker  manifest_pb.requireSharedApexLibs.extend(
89*33f37583SAndroid Build Coastguard Worker    sorted(re.sub(r':.{128}$', ':sha-512', lib)
90*33f37583SAndroid Build Coastguard Worker           for lib in libs_trimmed))
91*33f37583SAndroid Build Coastguard Worker
92*33f37583SAndroid Build Coastguard Worker  # write back to root apex_manifest.pb
93*33f37583SAndroid Build Coastguard Worker  with open(manifest, 'wb') as f:
94*33f37583SAndroid Build Coastguard Worker    f.write(manifest_pb.SerializeToString())
95*33f37583SAndroid Build Coastguard Worker
96*33f37583SAndroid Build Coastguard Workerdef main(argv):
97*33f37583SAndroid Build Coastguard Worker  args = ParseArgs(argv)
98*33f37583SAndroid Build Coastguard Worker  segs = args.libs_to_trim.split(',')
99*33f37583SAndroid Build Coastguard Worker  libs_to_trim = [v+'.so' for v in args.libs_to_trim.split(',')]
100*33f37583SAndroid Build Coastguard Worker  TrimNativeSharedLibs(args.input_dir, args.canned_fs_config, args.manifest,
101*33f37583SAndroid Build Coastguard Worker                       libs_to_trim)
102*33f37583SAndroid Build Coastguard Worker  cmd = [args.apexer, '--canned_fs_config', args.canned_fs_config]
103*33f37583SAndroid Build Coastguard Worker  cmd.extend(['--manifest', args.manifest])
104*33f37583SAndroid Build Coastguard Worker  cmd.extend(args.rest_args)
105*33f37583SAndroid Build Coastguard Worker  cmd.extend([args.input_dir, args.output])
106*33f37583SAndroid Build Coastguard Worker
107*33f37583SAndroid Build Coastguard Worker  apexer_wrapper_utils.RunCommand(cmd)
108*33f37583SAndroid Build Coastguard Worker
109*33f37583SAndroid Build Coastguard Workerif __name__ == "__main__":
110*33f37583SAndroid Build Coastguard Worker main(sys.argv[1:])
111