2 Descriptor objects for entities that are part of the LLVM project.
11 class ParseError(Exception):
14 class ComponentInfo(object):
16 Base class for component descriptions.
22 def parse_items(items, has_dependencies = True):
24 kwargs['name'] = items.get_string('name')
25 kwargs['parent'] = items.get_optional_string('parent')
27 kwargs['dependencies'] = items.get_list('dependencies')
30 def __init__(self, subpath, name, dependencies, parent):
31 if not subpath.startswith('/'):
32 raise ValueError,"invalid subpath: %r" % subpath
33 self.subpath = subpath
35 self.dependencies = list(dependencies)
37 # The name of the parent component to logically group this component
41 # The parent instance, once loaded.
42 self.parent_instance = None
45 # The original source path.
46 self._source_path = None
48 def set_parent_instance(self, parent):
49 assert parent.name == self.parent, "Unexpected parent!"
50 self.parent_instance = parent
51 self.parent_instance.children.append(self)
53 def get_component_references(self):
54 """get_component_references() -> iter
56 Return an iterator over the named references to other components from
57 this object. Items are of the form (reference-type, component-name).
60 # Parent references are handled specially.
61 for r in self.dependencies:
62 yield ('dependency', r)
64 def get_llvmbuild_fragment(self):
67 class GroupComponentInfo(ComponentInfo):
69 Group components have no semantics as far as the build system are concerned,
70 but exist to help organize other components into a logical tree structure.
76 def parse(subpath, items):
77 kwargs = ComponentInfo.parse_items(items, has_dependencies = False)
78 return GroupComponentInfo(subpath, **kwargs)
80 def __init__(self, subpath, name, parent):
81 ComponentInfo.__init__(self, subpath, name, [], parent)
83 def get_llvmbuild_fragment(self):
84 result = StringIO.StringIO()
85 print >>result, 'type = %s' % self.type_name
86 print >>result, 'name = %s' % self.name
87 print >>result, 'parent = %s' % self.parent
88 return result.getvalue()
90 class LibraryComponentInfo(ComponentInfo):
94 def parse(subpath, items):
95 kwargs = ComponentInfo.parse_items(items)
96 kwargs['library_name'] = items.get_optional_string('library_name')
97 kwargs['required_libraries'] = items.get_list('required_libraries')
98 kwargs['add_to_library_groups'] = items.get_list(
99 'add_to_library_groups')
100 return LibraryComponentInfo(subpath, **kwargs)
102 def __init__(self, subpath, name, dependencies, parent, library_name,
103 required_libraries, add_to_library_groups):
104 ComponentInfo.__init__(self, subpath, name, dependencies, parent)
106 # If given, the name to use for the library instead of deriving it from
107 # the component name.
108 self.library_name = library_name
110 # The names of the library components which are required when linking
111 # with this component.
112 self.required_libraries = list(required_libraries)
114 # The names of the library group components this component should be
115 # considered part of.
116 self.add_to_library_groups = list(add_to_library_groups)
118 def get_component_references(self):
119 for r in ComponentInfo.get_component_references(self):
121 for r in self.required_libraries:
122 yield ('required library', r)
123 for r in self.add_to_library_groups:
124 yield ('library group', r)
126 def get_llvmbuild_fragment(self):
127 result = StringIO.StringIO()
128 print >>result, 'type = %s' % self.type_name
129 print >>result, 'name = %s' % self.name
130 print >>result, 'parent = %s' % self.parent
131 if self.library_name is not None:
132 print >>result, 'library_name = %s' % self.library_name
133 if self.required_libraries:
134 print >>result, 'required_libraries = %s' % ' '.join(
135 self.required_libraries)
136 if self.add_to_library_groups:
137 print >>result, 'add_to_library_groups = %s' % ' '.join(
138 self.add_to_library_groups)
139 return result.getvalue()
141 def get_library_name(self):
142 return self.library_name or self.name
144 def get_prefixed_library_name(self):
146 get_prefixed_library_name() -> str
148 Return the library name prefixed by the project name. This is generally
149 what the library name will be on disk.
152 basename = self.get_library_name()
154 # FIXME: We need to get the prefix information from an explicit project
155 # object, or something.
156 if basename in ('gtest', 'gtest_main'):
159 return 'LLVM%s' % basename
161 def get_llvmconfig_component_name(self):
162 return self.get_library_name().lower()
164 class LibraryGroupComponentInfo(ComponentInfo):
165 type_name = 'LibraryGroup'
168 def parse(subpath, items):
169 kwargs = ComponentInfo.parse_items(items, has_dependencies = False)
170 kwargs['required_libraries'] = items.get_list('required_libraries')
171 kwargs['add_to_library_groups'] = items.get_list(
172 'add_to_library_groups')
173 return LibraryGroupComponentInfo(subpath, **kwargs)
175 def __init__(self, subpath, name, parent, required_libraries = [],
176 add_to_library_groups = []):
177 ComponentInfo.__init__(self, subpath, name, [], parent)
179 # The names of the library components which are required when linking
180 # with this component.
181 self.required_libraries = list(required_libraries)
183 # The names of the library group components this component should be
184 # considered part of.
185 self.add_to_library_groups = list(add_to_library_groups)
187 def get_component_references(self):
188 for r in ComponentInfo.get_component_references(self):
190 for r in self.required_libraries:
191 yield ('required library', r)
192 for r in self.add_to_library_groups:
193 yield ('library group', r)
195 def get_llvmbuild_fragment(self):
196 result = StringIO.StringIO()
197 print >>result, 'type = %s' % self.type_name
198 print >>result, 'name = %s' % self.name
199 print >>result, 'parent = %s' % self.parent
200 if self.required_libraries:
201 print >>result, 'required_libraries = %s' % ' '.join(
202 self.required_libraries)
203 if self.add_to_library_groups:
204 print >>result, 'add_to_library_groups = %s' % ' '.join(
205 self.add_to_library_groups)
206 return result.getvalue()
208 def get_llvmconfig_component_name(self):
209 return self.name.lower()
211 class TargetGroupComponentInfo(ComponentInfo):
212 type_name = 'TargetGroup'
215 def parse(subpath, items):
216 kwargs = ComponentInfo.parse_items(items, has_dependencies = False)
217 kwargs['required_libraries'] = items.get_list('required_libraries')
218 kwargs['add_to_library_groups'] = items.get_list(
219 'add_to_library_groups')
220 kwargs['has_jit'] = items.get_optional_bool('has_jit', False)
221 kwargs['has_asmprinter'] = items.get_optional_bool('has_asmprinter',
223 kwargs['has_asmparser'] = items.get_optional_bool('has_asmparser',
225 kwargs['has_disassembler'] = items.get_optional_bool('has_disassembler',
227 return TargetGroupComponentInfo(subpath, **kwargs)
229 def __init__(self, subpath, name, parent, required_libraries = [],
230 add_to_library_groups = [], has_jit = False,
231 has_asmprinter = False, has_asmparser = False,
232 has_disassembler = False):
233 ComponentInfo.__init__(self, subpath, name, [], parent)
235 # The names of the library components which are required when linking
236 # with this component.
237 self.required_libraries = list(required_libraries)
239 # The names of the library group components this component should be
240 # considered part of.
241 self.add_to_library_groups = list(add_to_library_groups)
243 # Whether or not this target supports the JIT.
244 self.has_jit = bool(has_jit)
246 # Whether or not this target defines an assembly printer.
247 self.has_asmprinter = bool(has_asmprinter)
249 # Whether or not this target defines an assembly parser.
250 self.has_asmparser = bool(has_asmparser)
252 # Whether or not this target defines an disassembler.
253 self.has_disassembler = bool(has_disassembler)
255 # Whether or not this target is enabled. This is set in response to
256 # configuration parameters.
259 def get_component_references(self):
260 for r in ComponentInfo.get_component_references(self):
262 for r in self.required_libraries:
263 yield ('required library', r)
264 for r in self.add_to_library_groups:
265 yield ('library group', r)
267 def get_llvmbuild_fragment(self):
268 result = StringIO.StringIO()
269 print >>result, 'type = %s' % self.type_name
270 print >>result, 'name = %s' % self.name
271 print >>result, 'parent = %s' % self.parent
272 if self.required_libraries:
273 print >>result, 'required_libraries = %s' % ' '.join(
274 self.required_libraries)
275 if self.add_to_library_groups:
276 print >>result, 'add_to_library_groups = %s' % ' '.join(
277 self.add_to_library_groups)
278 for bool_key in ('has_asmparser', 'has_asmprinter', 'has_disassembler',
280 if getattr(self, bool_key):
281 print >>result, '%s = 1' % (bool_key,)
282 return result.getvalue()
284 def get_llvmconfig_component_name(self):
285 return self.name.lower()
287 class ToolComponentInfo(ComponentInfo):
291 def parse(subpath, items):
292 kwargs = ComponentInfo.parse_items(items)
293 kwargs['required_libraries'] = items.get_list('required_libraries')
294 return ToolComponentInfo(subpath, **kwargs)
296 def __init__(self, subpath, name, dependencies, parent,
298 ComponentInfo.__init__(self, subpath, name, dependencies, parent)
300 # The names of the library components which are required to link this
302 self.required_libraries = list(required_libraries)
304 def get_component_references(self):
305 for r in ComponentInfo.get_component_references(self):
307 for r in self.required_libraries:
308 yield ('required library', r)
310 def get_llvmbuild_fragment(self):
311 result = StringIO.StringIO()
312 print >>result, 'type = %s' % self.type_name
313 print >>result, 'name = %s' % self.name
314 print >>result, 'parent = %s' % self.parent
315 print >>result, 'required_libraries = %s' % ' '.join(
316 self.required_libraries)
317 return result.getvalue()
319 class BuildToolComponentInfo(ToolComponentInfo):
320 type_name = 'BuildTool'
323 def parse(subpath, items):
324 kwargs = ComponentInfo.parse_items(items)
325 kwargs['required_libraries'] = items.get_list('required_libraries')
326 return BuildToolComponentInfo(subpath, **kwargs)
330 class IniFormatParser(dict):
331 def get_list(self, key):
332 # Check if the value is defined.
333 value = self.get(key)
337 # Lists are just whitespace separated strings.
340 def get_optional_string(self, key):
341 value = self.get_list(key)
345 raise ParseError("multiple values for scalar key: %r" % key)
348 def get_string(self, key):
349 value = self.get_optional_string(key)
351 raise ParseError("missing value for required string: %r" % key)
354 def get_optional_bool(self, key, default = None):
355 value = self.get_optional_string(key)
358 if value not in ('0', '1'):
359 raise ParseError("invalid value(%r) for boolean property: %r" % (
361 return bool(int(value))
363 def get_bool(self, key):
364 value = self.get_optional_bool(key)
366 raise ParseError("missing value for required boolean: %r" % key)
369 _component_type_map = dict(
371 for t in (GroupComponentInfo,
372 LibraryComponentInfo, LibraryGroupComponentInfo,
373 ToolComponentInfo, BuildToolComponentInfo,
374 TargetGroupComponentInfo))
375 def load_from_path(path, subpath):
376 # Load the LLVMBuild.txt file as an .ini format file.
377 parser = ConfigParser.RawConfigParser()
380 # We load each section which starts with 'component' as a distinct component
381 # description (so multiple components can be described in one file).
382 for section in parser.sections():
383 if not section.startswith('component'):
384 # We don't expect arbitrary sections currently, warn the user.
385 warning("ignoring unknown section %r in %r" % (section, path))
388 # Determine the type of the component to instantiate.
389 if not parser.has_option(section, 'type'):
390 fatal("invalid component %r in %r: %s" % (
391 section, path, "no component type"))
393 type_name = parser.get(section, 'type')
394 type_class = _component_type_map.get(type_name)
395 if type_class is None:
396 fatal("invalid component %r in %r: %s" % (
397 section, path, "invalid component type: %r" % type_name))
399 # Instantiate the component based on the remaining values.
401 info = type_class.parse(subpath,
402 IniFormatParser(parser.items(section)))
404 print >>sys.stderr, "error: invalid component %r in %r: %s" % (
405 section, path, "unable to instantiate: %r" % type_name)
407 traceback.print_exc()
410 fatal("unable to load component %r in %r: %s" % (
411 section, path, e.message))
413 info._source_path = path