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 class LibraryGroupComponentInfo(ComponentInfo):
139 type_name = 'LibraryGroup'
142 def parse(subpath, items):
143 kwargs = ComponentInfo.parse_items(items, has_dependencies = False)
144 kwargs['required_libraries'] = items.get_list('required_libraries')
145 kwargs['add_to_library_groups'] = items.get_list(
146 'add_to_library_groups')
147 return LibraryGroupComponentInfo(subpath, **kwargs)
149 def __init__(self, subpath, name, parent, required_libraries = [],
150 add_to_library_groups = []):
151 ComponentInfo.__init__(self, subpath, name, [], parent)
153 # The names of the library components which are required when linking
154 # with this component.
155 self.required_libraries = list(required_libraries)
157 # The names of the library group components this component should be
158 # considered part of.
159 self.add_to_library_groups = list(add_to_library_groups)
161 def get_component_references(self):
162 for r in ComponentInfo.get_component_references(self):
164 for r in self.required_libraries:
165 yield ('required library', r)
166 for r in self.add_to_library_groups:
167 yield ('library group', r)
169 def get_llvmbuild_fragment(self):
170 result = StringIO.StringIO()
171 print >>result, 'type = %s' % self.type_name
172 print >>result, 'name = %s' % self.name
173 print >>result, 'parent = %s' % self.parent
174 if self.required_libraries:
175 print >>result, 'required_libraries = %s' % ' '.join(
176 self.required_libraries)
177 if self.add_to_library_groups:
178 print >>result, 'add_to_library_groups = %s' % ' '.join(
179 self.add_to_library_groups)
180 return result.getvalue()
182 class ToolComponentInfo(ComponentInfo):
186 def parse(subpath, items):
187 kwargs = ComponentInfo.parse_items(items)
188 kwargs['required_libraries'] = items.get_list('required_libraries')
189 return ToolComponentInfo(subpath, **kwargs)
191 def __init__(self, subpath, name, dependencies, parent,
193 ComponentInfo.__init__(self, subpath, name, dependencies, parent)
195 # The names of the library components which are required to link this
197 self.required_libraries = list(required_libraries)
199 def get_component_references(self):
200 for r in ComponentInfo.get_component_references(self):
202 for r in self.required_libraries:
203 yield ('required library', r)
205 def get_llvmbuild_fragment(self):
206 result = StringIO.StringIO()
207 print >>result, 'type = %s' % self.type_name
208 print >>result, 'name = %s' % self.name
209 print >>result, 'parent = %s' % self.parent
210 print >>result, 'required_libraries = %s' % ' '.join(
211 self.required_libraries)
212 return result.getvalue()
214 class BuildToolComponentInfo(ToolComponentInfo):
215 type_name = 'BuildTool'
218 def parse(subpath, items):
219 kwargs = ComponentInfo.parse_items(items)
220 kwargs['required_libraries'] = items.get_list('required_libraries')
221 return BuildToolComponentInfo(subpath, **kwargs)
225 class IniFormatParser(dict):
226 def get_list(self, key):
227 # Check if the value is defined.
228 value = self.get(key)
232 # Lists are just whitespace separated strings.
235 def get_optional_string(self, key):
236 value = self.get_list(key)
240 raise ParseError("multiple values for scalar key: %r" % key)
243 def get_string(self, key):
244 value = self.get_optional_string(key)
246 raise ParseError("missing value for required string: %r" % key)
249 _component_type_map = dict(
251 for t in (GroupComponentInfo,
252 LibraryComponentInfo, LibraryGroupComponentInfo,
253 ToolComponentInfo, BuildToolComponentInfo))
254 def load_from_path(path, subpath):
255 # Load the LLVMBuild.txt file as an .ini format file.
256 parser = ConfigParser.RawConfigParser()
259 # We load each section which starts with 'component' as a distinct component
260 # description (so multiple components can be described in one file).
261 for section in parser.sections():
262 if not section.startswith('component'):
263 # We don't expect arbitrary sections currently, warn the user.
264 warning("ignoring unknown section %r in %r" % (section, path))
267 # Determine the type of the component to instantiate.
268 if not parser.has_option(section, 'type'):
269 fatal("invalid component %r in %r: %s" % (
270 section, path, "no component type"))
272 type_name = parser.get(section, 'type')
273 type_class = _component_type_map.get(type_name)
274 if type_class is None:
275 fatal("invalid component %r in %r: %s" % (
276 section, path, "invalid component type: %r" % type_name))
278 # Instantiate the component based on the remaining values.
280 info = type_class.parse(subpath,
281 IniFormatParser(parser.items(section)))
283 print >>sys.stderr, "error: invalid component %r in %r: %s" % (
284 section, path, "unable to instantiate: %r" % type_name)
286 traceback.print_exc()
289 fatal("unable to load component %r in %r: %s" % (
290 section, path, e.message))