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 def set_parent_instance(self, parent):
46 assert parent.name == self.parent, "Unexpected parent!"
47 self.parent_instance = parent
48 self.parent_instance.children.append(self)
50 def get_component_references(self):
51 """get_component_references() -> iter
53 Return an iterator over the named references to other components from
54 this object. Items are of the form (reference-type, component-name).
57 # Parent references are handled specially.
58 for r in self.dependencies:
59 yield ('dependency', r)
61 def get_llvmbuild_fragment(self):
64 class GroupComponentInfo(ComponentInfo):
66 Group components have no semantics as far as the build system are concerned,
67 but exist to help organize other components into a logical tree structure.
73 def parse(subpath, items):
74 kwargs = ComponentInfo.parse_items(items, has_dependencies = False)
75 return GroupComponentInfo(subpath, **kwargs)
77 def __init__(self, subpath, name, parent):
78 ComponentInfo.__init__(self, subpath, name, [], parent)
80 def get_llvmbuild_fragment(self):
81 result = StringIO.StringIO()
82 print >>result, 'type = %s' % self.type_name
83 print >>result, 'name = %s' % self.name
84 print >>result, 'parent = %s' % self.parent
85 return result.getvalue()
87 class LibraryComponentInfo(ComponentInfo):
91 def parse(subpath, items):
92 kwargs = ComponentInfo.parse_items(items)
93 kwargs['library_name'] = items.get_optional_string('library_name')
94 kwargs['required_libraries'] = items.get_list('required_libraries')
95 kwargs['add_to_library_groups'] = items.get_list(
96 'add_to_library_groups')
97 return LibraryComponentInfo(subpath, **kwargs)
99 def __init__(self, subpath, name, dependencies, parent, library_name,
100 required_libraries, add_to_library_groups):
101 ComponentInfo.__init__(self, subpath, name, dependencies, parent)
103 # If given, the name to use for the library instead of deriving it from
104 # the component name.
105 self.library_name = library_name
107 # The names of the library components which are required when linking
108 # with this component.
109 self.required_libraries = list(required_libraries)
111 # The names of the library group components this component should be
112 # considered part of.
113 self.add_to_library_groups = list(add_to_library_groups)
115 def get_component_references(self):
116 for r in ComponentInfo.get_component_references(self):
118 for r in self.required_libraries:
119 yield ('required library', r)
120 for r in self.add_to_library_groups:
121 yield ('library group', r)
123 def get_llvmbuild_fragment(self):
124 result = StringIO.StringIO()
125 print >>result, 'type = %s' % self.type_name
126 print >>result, 'name = %s' % self.name
127 print >>result, 'parent = %s' % self.parent
128 if self.library_name is not None:
129 print >>result, 'library_name = %s' % self.library_name
130 if self.required_libraries:
131 print >>result, 'required_libraries = %s' % ' '.join(
132 self.required_libraries)
133 if self.add_to_library_groups:
134 print >>result, 'add_to_library_groups = %s' % ' '.join(
135 self.add_to_library_groups)
136 return result.getvalue()
138 def get_library_name(self):
139 return self.library_name or self.name
141 def get_llvmconfig_component_name(self):
142 return self.get_library_name().lower()
144 class LibraryGroupComponentInfo(ComponentInfo):
145 type_name = 'LibraryGroup'
148 def parse(subpath, items):
149 kwargs = ComponentInfo.parse_items(items, has_dependencies = False)
150 kwargs['required_libraries'] = items.get_list('required_libraries')
151 kwargs['add_to_library_groups'] = items.get_list(
152 'add_to_library_groups')
153 return LibraryGroupComponentInfo(subpath, **kwargs)
155 def __init__(self, subpath, name, parent, required_libraries = [],
156 add_to_library_groups = []):
157 ComponentInfo.__init__(self, subpath, name, [], parent)
159 # The names of the library components which are required when linking
160 # with this component.
161 self.required_libraries = list(required_libraries)
163 # The names of the library group components this component should be
164 # considered part of.
165 self.add_to_library_groups = list(add_to_library_groups)
167 def get_component_references(self):
168 for r in ComponentInfo.get_component_references(self):
170 for r in self.required_libraries:
171 yield ('required library', r)
172 for r in self.add_to_library_groups:
173 yield ('library group', r)
175 def get_llvmbuild_fragment(self):
176 result = StringIO.StringIO()
177 print >>result, 'type = %s' % self.type_name
178 print >>result, 'name = %s' % self.name
179 print >>result, 'parent = %s' % self.parent
180 if self.required_libraries:
181 print >>result, 'required_libraries = %s' % ' '.join(
182 self.required_libraries)
183 if self.add_to_library_groups:
184 print >>result, 'add_to_library_groups = %s' % ' '.join(
185 self.add_to_library_groups)
186 return result.getvalue()
188 def get_llvmconfig_component_name(self):
189 return self.name.lower()
191 class TargetGroupComponentInfo(ComponentInfo):
192 type_name = 'TargetGroup'
195 def parse(subpath, items):
196 kwargs = ComponentInfo.parse_items(items, has_dependencies = False)
197 kwargs['required_libraries'] = items.get_list('required_libraries')
198 kwargs['add_to_library_groups'] = items.get_list(
199 'add_to_library_groups')
200 kwargs['has_jit'] = items.get_optional_bool('has_jit', False)
201 return TargetGroupComponentInfo(subpath, **kwargs)
203 def __init__(self, subpath, name, parent, required_libraries = [],
204 add_to_library_groups = [], has_jit = False):
205 ComponentInfo.__init__(self, subpath, name, [], parent)
207 # The names of the library components which are required when linking
208 # with this component.
209 self.required_libraries = list(required_libraries)
211 # The names of the library group components this component should be
212 # considered part of.
213 self.add_to_library_groups = list(add_to_library_groups)
215 # Whether or not this target supports the JIT.
216 self.has_jit = bool(has_jit)
218 # Whether or not this target is enabled. This is set in response to
219 # configuration parameters.
222 def get_component_references(self):
223 for r in ComponentInfo.get_component_references(self):
225 for r in self.required_libraries:
226 yield ('required library', r)
227 for r in self.add_to_library_groups:
228 yield ('library group', r)
230 def get_llvmbuild_fragment(self):
231 result = StringIO.StringIO()
232 print >>result, 'type = %s' % self.type_name
233 print >>result, 'name = %s' % self.name
234 print >>result, 'parent = %s' % self.parent
235 if self.required_libraries:
236 print >>result, 'required_libraries = %s' % ' '.join(
237 self.required_libraries)
238 if self.add_to_library_groups:
239 print >>result, 'add_to_library_groups = %s' % ' '.join(
240 self.add_to_library_groups)
242 print >>result, 'has_jit = %s' % ' '.join(
244 return result.getvalue()
246 def get_llvmconfig_component_name(self):
247 return self.name.lower()
249 class ToolComponentInfo(ComponentInfo):
253 def parse(subpath, items):
254 kwargs = ComponentInfo.parse_items(items)
255 kwargs['required_libraries'] = items.get_list('required_libraries')
256 return ToolComponentInfo(subpath, **kwargs)
258 def __init__(self, subpath, name, dependencies, parent,
260 ComponentInfo.__init__(self, subpath, name, dependencies, parent)
262 # The names of the library components which are required to link this
264 self.required_libraries = list(required_libraries)
266 def get_component_references(self):
267 for r in ComponentInfo.get_component_references(self):
269 for r in self.required_libraries:
270 yield ('required library', r)
272 def get_llvmbuild_fragment(self):
273 result = StringIO.StringIO()
274 print >>result, 'type = %s' % self.type_name
275 print >>result, 'name = %s' % self.name
276 print >>result, 'parent = %s' % self.parent
277 print >>result, 'required_libraries = %s' % ' '.join(
278 self.required_libraries)
279 return result.getvalue()
281 class BuildToolComponentInfo(ToolComponentInfo):
282 type_name = 'BuildTool'
285 def parse(subpath, items):
286 kwargs = ComponentInfo.parse_items(items)
287 kwargs['required_libraries'] = items.get_list('required_libraries')
288 return BuildToolComponentInfo(subpath, **kwargs)
292 class IniFormatParser(dict):
293 def get_list(self, key):
294 # Check if the value is defined.
295 value = self.get(key)
299 # Lists are just whitespace separated strings.
302 def get_optional_string(self, key):
303 value = self.get_list(key)
307 raise ParseError("multiple values for scalar key: %r" % key)
310 def get_string(self, key):
311 value = self.get_optional_string(key)
313 raise ParseError("missing value for required string: %r" % key)
316 def get_optional_bool(self, key, default = None):
317 value = self.get_optional_string(key)
320 if value not in ('0', '1'):
321 raise ParseError("invalid value(%r) for boolean property: %r" % (
323 return bool(int(value))
325 def get_bool(self, key):
326 value = self.get_optional_bool(key)
328 raise ParseError("missing value for required boolean: %r" % key)
331 _component_type_map = dict(
333 for t in (GroupComponentInfo,
334 LibraryComponentInfo, LibraryGroupComponentInfo,
335 ToolComponentInfo, BuildToolComponentInfo,
336 TargetGroupComponentInfo))
337 def load_from_path(path, subpath):
338 # Load the LLVMBuild.txt file as an .ini format file.
339 parser = ConfigParser.RawConfigParser()
342 # We load each section which starts with 'component' as a distinct component
343 # description (so multiple components can be described in one file).
344 for section in parser.sections():
345 if not section.startswith('component'):
346 # We don't expect arbitrary sections currently, warn the user.
347 warning("ignoring unknown section %r in %r" % (section, path))
350 # Determine the type of the component to instantiate.
351 if not parser.has_option(section, 'type'):
352 fatal("invalid component %r in %r: %s" % (
353 section, path, "no component type"))
355 type_name = parser.get(section, 'type')
356 type_class = _component_type_map.get(type_name)
357 if type_class is None:
358 fatal("invalid component %r in %r: %s" % (
359 section, path, "invalid component type: %r" % type_name))
361 # Instantiate the component based on the remaining values.
363 info = type_class.parse(subpath,
364 IniFormatParser(parser.items(section)))
366 print >>sys.stderr, "error: invalid component %r in %r: %s" % (
367 section, path, "unable to instantiate: %r" % type_name)
369 traceback.print_exc()
372 fatal("unable to load component %r in %r: %s" % (
373 section, path, e.message))