1*6dbdd20aSAndroid Build Coastguard Worker#!/usr/bin/env python3 2*6dbdd20aSAndroid Build Coastguard Worker# Copyright (C) 2021 The Android Open Source Project 3*6dbdd20aSAndroid Build Coastguard Worker# 4*6dbdd20aSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 5*6dbdd20aSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 6*6dbdd20aSAndroid Build Coastguard Worker# You may obtain a copy of the License at 7*6dbdd20aSAndroid Build Coastguard Worker# 8*6dbdd20aSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 9*6dbdd20aSAndroid Build Coastguard Worker# 10*6dbdd20aSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 11*6dbdd20aSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 12*6dbdd20aSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*6dbdd20aSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 14*6dbdd20aSAndroid Build Coastguard Worker# limitations under the License. 15*6dbdd20aSAndroid Build Coastguard Worker""" 16*6dbdd20aSAndroid Build Coastguard WorkerGenerate a size report for target binaries. 17*6dbdd20aSAndroid Build Coastguard Worker 18*6dbdd20aSAndroid Build Coastguard WorkerFor example: 19*6dbdd20aSAndroid Build Coastguard Worker$ tools/ninja -C out/r traced_probes traced 20*6dbdd20aSAndroid Build Coastguard Worker$ tools/size-report.py -C out/r traced_probes traced 21*6dbdd20aSAndroid Build Coastguard Worker""" 22*6dbdd20aSAndroid Build Coastguard Worker 23*6dbdd20aSAndroid Build Coastguard Workerfrom __future__ import absolute_import 24*6dbdd20aSAndroid Build Coastguard Workerfrom __future__ import division 25*6dbdd20aSAndroid Build Coastguard Workerfrom __future__ import print_function 26*6dbdd20aSAndroid Build Coastguard Worker 27*6dbdd20aSAndroid Build Coastguard Workerimport argparse 28*6dbdd20aSAndroid Build Coastguard Workerimport os 29*6dbdd20aSAndroid Build Coastguard Workerimport subprocess 30*6dbdd20aSAndroid Build Coastguard Workerimport sys 31*6dbdd20aSAndroid Build Coastguard Workerimport json 32*6dbdd20aSAndroid Build Coastguard Worker 33*6dbdd20aSAndroid Build Coastguard WorkerROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 34*6dbdd20aSAndroid Build Coastguard WorkerBLOATY_PATH = os.path.join(ROOT_DIR, 'buildtools', 'bloaty', 'bloaty') 35*6dbdd20aSAndroid Build Coastguard WorkerGN_PATH = os.path.join(ROOT_DIR, 'tools', 'gn') 36*6dbdd20aSAndroid Build Coastguard Worker 37*6dbdd20aSAndroid Build Coastguard Worker 38*6dbdd20aSAndroid Build Coastguard Workerdef GetGnArgValueOrNone(arg): 39*6dbdd20aSAndroid Build Coastguard Worker if 'current' in arg: 40*6dbdd20aSAndroid Build Coastguard Worker return eval(arg['current']['value']) 41*6dbdd20aSAndroid Build Coastguard Worker if 'default' in arg: 42*6dbdd20aSAndroid Build Coastguard Worker return eval(arg['default']['value']) 43*6dbdd20aSAndroid Build Coastguard Worker return None 44*6dbdd20aSAndroid Build Coastguard Worker 45*6dbdd20aSAndroid Build Coastguard Worker 46*6dbdd20aSAndroid Build Coastguard Workerdef GetTargetOsForBuildDir(build_dir): 47*6dbdd20aSAndroid Build Coastguard Worker cmd = [GN_PATH, 'args', '--list', '--json', build_dir] 48*6dbdd20aSAndroid Build Coastguard Worker args = json.loads(subprocess.check_output(cmd)) 49*6dbdd20aSAndroid Build Coastguard Worker target_os = None 50*6dbdd20aSAndroid Build Coastguard Worker host_os = None 51*6dbdd20aSAndroid Build Coastguard Worker for arg in args: 52*6dbdd20aSAndroid Build Coastguard Worker if arg['name'] == 'target_os': 53*6dbdd20aSAndroid Build Coastguard Worker print(arg) 54*6dbdd20aSAndroid Build Coastguard Worker target_os = GetGnArgValueOrNone(arg) 55*6dbdd20aSAndroid Build Coastguard Worker if arg['name'] == 'host_os': 56*6dbdd20aSAndroid Build Coastguard Worker print(arg) 57*6dbdd20aSAndroid Build Coastguard Worker host_os = GetGnArgValueOrNone(arg) 58*6dbdd20aSAndroid Build Coastguard Worker return target_os or host_os or None 59*6dbdd20aSAndroid Build Coastguard Worker 60*6dbdd20aSAndroid Build Coastguard Worker 61*6dbdd20aSAndroid Build Coastguard Workerdef main(): 62*6dbdd20aSAndroid Build Coastguard Worker parser = argparse.ArgumentParser( 63*6dbdd20aSAndroid Build Coastguard Worker formatter_class=argparse.RawDescriptionHelpFormatter, description=__doc__) 64*6dbdd20aSAndroid Build Coastguard Worker parser.add_argument( 65*6dbdd20aSAndroid Build Coastguard Worker '-C', '--build-dir', metavar='DIR', help='build directory', required=True) 66*6dbdd20aSAndroid Build Coastguard Worker parser.add_argument('-o', '--output', help='output path', default=None) 67*6dbdd20aSAndroid Build Coastguard Worker parser.add_argument( 68*6dbdd20aSAndroid Build Coastguard Worker 'binaries', metavar='BINARY', nargs='+', help='subjects of size report') 69*6dbdd20aSAndroid Build Coastguard Worker args = parser.parse_args() 70*6dbdd20aSAndroid Build Coastguard Worker 71*6dbdd20aSAndroid Build Coastguard Worker if not os.path.exists(BLOATY_PATH): 72*6dbdd20aSAndroid Build Coastguard Worker print( 73*6dbdd20aSAndroid Build Coastguard Worker 'Could not find bloaty at expected path "{}". Try re-running ./tools/install-build-deps' 74*6dbdd20aSAndroid Build Coastguard Worker .format(BLOATY_PATH)) 75*6dbdd20aSAndroid Build Coastguard Worker return 1 76*6dbdd20aSAndroid Build Coastguard Worker 77*6dbdd20aSAndroid Build Coastguard Worker results = [] 78*6dbdd20aSAndroid Build Coastguard Worker 79*6dbdd20aSAndroid Build Coastguard Worker out_directory = args.build_dir 80*6dbdd20aSAndroid Build Coastguard Worker target_os = GetTargetOsForBuildDir(out_directory) 81*6dbdd20aSAndroid Build Coastguard Worker print('target_os', target_os) 82*6dbdd20aSAndroid Build Coastguard Worker for binary in args.binaries: 83*6dbdd20aSAndroid Build Coastguard Worker binary_path = os.path.join(out_directory, binary) 84*6dbdd20aSAndroid Build Coastguard Worker output = '{} - {}\n'.format(binary, binary_path) 85*6dbdd20aSAndroid Build Coastguard Worker if target_os == 'mac': 86*6dbdd20aSAndroid Build Coastguard Worker subprocess.check_output(['dsymutil', binary_path]) 87*6dbdd20aSAndroid Build Coastguard Worker symbols = '--debug-file={}.dSYM/Contents/Resources/DWARF/{}'.format( 88*6dbdd20aSAndroid Build Coastguard Worker binary_path, binary) 89*6dbdd20aSAndroid Build Coastguard Worker cmd = [symbols, '-d', 'compileunits', '-n', '100', binary_path] 90*6dbdd20aSAndroid Build Coastguard Worker else: 91*6dbdd20aSAndroid Build Coastguard Worker cmd = ['-d', 'compileunits', '-n', '100', binary_path] 92*6dbdd20aSAndroid Build Coastguard Worker output += subprocess.check_output([BLOATY_PATH] + cmd).decode('utf-8') 93*6dbdd20aSAndroid Build Coastguard Worker results.append(output) 94*6dbdd20aSAndroid Build Coastguard Worker 95*6dbdd20aSAndroid Build Coastguard Worker if args.output is None or args.output == '-': 96*6dbdd20aSAndroid Build Coastguard Worker out = sys.stdout 97*6dbdd20aSAndroid Build Coastguard Worker else: 98*6dbdd20aSAndroid Build Coastguard Worker out = open(args.output, 'w') 99*6dbdd20aSAndroid Build Coastguard Worker 100*6dbdd20aSAndroid Build Coastguard Worker for result in results: 101*6dbdd20aSAndroid Build Coastguard Worker out.write(result) 102*6dbdd20aSAndroid Build Coastguard Worker out.write('\n') 103*6dbdd20aSAndroid Build Coastguard Worker return 0 104*6dbdd20aSAndroid Build Coastguard Worker 105*6dbdd20aSAndroid Build Coastguard Worker 106*6dbdd20aSAndroid Build Coastguard Workerif __name__ == '__main__': 107*6dbdd20aSAndroid Build Coastguard Worker sys.exit(main()) 108