xref: /aosp_15_r20/external/llvm/utils/llvm-build/llvmbuild/componentinfo.py (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker"""
2*9880d681SAndroid Build Coastguard WorkerDescriptor objects for entities that are part of the LLVM project.
3*9880d681SAndroid Build Coastguard Worker"""
4*9880d681SAndroid Build Coastguard Worker
5*9880d681SAndroid Build Coastguard Workerfrom __future__ import absolute_import
6*9880d681SAndroid Build Coastguard Workertry:
7*9880d681SAndroid Build Coastguard Worker    import configparser
8*9880d681SAndroid Build Coastguard Workerexcept:
9*9880d681SAndroid Build Coastguard Worker    import ConfigParser as configparser
10*9880d681SAndroid Build Coastguard Workerimport sys
11*9880d681SAndroid Build Coastguard Worker
12*9880d681SAndroid Build Coastguard Workerfrom llvmbuild.util import fatal, warning
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Workerclass ParseError(Exception):
15*9880d681SAndroid Build Coastguard Worker    pass
16*9880d681SAndroid Build Coastguard Worker
17*9880d681SAndroid Build Coastguard Workerclass ComponentInfo(object):
18*9880d681SAndroid Build Coastguard Worker    """
19*9880d681SAndroid Build Coastguard Worker    Base class for component descriptions.
20*9880d681SAndroid Build Coastguard Worker    """
21*9880d681SAndroid Build Coastguard Worker
22*9880d681SAndroid Build Coastguard Worker    type_name = None
23*9880d681SAndroid Build Coastguard Worker
24*9880d681SAndroid Build Coastguard Worker    @staticmethod
25*9880d681SAndroid Build Coastguard Worker    def parse_items(items, has_dependencies = True):
26*9880d681SAndroid Build Coastguard Worker        kwargs = {}
27*9880d681SAndroid Build Coastguard Worker        kwargs['name'] = items.get_string('name')
28*9880d681SAndroid Build Coastguard Worker        kwargs['parent'] = items.get_optional_string('parent')
29*9880d681SAndroid Build Coastguard Worker        if has_dependencies:
30*9880d681SAndroid Build Coastguard Worker            kwargs['dependencies'] = items.get_list('dependencies')
31*9880d681SAndroid Build Coastguard Worker        return kwargs
32*9880d681SAndroid Build Coastguard Worker
33*9880d681SAndroid Build Coastguard Worker    def __init__(self, subpath, name, dependencies, parent):
34*9880d681SAndroid Build Coastguard Worker        if not subpath.startswith('/'):
35*9880d681SAndroid Build Coastguard Worker            raise ValueError("invalid subpath: %r" % subpath)
36*9880d681SAndroid Build Coastguard Worker        self.subpath = subpath
37*9880d681SAndroid Build Coastguard Worker        self.name = name
38*9880d681SAndroid Build Coastguard Worker        self.dependencies = list(dependencies)
39*9880d681SAndroid Build Coastguard Worker
40*9880d681SAndroid Build Coastguard Worker        # The name of the parent component to logically group this component
41*9880d681SAndroid Build Coastguard Worker        # under.
42*9880d681SAndroid Build Coastguard Worker        self.parent = parent
43*9880d681SAndroid Build Coastguard Worker
44*9880d681SAndroid Build Coastguard Worker        # The parent instance, once loaded.
45*9880d681SAndroid Build Coastguard Worker        self.parent_instance = None
46*9880d681SAndroid Build Coastguard Worker        self.children = []
47*9880d681SAndroid Build Coastguard Worker
48*9880d681SAndroid Build Coastguard Worker        # The original source path.
49*9880d681SAndroid Build Coastguard Worker        self._source_path = None
50*9880d681SAndroid Build Coastguard Worker
51*9880d681SAndroid Build Coastguard Worker        # A flag to mark "special" components which have some amount of magic
52*9880d681SAndroid Build Coastguard Worker        # handling (generally based on command line options).
53*9880d681SAndroid Build Coastguard Worker        self._is_special_group = False
54*9880d681SAndroid Build Coastguard Worker
55*9880d681SAndroid Build Coastguard Worker    def set_parent_instance(self, parent):
56*9880d681SAndroid Build Coastguard Worker        assert parent.name == self.parent, "Unexpected parent!"
57*9880d681SAndroid Build Coastguard Worker        self.parent_instance = parent
58*9880d681SAndroid Build Coastguard Worker        self.parent_instance.children.append(self)
59*9880d681SAndroid Build Coastguard Worker
60*9880d681SAndroid Build Coastguard Worker    def get_component_references(self):
61*9880d681SAndroid Build Coastguard Worker        """get_component_references() -> iter
62*9880d681SAndroid Build Coastguard Worker
63*9880d681SAndroid Build Coastguard Worker        Return an iterator over the named references to other components from
64*9880d681SAndroid Build Coastguard Worker        this object. Items are of the form (reference-type, component-name).
65*9880d681SAndroid Build Coastguard Worker        """
66*9880d681SAndroid Build Coastguard Worker
67*9880d681SAndroid Build Coastguard Worker        # Parent references are handled specially.
68*9880d681SAndroid Build Coastguard Worker        for r in self.dependencies:
69*9880d681SAndroid Build Coastguard Worker            yield ('dependency', r)
70*9880d681SAndroid Build Coastguard Worker
71*9880d681SAndroid Build Coastguard Worker    def get_llvmbuild_fragment(self):
72*9880d681SAndroid Build Coastguard Worker        abstract
73*9880d681SAndroid Build Coastguard Worker
74*9880d681SAndroid Build Coastguard Worker    def get_parent_target_group(self):
75*9880d681SAndroid Build Coastguard Worker        """get_parent_target_group() -> ComponentInfo or None
76*9880d681SAndroid Build Coastguard Worker
77*9880d681SAndroid Build Coastguard Worker        Return the nearest parent target group (if any), or None if the
78*9880d681SAndroid Build Coastguard Worker        component is not part of any target group.
79*9880d681SAndroid Build Coastguard Worker        """
80*9880d681SAndroid Build Coastguard Worker
81*9880d681SAndroid Build Coastguard Worker        # If this is a target group, return it.
82*9880d681SAndroid Build Coastguard Worker        if self.type_name == 'TargetGroup':
83*9880d681SAndroid Build Coastguard Worker            return self
84*9880d681SAndroid Build Coastguard Worker
85*9880d681SAndroid Build Coastguard Worker        # Otherwise recurse on the parent, if any.
86*9880d681SAndroid Build Coastguard Worker        if self.parent_instance:
87*9880d681SAndroid Build Coastguard Worker            return self.parent_instance.get_parent_target_group()
88*9880d681SAndroid Build Coastguard Worker
89*9880d681SAndroid Build Coastguard Workerclass GroupComponentInfo(ComponentInfo):
90*9880d681SAndroid Build Coastguard Worker    """
91*9880d681SAndroid Build Coastguard Worker    Group components have no semantics as far as the build system are concerned,
92*9880d681SAndroid Build Coastguard Worker    but exist to help organize other components into a logical tree structure.
93*9880d681SAndroid Build Coastguard Worker    """
94*9880d681SAndroid Build Coastguard Worker
95*9880d681SAndroid Build Coastguard Worker    type_name = 'Group'
96*9880d681SAndroid Build Coastguard Worker
97*9880d681SAndroid Build Coastguard Worker    @staticmethod
98*9880d681SAndroid Build Coastguard Worker    def parse(subpath, items):
99*9880d681SAndroid Build Coastguard Worker        kwargs = ComponentInfo.parse_items(items, has_dependencies = False)
100*9880d681SAndroid Build Coastguard Worker        return GroupComponentInfo(subpath, **kwargs)
101*9880d681SAndroid Build Coastguard Worker
102*9880d681SAndroid Build Coastguard Worker    def __init__(self, subpath, name, parent):
103*9880d681SAndroid Build Coastguard Worker        ComponentInfo.__init__(self, subpath, name, [], parent)
104*9880d681SAndroid Build Coastguard Worker
105*9880d681SAndroid Build Coastguard Worker    def get_llvmbuild_fragment(self):
106*9880d681SAndroid Build Coastguard Worker        return """\
107*9880d681SAndroid Build Coastguard Workertype = %s
108*9880d681SAndroid Build Coastguard Workername = %s
109*9880d681SAndroid Build Coastguard Workerparent = %s
110*9880d681SAndroid Build Coastguard Worker""" % (self.type_name, self.name, self.parent)
111*9880d681SAndroid Build Coastguard Worker
112*9880d681SAndroid Build Coastguard Workerclass LibraryComponentInfo(ComponentInfo):
113*9880d681SAndroid Build Coastguard Worker    type_name = 'Library'
114*9880d681SAndroid Build Coastguard Worker
115*9880d681SAndroid Build Coastguard Worker    @staticmethod
116*9880d681SAndroid Build Coastguard Worker    def parse_items(items):
117*9880d681SAndroid Build Coastguard Worker        kwargs = ComponentInfo.parse_items(items)
118*9880d681SAndroid Build Coastguard Worker        kwargs['library_name'] = items.get_optional_string('library_name')
119*9880d681SAndroid Build Coastguard Worker        kwargs['required_libraries'] = items.get_list('required_libraries')
120*9880d681SAndroid Build Coastguard Worker        kwargs['add_to_library_groups'] = items.get_list(
121*9880d681SAndroid Build Coastguard Worker            'add_to_library_groups')
122*9880d681SAndroid Build Coastguard Worker        kwargs['installed'] = items.get_optional_bool('installed', True)
123*9880d681SAndroid Build Coastguard Worker        return kwargs
124*9880d681SAndroid Build Coastguard Worker
125*9880d681SAndroid Build Coastguard Worker    @staticmethod
126*9880d681SAndroid Build Coastguard Worker    def parse(subpath, items):
127*9880d681SAndroid Build Coastguard Worker        kwargs = LibraryComponentInfo.parse_items(items)
128*9880d681SAndroid Build Coastguard Worker        return LibraryComponentInfo(subpath, **kwargs)
129*9880d681SAndroid Build Coastguard Worker
130*9880d681SAndroid Build Coastguard Worker    def __init__(self, subpath, name, dependencies, parent, library_name,
131*9880d681SAndroid Build Coastguard Worker                 required_libraries, add_to_library_groups, installed):
132*9880d681SAndroid Build Coastguard Worker        ComponentInfo.__init__(self, subpath, name, dependencies, parent)
133*9880d681SAndroid Build Coastguard Worker
134*9880d681SAndroid Build Coastguard Worker        # If given, the name to use for the library instead of deriving it from
135*9880d681SAndroid Build Coastguard Worker        # the component name.
136*9880d681SAndroid Build Coastguard Worker        self.library_name = library_name
137*9880d681SAndroid Build Coastguard Worker
138*9880d681SAndroid Build Coastguard Worker        # The names of the library components which are required when linking
139*9880d681SAndroid Build Coastguard Worker        # with this component.
140*9880d681SAndroid Build Coastguard Worker        self.required_libraries = list(required_libraries)
141*9880d681SAndroid Build Coastguard Worker
142*9880d681SAndroid Build Coastguard Worker        # The names of the library group components this component should be
143*9880d681SAndroid Build Coastguard Worker        # considered part of.
144*9880d681SAndroid Build Coastguard Worker        self.add_to_library_groups = list(add_to_library_groups)
145*9880d681SAndroid Build Coastguard Worker
146*9880d681SAndroid Build Coastguard Worker        # Whether or not this library is installed.
147*9880d681SAndroid Build Coastguard Worker        self.installed = installed
148*9880d681SAndroid Build Coastguard Worker
149*9880d681SAndroid Build Coastguard Worker    def get_component_references(self):
150*9880d681SAndroid Build Coastguard Worker        for r in ComponentInfo.get_component_references(self):
151*9880d681SAndroid Build Coastguard Worker            yield r
152*9880d681SAndroid Build Coastguard Worker        for r in self.required_libraries:
153*9880d681SAndroid Build Coastguard Worker            yield ('required library', r)
154*9880d681SAndroid Build Coastguard Worker        for r in self.add_to_library_groups:
155*9880d681SAndroid Build Coastguard Worker            yield ('library group', r)
156*9880d681SAndroid Build Coastguard Worker
157*9880d681SAndroid Build Coastguard Worker    def get_llvmbuild_fragment(self):
158*9880d681SAndroid Build Coastguard Worker        result = """\
159*9880d681SAndroid Build Coastguard Workertype = %s
160*9880d681SAndroid Build Coastguard Workername = %s
161*9880d681SAndroid Build Coastguard Workerparent = %s
162*9880d681SAndroid Build Coastguard Worker""" % (self.type_name, self.name, self.parent)
163*9880d681SAndroid Build Coastguard Worker        if self.library_name is not None:
164*9880d681SAndroid Build Coastguard Worker            result += 'library_name = %s\n' % self.library_name
165*9880d681SAndroid Build Coastguard Worker        if self.required_libraries:
166*9880d681SAndroid Build Coastguard Worker            result += 'required_libraries = %s\n' % ' '.join(
167*9880d681SAndroid Build Coastguard Worker                self.required_libraries)
168*9880d681SAndroid Build Coastguard Worker        if self.add_to_library_groups:
169*9880d681SAndroid Build Coastguard Worker            result += 'add_to_library_groups = %s\n' % ' '.join(
170*9880d681SAndroid Build Coastguard Worker                self.add_to_library_groups)
171*9880d681SAndroid Build Coastguard Worker        if not self.installed:
172*9880d681SAndroid Build Coastguard Worker            result += 'installed = 0\n'
173*9880d681SAndroid Build Coastguard Worker        return result
174*9880d681SAndroid Build Coastguard Worker
175*9880d681SAndroid Build Coastguard Worker    def get_library_name(self):
176*9880d681SAndroid Build Coastguard Worker        return self.library_name or self.name
177*9880d681SAndroid Build Coastguard Worker
178*9880d681SAndroid Build Coastguard Worker    def get_prefixed_library_name(self):
179*9880d681SAndroid Build Coastguard Worker        """
180*9880d681SAndroid Build Coastguard Worker        get_prefixed_library_name() -> str
181*9880d681SAndroid Build Coastguard Worker
182*9880d681SAndroid Build Coastguard Worker        Return the library name prefixed by the project name. This is generally
183*9880d681SAndroid Build Coastguard Worker        what the library name will be on disk.
184*9880d681SAndroid Build Coastguard Worker        """
185*9880d681SAndroid Build Coastguard Worker
186*9880d681SAndroid Build Coastguard Worker        basename = self.get_library_name()
187*9880d681SAndroid Build Coastguard Worker
188*9880d681SAndroid Build Coastguard Worker        # FIXME: We need to get the prefix information from an explicit project
189*9880d681SAndroid Build Coastguard Worker        # object, or something.
190*9880d681SAndroid Build Coastguard Worker        if basename in ('gtest', 'gtest_main'):
191*9880d681SAndroid Build Coastguard Worker            return basename
192*9880d681SAndroid Build Coastguard Worker
193*9880d681SAndroid Build Coastguard Worker        return 'LLVM%s' % basename
194*9880d681SAndroid Build Coastguard Worker
195*9880d681SAndroid Build Coastguard Worker    def get_llvmconfig_component_name(self):
196*9880d681SAndroid Build Coastguard Worker        return self.get_library_name().lower()
197*9880d681SAndroid Build Coastguard Worker
198*9880d681SAndroid Build Coastguard Workerclass OptionalLibraryComponentInfo(LibraryComponentInfo):
199*9880d681SAndroid Build Coastguard Worker    type_name = "OptionalLibrary"
200*9880d681SAndroid Build Coastguard Worker
201*9880d681SAndroid Build Coastguard Worker    @staticmethod
202*9880d681SAndroid Build Coastguard Worker    def parse(subpath, items):
203*9880d681SAndroid Build Coastguard Worker      kwargs = LibraryComponentInfo.parse_items(items)
204*9880d681SAndroid Build Coastguard Worker      return OptionalLibraryComponentInfo(subpath, **kwargs)
205*9880d681SAndroid Build Coastguard Worker
206*9880d681SAndroid Build Coastguard Worker    def __init__(self, subpath, name, dependencies, parent, library_name,
207*9880d681SAndroid Build Coastguard Worker                 required_libraries, add_to_library_groups, installed):
208*9880d681SAndroid Build Coastguard Worker      LibraryComponentInfo.__init__(self, subpath, name, dependencies, parent,
209*9880d681SAndroid Build Coastguard Worker                                    library_name, required_libraries,
210*9880d681SAndroid Build Coastguard Worker                                    add_to_library_groups, installed)
211*9880d681SAndroid Build Coastguard Worker
212*9880d681SAndroid Build Coastguard Workerclass LibraryGroupComponentInfo(ComponentInfo):
213*9880d681SAndroid Build Coastguard Worker    type_name = 'LibraryGroup'
214*9880d681SAndroid Build Coastguard Worker
215*9880d681SAndroid Build Coastguard Worker    @staticmethod
216*9880d681SAndroid Build Coastguard Worker    def parse(subpath, items):
217*9880d681SAndroid Build Coastguard Worker        kwargs = ComponentInfo.parse_items(items, has_dependencies = False)
218*9880d681SAndroid Build Coastguard Worker        kwargs['required_libraries'] = items.get_list('required_libraries')
219*9880d681SAndroid Build Coastguard Worker        kwargs['add_to_library_groups'] = items.get_list(
220*9880d681SAndroid Build Coastguard Worker            'add_to_library_groups')
221*9880d681SAndroid Build Coastguard Worker        return LibraryGroupComponentInfo(subpath, **kwargs)
222*9880d681SAndroid Build Coastguard Worker
223*9880d681SAndroid Build Coastguard Worker    def __init__(self, subpath, name, parent, required_libraries = [],
224*9880d681SAndroid Build Coastguard Worker                 add_to_library_groups = []):
225*9880d681SAndroid Build Coastguard Worker        ComponentInfo.__init__(self, subpath, name, [], parent)
226*9880d681SAndroid Build Coastguard Worker
227*9880d681SAndroid Build Coastguard Worker        # The names of the library components which are required when linking
228*9880d681SAndroid Build Coastguard Worker        # with this component.
229*9880d681SAndroid Build Coastguard Worker        self.required_libraries = list(required_libraries)
230*9880d681SAndroid Build Coastguard Worker
231*9880d681SAndroid Build Coastguard Worker        # The names of the library group components this component should be
232*9880d681SAndroid Build Coastguard Worker        # considered part of.
233*9880d681SAndroid Build Coastguard Worker        self.add_to_library_groups = list(add_to_library_groups)
234*9880d681SAndroid Build Coastguard Worker
235*9880d681SAndroid Build Coastguard Worker    def get_component_references(self):
236*9880d681SAndroid Build Coastguard Worker        for r in ComponentInfo.get_component_references(self):
237*9880d681SAndroid Build Coastguard Worker            yield r
238*9880d681SAndroid Build Coastguard Worker        for r in self.required_libraries:
239*9880d681SAndroid Build Coastguard Worker            yield ('required library', r)
240*9880d681SAndroid Build Coastguard Worker        for r in self.add_to_library_groups:
241*9880d681SAndroid Build Coastguard Worker            yield ('library group', r)
242*9880d681SAndroid Build Coastguard Worker
243*9880d681SAndroid Build Coastguard Worker    def get_llvmbuild_fragment(self):
244*9880d681SAndroid Build Coastguard Worker        result = """\
245*9880d681SAndroid Build Coastguard Workertype = %s
246*9880d681SAndroid Build Coastguard Workername = %s
247*9880d681SAndroid Build Coastguard Workerparent = %s
248*9880d681SAndroid Build Coastguard Worker""" % (self.type_name, self.name, self.parent)
249*9880d681SAndroid Build Coastguard Worker        if self.required_libraries and not self._is_special_group:
250*9880d681SAndroid Build Coastguard Worker            result += 'required_libraries = %s\n' % ' '.join(
251*9880d681SAndroid Build Coastguard Worker                self.required_libraries)
252*9880d681SAndroid Build Coastguard Worker        if self.add_to_library_groups:
253*9880d681SAndroid Build Coastguard Worker            result += 'add_to_library_groups = %s\n' % ' '.join(
254*9880d681SAndroid Build Coastguard Worker                self.add_to_library_groups)
255*9880d681SAndroid Build Coastguard Worker        return result
256*9880d681SAndroid Build Coastguard Worker
257*9880d681SAndroid Build Coastguard Worker    def get_llvmconfig_component_name(self):
258*9880d681SAndroid Build Coastguard Worker        return self.name.lower()
259*9880d681SAndroid Build Coastguard Worker
260*9880d681SAndroid Build Coastguard Workerclass TargetGroupComponentInfo(ComponentInfo):
261*9880d681SAndroid Build Coastguard Worker    type_name = 'TargetGroup'
262*9880d681SAndroid Build Coastguard Worker
263*9880d681SAndroid Build Coastguard Worker    @staticmethod
264*9880d681SAndroid Build Coastguard Worker    def parse(subpath, items):
265*9880d681SAndroid Build Coastguard Worker        kwargs = ComponentInfo.parse_items(items, has_dependencies = False)
266*9880d681SAndroid Build Coastguard Worker        kwargs['required_libraries'] = items.get_list('required_libraries')
267*9880d681SAndroid Build Coastguard Worker        kwargs['add_to_library_groups'] = items.get_list(
268*9880d681SAndroid Build Coastguard Worker            'add_to_library_groups')
269*9880d681SAndroid Build Coastguard Worker        kwargs['has_jit'] = items.get_optional_bool('has_jit', False)
270*9880d681SAndroid Build Coastguard Worker        kwargs['has_asmprinter'] = items.get_optional_bool('has_asmprinter',
271*9880d681SAndroid Build Coastguard Worker                                                           False)
272*9880d681SAndroid Build Coastguard Worker        kwargs['has_asmparser'] = items.get_optional_bool('has_asmparser',
273*9880d681SAndroid Build Coastguard Worker                                                          False)
274*9880d681SAndroid Build Coastguard Worker        kwargs['has_disassembler'] = items.get_optional_bool('has_disassembler',
275*9880d681SAndroid Build Coastguard Worker                                                             False)
276*9880d681SAndroid Build Coastguard Worker        return TargetGroupComponentInfo(subpath, **kwargs)
277*9880d681SAndroid Build Coastguard Worker
278*9880d681SAndroid Build Coastguard Worker    def __init__(self, subpath, name, parent, required_libraries = [],
279*9880d681SAndroid Build Coastguard Worker                 add_to_library_groups = [], has_jit = False,
280*9880d681SAndroid Build Coastguard Worker                 has_asmprinter = False, has_asmparser = False,
281*9880d681SAndroid Build Coastguard Worker                 has_disassembler = False):
282*9880d681SAndroid Build Coastguard Worker        ComponentInfo.__init__(self, subpath, name, [], parent)
283*9880d681SAndroid Build Coastguard Worker
284*9880d681SAndroid Build Coastguard Worker        # The names of the library components which are required when linking
285*9880d681SAndroid Build Coastguard Worker        # with this component.
286*9880d681SAndroid Build Coastguard Worker        self.required_libraries = list(required_libraries)
287*9880d681SAndroid Build Coastguard Worker
288*9880d681SAndroid Build Coastguard Worker        # The names of the library group components this component should be
289*9880d681SAndroid Build Coastguard Worker        # considered part of.
290*9880d681SAndroid Build Coastguard Worker        self.add_to_library_groups = list(add_to_library_groups)
291*9880d681SAndroid Build Coastguard Worker
292*9880d681SAndroid Build Coastguard Worker        # Whether or not this target supports the JIT.
293*9880d681SAndroid Build Coastguard Worker        self.has_jit = bool(has_jit)
294*9880d681SAndroid Build Coastguard Worker
295*9880d681SAndroid Build Coastguard Worker        # Whether or not this target defines an assembly printer.
296*9880d681SAndroid Build Coastguard Worker        self.has_asmprinter = bool(has_asmprinter)
297*9880d681SAndroid Build Coastguard Worker
298*9880d681SAndroid Build Coastguard Worker        # Whether or not this target defines an assembly parser.
299*9880d681SAndroid Build Coastguard Worker        self.has_asmparser = bool(has_asmparser)
300*9880d681SAndroid Build Coastguard Worker
301*9880d681SAndroid Build Coastguard Worker        # Whether or not this target defines an disassembler.
302*9880d681SAndroid Build Coastguard Worker        self.has_disassembler = bool(has_disassembler)
303*9880d681SAndroid Build Coastguard Worker
304*9880d681SAndroid Build Coastguard Worker        # Whether or not this target is enabled. This is set in response to
305*9880d681SAndroid Build Coastguard Worker        # configuration parameters.
306*9880d681SAndroid Build Coastguard Worker        self.enabled = False
307*9880d681SAndroid Build Coastguard Worker
308*9880d681SAndroid Build Coastguard Worker    def get_component_references(self):
309*9880d681SAndroid Build Coastguard Worker        for r in ComponentInfo.get_component_references(self):
310*9880d681SAndroid Build Coastguard Worker            yield r
311*9880d681SAndroid Build Coastguard Worker        for r in self.required_libraries:
312*9880d681SAndroid Build Coastguard Worker            yield ('required library', r)
313*9880d681SAndroid Build Coastguard Worker        for r in self.add_to_library_groups:
314*9880d681SAndroid Build Coastguard Worker            yield ('library group', r)
315*9880d681SAndroid Build Coastguard Worker
316*9880d681SAndroid Build Coastguard Worker    def get_llvmbuild_fragment(self):
317*9880d681SAndroid Build Coastguard Worker        result = """\
318*9880d681SAndroid Build Coastguard Workertype = %s
319*9880d681SAndroid Build Coastguard Workername = %s
320*9880d681SAndroid Build Coastguard Workerparent = %s
321*9880d681SAndroid Build Coastguard Worker""" % (self.type_name, self.name, self.parent)
322*9880d681SAndroid Build Coastguard Worker        if self.required_libraries:
323*9880d681SAndroid Build Coastguard Worker            result += 'required_libraries = %s\n' % ' '.join(
324*9880d681SAndroid Build Coastguard Worker                self.required_libraries)
325*9880d681SAndroid Build Coastguard Worker        if self.add_to_library_groups:
326*9880d681SAndroid Build Coastguard Worker            result += 'add_to_library_groups = %s\n' % ' '.join(
327*9880d681SAndroid Build Coastguard Worker                self.add_to_library_groups)
328*9880d681SAndroid Build Coastguard Worker        for bool_key in ('has_asmparser', 'has_asmprinter', 'has_disassembler',
329*9880d681SAndroid Build Coastguard Worker                         'has_jit'):
330*9880d681SAndroid Build Coastguard Worker            if getattr(self, bool_key):
331*9880d681SAndroid Build Coastguard Worker                result += '%s = 1\n' % (bool_key,)
332*9880d681SAndroid Build Coastguard Worker        return result
333*9880d681SAndroid Build Coastguard Worker
334*9880d681SAndroid Build Coastguard Worker    def get_llvmconfig_component_name(self):
335*9880d681SAndroid Build Coastguard Worker        return self.name.lower()
336*9880d681SAndroid Build Coastguard Worker
337*9880d681SAndroid Build Coastguard Workerclass ToolComponentInfo(ComponentInfo):
338*9880d681SAndroid Build Coastguard Worker    type_name = 'Tool'
339*9880d681SAndroid Build Coastguard Worker
340*9880d681SAndroid Build Coastguard Worker    @staticmethod
341*9880d681SAndroid Build Coastguard Worker    def parse(subpath, items):
342*9880d681SAndroid Build Coastguard Worker        kwargs = ComponentInfo.parse_items(items)
343*9880d681SAndroid Build Coastguard Worker        kwargs['required_libraries'] = items.get_list('required_libraries')
344*9880d681SAndroid Build Coastguard Worker        return ToolComponentInfo(subpath, **kwargs)
345*9880d681SAndroid Build Coastguard Worker
346*9880d681SAndroid Build Coastguard Worker    def __init__(self, subpath, name, dependencies, parent,
347*9880d681SAndroid Build Coastguard Worker                 required_libraries):
348*9880d681SAndroid Build Coastguard Worker        ComponentInfo.__init__(self, subpath, name, dependencies, parent)
349*9880d681SAndroid Build Coastguard Worker
350*9880d681SAndroid Build Coastguard Worker        # The names of the library components which are required to link this
351*9880d681SAndroid Build Coastguard Worker        # tool.
352*9880d681SAndroid Build Coastguard Worker        self.required_libraries = list(required_libraries)
353*9880d681SAndroid Build Coastguard Worker
354*9880d681SAndroid Build Coastguard Worker    def get_component_references(self):
355*9880d681SAndroid Build Coastguard Worker        for r in ComponentInfo.get_component_references(self):
356*9880d681SAndroid Build Coastguard Worker            yield r
357*9880d681SAndroid Build Coastguard Worker        for r in self.required_libraries:
358*9880d681SAndroid Build Coastguard Worker            yield ('required library', r)
359*9880d681SAndroid Build Coastguard Worker
360*9880d681SAndroid Build Coastguard Worker    def get_llvmbuild_fragment(self):
361*9880d681SAndroid Build Coastguard Worker        return """\
362*9880d681SAndroid Build Coastguard Workertype = %s
363*9880d681SAndroid Build Coastguard Workername = %s
364*9880d681SAndroid Build Coastguard Workerparent = %s
365*9880d681SAndroid Build Coastguard Workerrequired_libraries = %s
366*9880d681SAndroid Build Coastguard Worker""" % (self.type_name, self.name, self.parent,
367*9880d681SAndroid Build Coastguard Worker       ' '.join(self.required_libraries))
368*9880d681SAndroid Build Coastguard Worker
369*9880d681SAndroid Build Coastguard Workerclass BuildToolComponentInfo(ToolComponentInfo):
370*9880d681SAndroid Build Coastguard Worker    type_name = 'BuildTool'
371*9880d681SAndroid Build Coastguard Worker
372*9880d681SAndroid Build Coastguard Worker    @staticmethod
373*9880d681SAndroid Build Coastguard Worker    def parse(subpath, items):
374*9880d681SAndroid Build Coastguard Worker        kwargs = ComponentInfo.parse_items(items)
375*9880d681SAndroid Build Coastguard Worker        kwargs['required_libraries'] = items.get_list('required_libraries')
376*9880d681SAndroid Build Coastguard Worker        return BuildToolComponentInfo(subpath, **kwargs)
377*9880d681SAndroid Build Coastguard Worker
378*9880d681SAndroid Build Coastguard Worker###
379*9880d681SAndroid Build Coastguard Worker
380*9880d681SAndroid Build Coastguard Workerclass IniFormatParser(dict):
381*9880d681SAndroid Build Coastguard Worker    def get_list(self, key):
382*9880d681SAndroid Build Coastguard Worker        # Check if the value is defined.
383*9880d681SAndroid Build Coastguard Worker        value = self.get(key)
384*9880d681SAndroid Build Coastguard Worker        if value is None:
385*9880d681SAndroid Build Coastguard Worker            return []
386*9880d681SAndroid Build Coastguard Worker
387*9880d681SAndroid Build Coastguard Worker        # Lists are just whitespace separated strings.
388*9880d681SAndroid Build Coastguard Worker        return value.split()
389*9880d681SAndroid Build Coastguard Worker
390*9880d681SAndroid Build Coastguard Worker    def get_optional_string(self, key):
391*9880d681SAndroid Build Coastguard Worker        value = self.get_list(key)
392*9880d681SAndroid Build Coastguard Worker        if not value:
393*9880d681SAndroid Build Coastguard Worker            return None
394*9880d681SAndroid Build Coastguard Worker        if len(value) > 1:
395*9880d681SAndroid Build Coastguard Worker            raise ParseError("multiple values for scalar key: %r" % key)
396*9880d681SAndroid Build Coastguard Worker        return value[0]
397*9880d681SAndroid Build Coastguard Worker
398*9880d681SAndroid Build Coastguard Worker    def get_string(self, key):
399*9880d681SAndroid Build Coastguard Worker        value = self.get_optional_string(key)
400*9880d681SAndroid Build Coastguard Worker        if not value:
401*9880d681SAndroid Build Coastguard Worker            raise ParseError("missing value for required string: %r" % key)
402*9880d681SAndroid Build Coastguard Worker        return value
403*9880d681SAndroid Build Coastguard Worker
404*9880d681SAndroid Build Coastguard Worker    def get_optional_bool(self, key, default = None):
405*9880d681SAndroid Build Coastguard Worker        value = self.get_optional_string(key)
406*9880d681SAndroid Build Coastguard Worker        if not value:
407*9880d681SAndroid Build Coastguard Worker            return default
408*9880d681SAndroid Build Coastguard Worker        if value not in ('0', '1'):
409*9880d681SAndroid Build Coastguard Worker            raise ParseError("invalid value(%r) for boolean property: %r" % (
410*9880d681SAndroid Build Coastguard Worker                    value, key))
411*9880d681SAndroid Build Coastguard Worker        return bool(int(value))
412*9880d681SAndroid Build Coastguard Worker
413*9880d681SAndroid Build Coastguard Worker    def get_bool(self, key):
414*9880d681SAndroid Build Coastguard Worker        value = self.get_optional_bool(key)
415*9880d681SAndroid Build Coastguard Worker        if value is None:
416*9880d681SAndroid Build Coastguard Worker            raise ParseError("missing value for required boolean: %r" % key)
417*9880d681SAndroid Build Coastguard Worker        return value
418*9880d681SAndroid Build Coastguard Worker
419*9880d681SAndroid Build Coastguard Worker_component_type_map = dict(
420*9880d681SAndroid Build Coastguard Worker    (t.type_name, t)
421*9880d681SAndroid Build Coastguard Worker    for t in (GroupComponentInfo,
422*9880d681SAndroid Build Coastguard Worker              LibraryComponentInfo, LibraryGroupComponentInfo,
423*9880d681SAndroid Build Coastguard Worker              ToolComponentInfo, BuildToolComponentInfo,
424*9880d681SAndroid Build Coastguard Worker              TargetGroupComponentInfo, OptionalLibraryComponentInfo))
425*9880d681SAndroid Build Coastguard Workerdef load_from_path(path, subpath):
426*9880d681SAndroid Build Coastguard Worker    # Load the LLVMBuild.txt file as an .ini format file.
427*9880d681SAndroid Build Coastguard Worker    parser = configparser.RawConfigParser()
428*9880d681SAndroid Build Coastguard Worker    parser.read(path)
429*9880d681SAndroid Build Coastguard Worker
430*9880d681SAndroid Build Coastguard Worker    # Extract the common section.
431*9880d681SAndroid Build Coastguard Worker    if parser.has_section("common"):
432*9880d681SAndroid Build Coastguard Worker        common = IniFormatParser(parser.items("common"))
433*9880d681SAndroid Build Coastguard Worker        parser.remove_section("common")
434*9880d681SAndroid Build Coastguard Worker    else:
435*9880d681SAndroid Build Coastguard Worker        common = IniFormatParser({})
436*9880d681SAndroid Build Coastguard Worker
437*9880d681SAndroid Build Coastguard Worker    return common, _read_components_from_parser(parser, path, subpath)
438*9880d681SAndroid Build Coastguard Worker
439*9880d681SAndroid Build Coastguard Workerdef _read_components_from_parser(parser, path, subpath):
440*9880d681SAndroid Build Coastguard Worker    # We load each section which starts with 'component' as a distinct component
441*9880d681SAndroid Build Coastguard Worker    # description (so multiple components can be described in one file).
442*9880d681SAndroid Build Coastguard Worker    for section in parser.sections():
443*9880d681SAndroid Build Coastguard Worker        if not section.startswith('component'):
444*9880d681SAndroid Build Coastguard Worker            # We don't expect arbitrary sections currently, warn the user.
445*9880d681SAndroid Build Coastguard Worker            warning("ignoring unknown section %r in %r" % (section, path))
446*9880d681SAndroid Build Coastguard Worker            continue
447*9880d681SAndroid Build Coastguard Worker
448*9880d681SAndroid Build Coastguard Worker        # Determine the type of the component to instantiate.
449*9880d681SAndroid Build Coastguard Worker        if not parser.has_option(section, 'type'):
450*9880d681SAndroid Build Coastguard Worker            fatal("invalid component %r in %r: %s" % (
451*9880d681SAndroid Build Coastguard Worker                    section, path, "no component type"))
452*9880d681SAndroid Build Coastguard Worker
453*9880d681SAndroid Build Coastguard Worker        type_name = parser.get(section, 'type')
454*9880d681SAndroid Build Coastguard Worker        type_class = _component_type_map.get(type_name)
455*9880d681SAndroid Build Coastguard Worker        if type_class is None:
456*9880d681SAndroid Build Coastguard Worker            fatal("invalid component %r in %r: %s" % (
457*9880d681SAndroid Build Coastguard Worker                    section, path, "invalid component type: %r" % type_name))
458*9880d681SAndroid Build Coastguard Worker
459*9880d681SAndroid Build Coastguard Worker        # Instantiate the component based on the remaining values.
460*9880d681SAndroid Build Coastguard Worker        try:
461*9880d681SAndroid Build Coastguard Worker            info = type_class.parse(subpath,
462*9880d681SAndroid Build Coastguard Worker                                    IniFormatParser(parser.items(section)))
463*9880d681SAndroid Build Coastguard Worker        except TypeError:
464*9880d681SAndroid Build Coastguard Worker            print >>sys.stderr, "error: invalid component %r in %r: %s" % (
465*9880d681SAndroid Build Coastguard Worker                section, path, "unable to instantiate: %r" % type_name)
466*9880d681SAndroid Build Coastguard Worker            import traceback
467*9880d681SAndroid Build Coastguard Worker            traceback.print_exc()
468*9880d681SAndroid Build Coastguard Worker            raise SystemExit(1)
469*9880d681SAndroid Build Coastguard Worker        except ParseError:
470*9880d681SAndroid Build Coastguard Worker            e = sys.exc_info()[1]
471*9880d681SAndroid Build Coastguard Worker            fatal("unable to load component %r in %r: %s" % (
472*9880d681SAndroid Build Coastguard Worker                    section, path, e.message))
473*9880d681SAndroid Build Coastguard Worker
474*9880d681SAndroid Build Coastguard Worker        info._source_path = path
475*9880d681SAndroid Build Coastguard Worker        yield info
476