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