Make IntelJITEvents and OProfileJIT as optional libraries and add
[oota-llvm.git] / utils / llvm-build / llvmbuild / componentinfo.py
index 3ea80016a119a4c3a695ef5e7955670d12f719f1..737b857dfbbafd17ffcf5941b442906d6eed50a9 100644 (file)
@@ -42,6 +42,13 @@ class ComponentInfo(object):
         self.parent_instance = None
         self.children = []
 
+        # The original source path.
+        self._source_path = None
+
+        # A flag to mark "special" components which have some amount of magic
+        # handling (generally based on command line options).
+        self._is_special_group = False
+
     def set_parent_instance(self, parent):
         assert parent.name == self.parent, "Unexpected parent!"
         self.parent_instance = parent
@@ -88,12 +95,17 @@ class LibraryComponentInfo(ComponentInfo):
     type_name = 'Library'
 
     @staticmethod
-    def parse(subpath, items):
+    def parse_items(items):
         kwargs = ComponentInfo.parse_items(items)
         kwargs['library_name'] = items.get_optional_string('library_name')
         kwargs['required_libraries'] = items.get_list('required_libraries')
         kwargs['add_to_library_groups'] = items.get_list(
             'add_to_library_groups')
+        return kwargs
+
+    @staticmethod
+    def parse(subpath, items):
+        kwargs = LibraryComponentInfo.parse_items(items)
         return LibraryComponentInfo(subpath, **kwargs)
 
     def __init__(self, subpath, name, dependencies, parent, library_name,
@@ -135,6 +147,43 @@ class LibraryComponentInfo(ComponentInfo):
                 self.add_to_library_groups)
         return result.getvalue()
 
+    def get_library_name(self):
+        return self.library_name or self.name
+
+    def get_prefixed_library_name(self):
+        """
+        get_prefixed_library_name() -> str
+
+        Return the library name prefixed by the project name. This is generally
+        what the library name will be on disk.
+        """
+
+        basename = self.get_library_name()
+
+        # FIXME: We need to get the prefix information from an explicit project
+        # object, or something.
+        if basename in ('gtest', 'gtest_main'):
+            return basename
+
+        return 'LLVM%s' % basename
+
+    def get_llvmconfig_component_name(self):
+        return self.get_library_name().lower()
+
+class OptionalLibraryComponentInfo(LibraryComponentInfo):
+    type_name = "OptionalLibrary"
+
+    @staticmethod
+    def parse(subpath, items):
+      kwargs = LibraryComponentInfo.parse_items(items)
+      return OptionalLibraryComponentInfo(subpath, **kwargs)
+
+    def __init__(self, subpath, name, dependencies, parent, library_name,
+                 required_libraries, add_to_library_groups):
+      LibraryComponentInfo.__init__(self, subpath, name, dependencies, parent,
+                                    library_name, required_libraries,
+                                    add_to_library_groups)
+
 class LibraryGroupComponentInfo(ComponentInfo):
     type_name = 'LibraryGroup'
 
@@ -166,6 +215,78 @@ class LibraryGroupComponentInfo(ComponentInfo):
         for r in self.add_to_library_groups:
             yield ('library group', r)
 
+    def get_llvmbuild_fragment(self):
+        result = StringIO.StringIO()
+        print >>result, 'type = %s' % self.type_name
+        print >>result, 'name = %s' % self.name
+        print >>result, 'parent = %s' % self.parent
+        if self.required_libraries and not self._is_special_group:
+            print >>result, 'required_libraries = %s' % ' '.join(
+                self.required_libraries)
+        if self.add_to_library_groups:
+            print >>result, 'add_to_library_groups = %s' % ' '.join(
+                self.add_to_library_groups)
+        return result.getvalue()
+
+    def get_llvmconfig_component_name(self):
+        return self.name.lower()
+
+class TargetGroupComponentInfo(ComponentInfo):
+    type_name = 'TargetGroup'
+
+    @staticmethod
+    def parse(subpath, items):
+        kwargs = ComponentInfo.parse_items(items, has_dependencies = False)
+        kwargs['required_libraries'] = items.get_list('required_libraries')
+        kwargs['add_to_library_groups'] = items.get_list(
+            'add_to_library_groups')
+        kwargs['has_jit'] = items.get_optional_bool('has_jit', False)
+        kwargs['has_asmprinter'] = items.get_optional_bool('has_asmprinter',
+                                                           False)
+        kwargs['has_asmparser'] = items.get_optional_bool('has_asmparser',
+                                                          False)
+        kwargs['has_disassembler'] = items.get_optional_bool('has_disassembler',
+                                                             False)
+        return TargetGroupComponentInfo(subpath, **kwargs)
+
+    def __init__(self, subpath, name, parent, required_libraries = [],
+                 add_to_library_groups = [], has_jit = False,
+                 has_asmprinter = False, has_asmparser = False,
+                 has_disassembler = False):
+        ComponentInfo.__init__(self, subpath, name, [], parent)
+
+        # The names of the library components which are required when linking
+        # with this component.
+        self.required_libraries = list(required_libraries)
+
+        # The names of the library group components this component should be
+        # considered part of.
+        self.add_to_library_groups = list(add_to_library_groups)
+
+        # Whether or not this target supports the JIT.
+        self.has_jit = bool(has_jit)
+
+        # Whether or not this target defines an assembly printer.
+        self.has_asmprinter = bool(has_asmprinter)
+
+        # Whether or not this target defines an assembly parser.
+        self.has_asmparser = bool(has_asmparser)
+
+        # Whether or not this target defines an disassembler.
+        self.has_disassembler = bool(has_disassembler)
+
+        # Whether or not this target is enabled. This is set in response to
+        # configuration parameters.
+        self.enabled = False
+
+    def get_component_references(self):
+        for r in ComponentInfo.get_component_references(self):
+            yield r
+        for r in self.required_libraries:
+            yield ('required library', r)
+        for r in self.add_to_library_groups:
+            yield ('library group', r)
+
     def get_llvmbuild_fragment(self):
         result = StringIO.StringIO()
         print >>result, 'type = %s' % self.type_name
@@ -177,8 +298,15 @@ class LibraryGroupComponentInfo(ComponentInfo):
         if self.add_to_library_groups:
             print >>result, 'add_to_library_groups = %s' % ' '.join(
                 self.add_to_library_groups)
+        for bool_key in ('has_asmparser', 'has_asmprinter', 'has_disassembler',
+                         'has_jit'):
+            if getattr(self, bool_key):
+                print >>result, '%s = 1' % (bool_key,)
         return result.getvalue()
 
+    def get_llvmconfig_component_name(self):
+        return self.name.lower()
+
 class ToolComponentInfo(ComponentInfo):
     type_name = 'Tool'
 
@@ -246,16 +374,42 @@ class IniFormatParser(dict):
             raise ParseError("missing value for required string: %r" % key)
         return value
 
+    def get_optional_bool(self, key, default = None):
+        value = self.get_optional_string(key)
+        if not value:
+            return default
+        if value not in ('0', '1'):
+            raise ParseError("invalid value(%r) for boolean property: %r" % (
+                    value, key))
+        return bool(int(value))
+
+    def get_bool(self, key):
+        value = self.get_optional_bool(key)
+        if value is None:
+            raise ParseError("missing value for required boolean: %r" % key)
+        return value
+
 _component_type_map = dict(
     (t.type_name, t)
     for t in (GroupComponentInfo,
               LibraryComponentInfo, LibraryGroupComponentInfo,
-              ToolComponentInfo, BuildToolComponentInfo))
+              ToolComponentInfo, BuildToolComponentInfo,
+              TargetGroupComponentInfo, OptionalLibraryComponentInfo))
 def load_from_path(path, subpath):
     # Load the LLVMBuild.txt file as an .ini format file.
     parser = ConfigParser.RawConfigParser()
     parser.read(path)
 
+    # Extract the common section.
+    if parser.has_section("common"):
+        common = IniFormatParser(parser.items("common"))
+        parser.remove_section("common")
+    else:
+        common = IniFormatParser({})
+
+    return common, _read_components_from_parser(parser, path, subpath)
+
+def _read_components_from_parser(parser, path, subpath):
     # We load each section which starts with 'component' as a distinct component
     # description (so multiple components can be described in one file).
     for section in parser.sections():
@@ -289,4 +443,5 @@ def load_from_path(path, subpath):
             fatal("unable to load component %r in %r: %s" % (
                     section, path, e.message))
 
+        info._source_path = path
         yield info