• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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        # The file system tests require a handful of defines that we can't add
18        # to the Android.bp since they require absolute paths.
19        self.extra_cflags = []
20
21    def copy(self):
22        return copy.deepcopy(self)
23
24    def get_triple(self):
25        if 'clang' in self.path:
26            return self.get_clang_triple()
27        else:
28            return self.get_gcc_triple()
29
30        raise RuntimeError('Could not determine target triple.')
31
32    def get_clang_triple(self):
33        match = re.search(r'-target\s+(\S+)', self.cxx_template)
34        if match:
35            return match.group(1)
36        return None
37
38    def get_gcc_triple(self):
39        proc = subprocess.Popen([self.path, '-v'],
40                                stderr=subprocess.PIPE)
41        _, stderr = proc.communicate()
42        for line in stderr.split('\n'):
43            print 'Checking {}'.format(line)
44            match = re.search(r'^Target: (.+)$', line)
45            if match:
46                return match.group(1)
47        return None
48
49    def compile(self, source_files, out=None, flags=None, cwd=None):
50        flags = [] if flags is None else flags
51        return super(AndroidCXXCompiler, self).compile(source_files, out, flags,
52                                                       self.build_top)
53
54    def link(self, source_files, out=None, flags=None, cwd=None):
55        flags = [] if flags is None else flags
56        return super(AndroidCXXCompiler, self).link(source_files, out, flags,
57                                                    self.build_top)
58
59    def compileCmd(self, source_files, out=None, flags=None):
60        if out is None:
61            raise RuntimeError('The Android compiler requires an out path.')
62
63        if isinstance(source_files, str):
64            source_files = [source_files]
65        cxx_args = self.cxx_template.replace('%OUT%', out)
66        cxx_args = cxx_args.replace('%SOURCE%', ' '.join(source_files))
67        return [self.path] + shlex.split(cxx_args) + self.extra_cflags
68
69    def linkCmd(self, source_files, out=None, flags=None):
70        if out is None:
71            raise RuntimeError('The Android compiler requires an out path.')
72
73        if isinstance(source_files, str):
74            source_files = [source_files]
75        link_args = self.link_template.replace('%OUT%', out)
76        link_args = link_args.replace('%SOURCE%', ' '.join(source_files))
77        return [self.path] + shlex.split(link_args)
78
79    def _basicCmd(self, source_files, out, is_link=False, input_is_cxx=False):
80        raise NotImplementedError()
81
82    def _initTypeAndVersion(self):
83        pass
84