[llvm-commits] [llvm] r143621 - in /llvm/trunk/utils/llvm-build/llvmbuild: componentinfo.py main.py

Daniel Dunbar daniel at zuster.org
Thu Nov 3 10:56:06 PDT 2011


Author: ddunbar
Date: Thu Nov  3 12:56:06 2011
New Revision: 143621

URL: http://llvm.org/viewvc/llvm-project?rev=143621&view=rev
Log:
llvm-build: Sketch code to load LLVMBuild.txt files.

Added:
    llvm/trunk/utils/llvm-build/llvmbuild/componentinfo.py
Modified:
    llvm/trunk/utils/llvm-build/llvmbuild/main.py

Added: llvm/trunk/utils/llvm-build/llvmbuild/componentinfo.py
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/llvm-build/llvmbuild/componentinfo.py?rev=143621&view=auto
==============================================================================
--- llvm/trunk/utils/llvm-build/llvmbuild/componentinfo.py (added)
+++ llvm/trunk/utils/llvm-build/llvmbuild/componentinfo.py Thu Nov  3 12:56:06 2011
@@ -0,0 +1,134 @@
+"""
+Descriptor objects for entities that are part of the LLVM project.
+"""
+
+import ConfigParser
+import sys
+
+class ComponentInfo(object):
+    """
+    Base class for component descriptions.
+    """
+
+    type_name = None
+
+    def __init__(self, subpath, name, dependencies, parent):
+        if not subpath.startswith('/'):
+            raise ValueError,"invalid subpath: %r" % subpath
+        self.subpath = subpath
+        self.name = name
+        self.dependencies = list(dependencies)
+
+        # The name of the parent component to logically group this component
+        # under.
+        self.parent = parent
+
+class GroupComponentInfo(ComponentInfo):
+    """
+    Group components have no semantics as far as the build system are concerned,
+    but exist to help organize other components into a logical tree structure.
+    """
+
+    type_name = 'Group'
+
+    def __init__(self, subpath, name, parent):
+        ComponentInfo.__init__(self, subpath, name, [], parent)
+
+class LibraryComponentInfo(ComponentInfo):
+    type_name = 'Library'
+
+    def __init__(self, subpath, name, dependencies, parent, library_name = None,
+                 required_libraries = [], add_to_library_groups = []):
+        ComponentInfo.__init__(self, subpath, name, dependencies, parent)
+
+        # If given, the name to use for the library instead of deriving it from
+        # the component name.
+        self.library_name = library_name
+
+        # 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)
+
+class LibraryGroupComponentInfo(ComponentInfo):
+    type_name = 'LibraryGroup'
+
+    def __init__(self, subpath, name, parent, required_libraries = [],
+                 add_to_library_groups = []):
+        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)
+
+class ToolComponentInfo(ComponentInfo):
+    type_name = 'Tool'
+
+    def __init__(self, subpath, name, dependencies, parent,
+                 required_libraries = []):
+        ComponentInfo.__init__(self, subpath, name, dependencies, parent)
+
+        # The names of the library components which are required to link this
+        # tool.
+        self.required_libraries = list(required_libraries)
+
+class BuildToolComponentInfo(ToolComponentInfo):
+    type_name = 'BuildTool'
+
+_component_type_map = dict(
+    (t.type_name, t)
+    for t in (GroupComponentInfo,
+              LibraryComponentInfo, LibraryGroupComponentInfo,
+              ToolComponentInfo, BuildToolComponentInfo))
+def load_from_path(path, subpath):
+    # Load the LLVMBuild.txt file as an .ini format file.
+    parser = ConfigParser.RawConfigParser()
+    parser.read(path)
+
+    # 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():
+        if not section.startswith('component'):
+            # We don't expect arbitrary sections currently, warn the user.
+            print >>sys.stderr, "warning: ignoring unknown section %r in %r" % (
+                section, path)
+            continue
+
+        # Load the component that this section describes. For now we just do
+        # this the trivial way by letting python validate the argument
+        # assignment. This is simple, but means users see lame diagnostics. We
+        # should audit the component manually, eventually.
+        if not parser.has_option(section, 'type'):
+            print >>sys.stderr, "error: invalid component %r in %r: %s" % (
+                section, path, "no component type")
+            raise SystemExit, 1
+
+        type_name = parser.get(section, 'type')
+        type_class = _component_type_map.get(type_name)
+        if type_class is None:
+            print >>sys.stderr, "error: invalid component %r in %r: %s" % (
+                section, path, "invalid component type: %r" % type_name)
+            raise SystemExit, 1
+
+        items = dict(parser.items(section))
+        items['subpath'] = subpath
+        items.pop('type')
+
+        # Instantiate the component based on the remaining values.
+        try:
+            info = type_class(**items)
+        except TypeError:
+            print >>sys.stderr, "error: invalid component %r in %r: %s" % (
+                section, path, "unable to instantiate: %r" % type_name)
+            import traceback
+            traceback.print_exc()
+            raise SystemExit, 1
+
+        yield info

Modified: llvm/trunk/utils/llvm-build/llvmbuild/main.py
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/llvm-build/llvmbuild/main.py?rev=143621&r1=143620&r2=143621&view=diff
==============================================================================
--- llvm/trunk/utils/llvm-build/llvmbuild/main.py (original)
+++ llvm/trunk/utils/llvm-build/llvmbuild/main.py Thu Nov  3 12:56:06 2011
@@ -1,11 +1,53 @@
+import pprint
 import os
 
+import componentinfo
+
+class LLVMProjectInfo(object):
+    @staticmethod
+    def load_infos_from_path(llvmbuild_source_root):
+        # FIXME: Implement a simple subpath file list cache, so we don't restat
+        # directories we have already traversed.
+
+        # First, discover all the LLVMBuild.txt files.
+        for dirpath,dirnames,filenames in os.walk(llvmbuild_source_root,
+                                                  followlinks = True):
+            # If there is no LLVMBuild.txt file in a directory, we don't recurse
+            # past it. This is a simple way to prune our search, although it
+            # makes it easy for users to add LLVMBuild.txt files in places they
+            # won't be seen.
+            if 'LLVMBuild.txt' not in filenames:
+                del dirnames[:]
+                continue
+
+            # Otherwise, load the LLVMBuild file in this directory.
+            assert dirpath.startswith(llvmbuild_source_root)
+            subpath = '/' + dirpath[len(llvmbuild_source_root)+1:]
+            llvmbuild_path = os.path.join(dirpath, 'LLVMBuild.txt')
+            for info in componentinfo.load_from_path(llvmbuild_path, subpath):
+                yield info
+
+    @staticmethod
+    def load_from_path(source_root, llvmbuild_source_root):
+        infos = list(
+            LLVMProjectInfo.load_infos_from_path(llvmbuild_source_root))
+
+        return LLVMProjectInfo(source_root, infos)
+
+    def __init__(self, source_root, component_infos):
+        self.source_root = source_root
+        self.component_infos = component_infos
+
 def main():
     from optparse import OptionParser, OptionGroup
     parser = OptionParser("usage: %prog [options]")
     parser.add_option("", "--source-root", dest="source_root", metavar="PATH",
                       help="Path to the LLVM source (inferred if not given)",
                       action="store", default=None)
+    parser.add_option(
+        "", "--llvmbuild-source-root", dest="llvmbuild_source_root",
+        help="If given, an alternate path to search for LLVMBuild.txt files",
+        action="store", default=None, metavar="PATH")
     (opts, args) = parser.parse_args()
 
     # Determine the LLVM source path, if not given.
@@ -23,5 +65,10 @@
                                            'Function.cpp')):
             parser.error('unable to infer LLVM source root, please specify')
 
+    # Construct the LLVM project information.
+    llvmbuild_source_root = opts.llvmbuild_source_root or source_root
+    project_info = LLVMProjectInfo.load_from_path(
+        source_root, llvmbuild_source_root)
+
 if __name__=='__main__':
     main()





More information about the llvm-commits mailing list