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