xref: /aosp_15_r20/system/apex/tools/apexer_with_DCLA_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 placing native shared libs in DCLA. It is better to do
7*33f37583SAndroid Build Coastguard Workerthese in a binary so that the DCLA preprocessing logic can be reused
8*33f37583SAndroid Build Coastguard Workerregardless of 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 shutil
15*33f37583SAndroid Build Coastguard Workerimport sys
16*33f37583SAndroid Build Coastguard Workerimport tempfile
17*33f37583SAndroid Build Coastguard Worker
18*33f37583SAndroid Build Coastguard Workerimport apexer_wrapper_utils
19*33f37583SAndroid Build Coastguard Worker
20*33f37583SAndroid Build Coastguard Workerdef ParseArgs(argv):
21*33f37583SAndroid Build Coastguard Worker  parser = argparse.ArgumentParser(
22*33f37583SAndroid Build Coastguard Worker      description='wrapper to run apexer for DCLA')
23*33f37583SAndroid Build Coastguard Worker  parser.add_argument(
24*33f37583SAndroid Build Coastguard Worker      '--apexer',
25*33f37583SAndroid Build Coastguard Worker      help='path to apexer binary')
26*33f37583SAndroid Build Coastguard Worker  parser.add_argument(
27*33f37583SAndroid Build Coastguard Worker      '--canned_fs_config',
28*33f37583SAndroid Build Coastguard Worker      help='path to canned_fs_config file')
29*33f37583SAndroid Build Coastguard Worker  parser.add_argument(
30*33f37583SAndroid Build Coastguard Worker      'input_dir',
31*33f37583SAndroid Build Coastguard Worker      metavar='INPUT_DIR',
32*33f37583SAndroid Build Coastguard Worker      help='the directory having files to be packaged')
33*33f37583SAndroid Build Coastguard Worker  parser.add_argument(
34*33f37583SAndroid Build Coastguard Worker      'output',
35*33f37583SAndroid Build Coastguard Worker      metavar='OUTPUT',
36*33f37583SAndroid Build Coastguard Worker      help='name of the APEX file')
37*33f37583SAndroid Build Coastguard Worker  parser.add_argument(
38*33f37583SAndroid Build Coastguard Worker      'rest_args',
39*33f37583SAndroid Build Coastguard Worker      nargs='*',
40*33f37583SAndroid Build Coastguard Worker      help='remaining flags that will be passed as-is to apexer')
41*33f37583SAndroid Build Coastguard Worker  return parser.parse_args(argv)
42*33f37583SAndroid Build Coastguard Worker
43*33f37583SAndroid Build Coastguard Workerdef PlaceDCLANativeSharedLibs(image_dir: str, canned_fs_config: str) -> str:
44*33f37583SAndroid Build Coastguard Worker  """Place native shared libs for DCLA in a special way.
45*33f37583SAndroid Build Coastguard Worker
46*33f37583SAndroid Build Coastguard Worker  Traditional apex has native shared libs placed under /lib(64)? inside
47*33f37583SAndroid Build Coastguard Worker  the apex. However, for DCLA, it needs to be placed in a special way:
48*33f37583SAndroid Build Coastguard Worker
49*33f37583SAndroid Build Coastguard Worker  /lib(64)?/foo.so/<sha512 foo.so>/foo.so
50*33f37583SAndroid Build Coastguard Worker
51*33f37583SAndroid Build Coastguard Worker  This function moves the shared libs to desired location and update
52*33f37583SAndroid Build Coastguard Worker  canned_fs_config file accordingly
53*33f37583SAndroid Build Coastguard Worker  """
54*33f37583SAndroid Build Coastguard Worker
55*33f37583SAndroid Build Coastguard Worker  # remove all .so entries from canned_fs_config
56*33f37583SAndroid Build Coastguard Worker  parent_dir = os.path.dirname(canned_fs_config)
57*33f37583SAndroid Build Coastguard Worker  updated_canned_fs_config = os.path.join(parent_dir, 'updated_canned_fs_config')
58*33f37583SAndroid Build Coastguard Worker  with open(canned_fs_config, 'r') as f:
59*33f37583SAndroid Build Coastguard Worker    lines = f.readlines()
60*33f37583SAndroid Build Coastguard Worker  with open(updated_canned_fs_config, 'w') as f:
61*33f37583SAndroid Build Coastguard Worker    for line in lines:
62*33f37583SAndroid Build Coastguard Worker      segs = line.split(' ')
63*33f37583SAndroid Build Coastguard Worker      if not segs[0].endswith('.so'):
64*33f37583SAndroid Build Coastguard Worker        f.write(line)
65*33f37583SAndroid Build Coastguard Worker      else:
66*33f37583SAndroid Build Coastguard Worker        with tempfile.TemporaryDirectory() as tmp_dir:
67*33f37583SAndroid Build Coastguard Worker          # move native libs
68*33f37583SAndroid Build Coastguard Worker          lib_file = os.path.join(image_dir, segs[0][1:])
69*33f37583SAndroid Build Coastguard Worker          digest = apexer_wrapper_utils.GetDigest(lib_file)
70*33f37583SAndroid Build Coastguard Worker          lib_name = os.path.basename(lib_file)
71*33f37583SAndroid Build Coastguard Worker          dest_dir = os.path.join(lib_file, digest)
72*33f37583SAndroid Build Coastguard Worker
73*33f37583SAndroid Build Coastguard Worker          shutil.move(lib_file, os.path.join(tmp_dir, lib_name))
74*33f37583SAndroid Build Coastguard Worker          os.makedirs(dest_dir, exist_ok=True)
75*33f37583SAndroid Build Coastguard Worker          shutil.move(os.path.join(tmp_dir, lib_name),
76*33f37583SAndroid Build Coastguard Worker                      os.path.join(dest_dir, lib_name))
77*33f37583SAndroid Build Coastguard Worker
78*33f37583SAndroid Build Coastguard Worker          # add canned_fs_config entries
79*33f37583SAndroid Build Coastguard Worker          f.write(f'{segs[0]} 0 2000 0755\n')
80*33f37583SAndroid Build Coastguard Worker          f.write(f'{os.path.join(segs[0], digest)} 0 2000 0755\n')
81*33f37583SAndroid Build Coastguard Worker          f.write(f'{os.path.join(segs[0], digest, lib_name)} 1000 1000 0644\n')
82*33f37583SAndroid Build Coastguard Worker
83*33f37583SAndroid Build Coastguard Worker  # return the modified canned_fs_config
84*33f37583SAndroid Build Coastguard Worker  return updated_canned_fs_config
85*33f37583SAndroid Build Coastguard Worker
86*33f37583SAndroid Build Coastguard Workerdef main(argv):
87*33f37583SAndroid Build Coastguard Worker  args = ParseArgs(argv)
88*33f37583SAndroid Build Coastguard Worker  args.canned_fs_config = PlaceDCLANativeSharedLibs(
89*33f37583SAndroid Build Coastguard Worker      args.input_dir, args.canned_fs_config)
90*33f37583SAndroid Build Coastguard Worker
91*33f37583SAndroid Build Coastguard Worker  cmd = [args.apexer, '--canned_fs_config', args.canned_fs_config]
92*33f37583SAndroid Build Coastguard Worker  cmd.extend(args.rest_args)
93*33f37583SAndroid Build Coastguard Worker  cmd.extend([args.input_dir, args.output])
94*33f37583SAndroid Build Coastguard Worker
95*33f37583SAndroid Build Coastguard Worker  apexer_wrapper_utils.RunCommand(cmd)
96*33f37583SAndroid Build Coastguard Worker
97*33f37583SAndroid Build Coastguard Workerif __name__ == "__main__":
98*33f37583SAndroid Build Coastguard Worker main(sys.argv[1:])
99