1*c2e18aaaSAndroid Build Coastguard Worker#!/usr/bin/env python3 2*c2e18aaaSAndroid Build Coastguard Worker# Copyright 2022, The Android Open Source Project 3*c2e18aaaSAndroid Build Coastguard Worker# 4*c2e18aaaSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 5*c2e18aaaSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 6*c2e18aaaSAndroid Build Coastguard Worker# You may obtain a copy of the License at 7*c2e18aaaSAndroid Build Coastguard Worker# 8*c2e18aaaSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 9*c2e18aaaSAndroid Build Coastguard Worker# 10*c2e18aaaSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 11*c2e18aaaSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 12*c2e18aaaSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*c2e18aaaSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 14*c2e18aaaSAndroid Build Coastguard Worker# limitations under the License. 15*c2e18aaaSAndroid Build Coastguard Worker 16*c2e18aaaSAndroid Build Coastguard Worker"""Script of Atest Profiler.""" 17*c2e18aaaSAndroid Build Coastguard Worker 18*c2e18aaaSAndroid Build Coastguard Workerimport argparse 19*c2e18aaaSAndroid Build Coastguard Workerimport os 20*c2e18aaaSAndroid Build Coastguard Workerimport shutil 21*c2e18aaaSAndroid Build Coastguard Workerimport subprocess 22*c2e18aaaSAndroid Build Coastguard Workerimport sys 23*c2e18aaaSAndroid Build Coastguard Workerimport tempfile 24*c2e18aaaSAndroid Build Coastguard Workerimport zipfile 25*c2e18aaaSAndroid Build Coastguard Worker 26*c2e18aaaSAndroid Build Coastguard Worker# This is mostly a copy of Soong's stub_template_host.txt, but with changes to 27*c2e18aaaSAndroid Build Coastguard Worker# run soong python executables via a profiler tool. This is just a hack, soong 28*c2e18aaaSAndroid Build Coastguard Worker# should really have the ability to build profiled binaries directly. 29*c2e18aaaSAndroid Build Coastguard Worker 30*c2e18aaaSAndroid Build Coastguard Worker 31*c2e18aaaSAndroid Build Coastguard Workerdef main(): 32*c2e18aaaSAndroid Build Coastguard Worker """Main method that runs python profilers.""" 33*c2e18aaaSAndroid Build Coastguard Worker parser = argparse.ArgumentParser( 34*c2e18aaaSAndroid Build Coastguard Worker description='Runs a soong-built python binary under a profiler.' 35*c2e18aaaSAndroid Build Coastguard Worker ) 36*c2e18aaaSAndroid Build Coastguard Worker parser.add_argument( 37*c2e18aaaSAndroid Build Coastguard Worker 'profiler', 38*c2e18aaaSAndroid Build Coastguard Worker choices=['pyinstrument', 'cProfile'], 39*c2e18aaaSAndroid Build Coastguard Worker help='The profiler to use', 40*c2e18aaaSAndroid Build Coastguard Worker ) 41*c2e18aaaSAndroid Build Coastguard Worker parser.add_argument('profile_file', help='The output file of the profiler') 42*c2e18aaaSAndroid Build Coastguard Worker parser.add_argument( 43*c2e18aaaSAndroid Build Coastguard Worker 'executable', 44*c2e18aaaSAndroid Build Coastguard Worker help='The soong-built python binary (with embedded_launcher: false)', 45*c2e18aaaSAndroid Build Coastguard Worker ) 46*c2e18aaaSAndroid Build Coastguard Worker args, args_for_executable = parser.parse_known_args() 47*c2e18aaaSAndroid Build Coastguard Worker 48*c2e18aaaSAndroid Build Coastguard Worker if not os.path.isfile(args.executable): 49*c2e18aaaSAndroid Build Coastguard Worker sys.exit(f'{args.executable}: File not found') 50*c2e18aaaSAndroid Build Coastguard Worker os.makedirs(os.path.dirname(args.profile_file), exist_ok=True) 51*c2e18aaaSAndroid Build Coastguard Worker 52*c2e18aaaSAndroid Build Coastguard Worker runfiles_path = tempfile.mkdtemp(prefix='Soong.python_') 53*c2e18aaaSAndroid Build Coastguard Worker try: 54*c2e18aaaSAndroid Build Coastguard Worker _zf = zipfile.ZipFile(args.executable) 55*c2e18aaaSAndroid Build Coastguard Worker _zf.extractall(runfiles_path) 56*c2e18aaaSAndroid Build Coastguard Worker _zf.close() 57*c2e18aaaSAndroid Build Coastguard Worker 58*c2e18aaaSAndroid Build Coastguard Worker sys.exit( 59*c2e18aaaSAndroid Build Coastguard Worker subprocess.call( 60*c2e18aaaSAndroid Build Coastguard Worker [ 61*c2e18aaaSAndroid Build Coastguard Worker 'python3', 62*c2e18aaaSAndroid Build Coastguard Worker '-m', 63*c2e18aaaSAndroid Build Coastguard Worker args.profiler, 64*c2e18aaaSAndroid Build Coastguard Worker '-o', 65*c2e18aaaSAndroid Build Coastguard Worker args.profile_file, 66*c2e18aaaSAndroid Build Coastguard Worker os.path.join( 67*c2e18aaaSAndroid Build Coastguard Worker runfiles_path, '__soong_entrypoint_redirector__.py' 68*c2e18aaaSAndroid Build Coastguard Worker ), 69*c2e18aaaSAndroid Build Coastguard Worker ] 70*c2e18aaaSAndroid Build Coastguard Worker + args_for_executable, 71*c2e18aaaSAndroid Build Coastguard Worker close_fds=False, 72*c2e18aaaSAndroid Build Coastguard Worker ) 73*c2e18aaaSAndroid Build Coastguard Worker ) 74*c2e18aaaSAndroid Build Coastguard Worker 75*c2e18aaaSAndroid Build Coastguard Worker finally: 76*c2e18aaaSAndroid Build Coastguard Worker shutil.rmtree(runfiles_path, ignore_errors=True) 77*c2e18aaaSAndroid Build Coastguard Worker 78*c2e18aaaSAndroid Build Coastguard Worker 79*c2e18aaaSAndroid Build Coastguard Workerif __name__ == '__main__': 80*c2e18aaaSAndroid Build Coastguard Worker main() 81