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