1import os 2import re 3import shlex 4import subprocess 5 6import libcxx.compiler 7 8 9class AndroidCXXCompiler(libcxx.compiler.CXXCompiler): 10 def __init__(self, cxx_under_test, cxx_template, link_template): 11 super(AndroidCXXCompiler, self).__init__(cxx_under_test) 12 self.cxx_template = cxx_template 13 self.link_template = link_template 14 self.build_top = os.getenv('ANDROID_BUILD_TOP') 15 16 def get_triple(self): 17 if 'clang' in self.path: 18 return self.get_clang_triple() 19 else: 20 return self.get_gcc_triple() 21 22 raise RuntimeError('Could not determine target triple.') 23 24 def get_clang_triple(self): 25 match = re.search(r'-target\s+(\S+)', self.cxx_template) 26 if match: 27 return match.group(1) 28 return None 29 30 def get_gcc_triple(self): 31 proc = subprocess.Popen([self.path, '-v'], 32 stderr=subprocess.PIPE) 33 _, stderr = proc.communicate() 34 for line in stderr.split('\n'): 35 print 'Checking {}'.format(line) 36 match = re.search(r'^Target: (.+)$', line) 37 if match: 38 return match.group(1) 39 return None 40 41 def compile(self, source_files, out=None, flags=None, env=None, cwd=None): 42 flags = [] if flags is None else flags 43 return super(AndroidCXXCompiler, self).compile(source_files, out, flags, 44 env, self.build_top) 45 46 def link(self, source_files, out=None, flags=None, env=None, cwd=None): 47 flags = [] if flags is None else flags 48 return super(AndroidCXXCompiler, self).link(source_files, out, flags, 49 env, self.build_top) 50 51 def compileCmd(self, source_files, out=None, flags=None): 52 if out is None: 53 raise RuntimeError('The Android compiler requires an out path.') 54 55 if isinstance(source_files, str): 56 source_files = [source_files] 57 cxx_args = self.cxx_template.replace('%OUT%', out) 58 cxx_args = cxx_args.replace('%SOURCE%', ' '.join(source_files)) 59 return [self.path] + shlex.split(cxx_args) 60 61 def linkCmd(self, source_files, out=None, flags=None): 62 if out is None: 63 raise RuntimeError('The Android compiler requires an out path.') 64 65 if isinstance(source_files, str): 66 source_files = [source_files] 67 link_args = self.link_template.replace('%OUT%', out) 68 link_args = link_args.replace('%SOURCE%', ' '.join(source_files)) 69 return [self.path] + shlex.split(link_args) 70 71 def _basicCmd(self, source_files, out, is_link=False, input_is_cxx=False): 72 raise NotImplementedError() 73 74 def _initTypeAndVersion(self): 75 pass 76