1#!/usr/bin/env python2 2"""Prototype compiler wrapper. 3 4Only tested with: gcc, g++, clang, clang++ 5Installation instructions: 6 1. Rename compiler from <compiler_name> to <compiler_name>.real 7 2. Create symlink from this script (compiler_wrapper.py), and name it 8 <compiler_name>. compiler_wrapper.py can live anywhere as long as it is 9 executable. 10 11Reference page: 12https://sites.google.com/a/google.com/chromeos-toolchain-team-home2/home/team-tools-and-scripts/bisecting-chromeos-compiler-problems/bisection-compiler-wrapper 13 14Design doc: 15https://docs.google.com/document/d/1yDgaUIa2O5w6dc3sSTe1ry-1ehKajTGJGQCbyn0fcEM 16""" 17 18from __future__ import print_function 19 20import os 21import shlex 22import sys 23 24import bisect_driver 25 26WRAPPED = '%s.real' % sys.argv[0] 27BISECT_STAGE = os.environ.get('BISECT_STAGE') 28DEFAULT_BISECT_DIR = os.path.expanduser('~/ANDROID_BISECT') 29BISECT_DIR = os.environ.get('BISECT_DIR') or DEFAULT_BISECT_DIR 30 31 32def ProcessArgFile(arg_file): 33 args = [] 34 # Read in entire file at once and parse as if in shell 35 with open(arg_file, 'rb') as f: 36 args.extend(shlex.split(f.read())) 37 38 return args 39 40 41def Main(_): 42 if not os.path.islink(sys.argv[0]): 43 print("Compiler wrapper can't be called directly!") 44 return 1 45 46 execargs = [WRAPPED] + sys.argv[1:] 47 48 if BISECT_STAGE not in bisect_driver.VALID_MODES or '-o' not in execargs: 49 os.execv(WRAPPED, [WRAPPED] + sys.argv[1:]) 50 51 # Handle @file argument syntax with compiler 52 for idx, _ in enumerate(execargs): 53 # @file can be nested in other @file arguments, use While to re-evaluate 54 # the first argument of the embedded file. 55 while execargs[idx][0] == '@': 56 args_in_file = ProcessArgFile(execargs[idx][1:]) 57 execargs = execargs[0:idx] + args_in_file + execargs[idx + 1:] 58 59 bisect_driver.bisect_driver(BISECT_STAGE, BISECT_DIR, execargs) 60 61 62if __name__ == '__main__': 63 sys.exit(Main(sys.argv[1:])) 64