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