[llvm-commits] [llvm] r143628 - in /llvm/trunk: docs/CommandGuide/llvm-build.pod utils/llvm-build/llvmbuild/componentinfo.py utils/llvm-build/llvmbuild/main.py

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


Author: ddunbar
Date: Thu Nov  3 12:56:28 2011
New Revision: 143628

URL: http://llvm.org/viewvc/llvm-project?rev=143628&view=rev
Log:
llvm-build: Add "--write-library-table" option for generating the C++ library
dependency table used by llvm-config.

Modified:
    llvm/trunk/docs/CommandGuide/llvm-build.pod
    llvm/trunk/utils/llvm-build/llvmbuild/componentinfo.py
    llvm/trunk/utils/llvm-build/llvmbuild/main.py

Modified: llvm/trunk/docs/CommandGuide/llvm-build.pod
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/CommandGuide/llvm-build.pod?rev=143628&r1=143627&r2=143628&view=diff
==============================================================================
--- llvm/trunk/docs/CommandGuide/llvm-build.pod (original)
+++ llvm/trunk/docs/CommandGuide/llvm-build.pod Thu Nov  3 12:56:28 2011
@@ -36,6 +36,13 @@
 
 Print the component tree for the project.
 
+=item B<--write-library-table>
+
+Write out the C++ fragment which defines the components, library names, and
+required libraries. This C++ fragment is built into L<llvm-config|llvm-config>
+in order to provide clients with the list of required libraries for arbitrary
+component combinations.
+
 =item B<--write-llvmbuild>
 
 Write out new I<LLVMBuild.txt> files based on the loaded components. This is

Modified: llvm/trunk/utils/llvm-build/llvmbuild/componentinfo.py
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/llvm-build/llvmbuild/componentinfo.py?rev=143628&r1=143627&r2=143628&view=diff
==============================================================================
--- llvm/trunk/utils/llvm-build/llvmbuild/componentinfo.py (original)
+++ llvm/trunk/utils/llvm-build/llvmbuild/componentinfo.py Thu Nov  3 12:56:28 2011
@@ -135,6 +135,12 @@
                 self.add_to_library_groups)
         return result.getvalue()
 
+    def get_library_name(self):
+        return self.library_name or self.name
+
+    def get_llvmconfig_component_name(self):
+        return self.get_library_name().lower()
+
 class LibraryGroupComponentInfo(ComponentInfo):
     type_name = 'LibraryGroup'
 
@@ -179,6 +185,9 @@
                 self.add_to_library_groups)
         return result.getvalue()
 
+    def get_llvmconfig_component_name(self):
+        return self.name.lower()
+
 class ToolComponentInfo(ComponentInfo):
     type_name = 'Tool'
 

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=143628&r1=143627&r2=143628&view=diff
==============================================================================
--- llvm/trunk/utils/llvm-build/llvmbuild/main.py (original)
+++ llvm/trunk/utils/llvm-build/llvmbuild/main.py Thu Nov  3 12:56:28 2011
@@ -54,6 +54,10 @@
                         ci.name, ci.subpath, existing.subpath))
             self.component_info_map[ci.name] = ci
 
+        # Disallow 'all' as a component name, which is a special case.
+        if 'all' in self.component_info_map:
+            fatal("project is not allowed to define 'all' component")
+
         # Add the root component.
         if '$ROOT' in self.component_info_map:
             fatal("project is not allowed to define $ROOT component")
@@ -164,6 +168,94 @@
                 print >>f
             f.close()
 
+    def write_library_table(self, output_path):
+        # Write out the mapping from component names to required libraries.
+        #
+        # We do this in topological order so that we know we can append the
+        # dependencies for added library groups.
+        entries = {}
+        for c in self.ordered_component_infos:
+            # Only Library and LibraryGroup components are in the table.
+            if c.type_name not in ('Library', 'LibraryGroup'):
+                continue
+
+            # Compute the llvm-config "component name". For historical reasons,
+            # this is lowercased based on the library name.
+            llvmconfig_component_name = c.get_llvmconfig_component_name()
+            
+            # Get the library name, or None for LibraryGroups.
+            if c.type_name == 'LibraryGroup':
+                library_name = None
+            else:
+                library_name = c.get_library_name()
+
+            # Get the component names of all the required libraries.
+            required_llvmconfig_component_names = [
+                self.component_info_map[dep].get_llvmconfig_component_name()
+                for dep in c.required_libraries]
+
+            # Insert the entries for library groups we should add to.
+            for dep in c.add_to_library_groups:
+                entries[dep][2].append(llvmconfig_component_name)
+
+            # Add the entry.
+            entries[c.name] = (llvmconfig_component_name, library_name,
+                               required_llvmconfig_component_names)
+
+        # Convert to a list of entries and sort by name.
+        entries = entries.values()
+
+        # Create an 'all' pseudo component. We keep the dependency list small by
+        # only listing entries that have no other dependents.
+        root_entries = set(e[0] for e in entries)
+        for _,_,deps in entries:
+            root_entries -= set(deps)
+        entries.append(('all', None, root_entries))
+
+        entries.sort()
+
+        # Compute the maximum number of required libraries, plus one so there is
+        # always a sentinel.
+        max_required_libraries = max(len(deps)
+                                     for _,_,deps in entries) + 1
+
+        # Write out the library table.
+        f = open(output_path, 'w')
+        print >>f, """\
+//===- llvm-build generated file --------------------------------*- C++ -*-===//
+//
+// Component Library Depenedency Table
+//
+// Automatically generated file, do not edit!
+//
+//===----------------------------------------------------------------------===//
+"""
+        print >>f, 'struct AvailableComponent {'
+        print >>f, '  /// The name of the component.'
+        print >>f, '  const char *Name;'
+        print >>f, ''
+        print >>f, '  /// The name of the library for this component (or NULL).'
+        print >>f, '  const char *Library;'
+        print >>f, ''
+        print >>f, '\
+  /// The list of libraries required when linking this component.'
+        print >>f, '  const char *RequiredLibraries[%d];' % (
+            max_required_libraries)
+        print >>f, '} AvailableComponents[%d] = {' % len(entries)
+        for name,library_name,required_names in entries:
+            if library_name is None:
+                library_name_as_cstr = '0'
+            else:
+                # If we had a project level component, we could derive the
+                # library prefix.
+                library_name_as_cstr = '"libLLVM%s.a"' % library_name
+            print >>f, '  { "%s", %s, { %s } },' % (
+                name, library_name_as_cstr,
+                ', '.join('"%s"' % dep
+                          for dep in required_names))
+        print >>f, '};'
+        f.close()
+
 def main():
     from optparse import OptionParser, OptionGroup
     parser = OptionParser("usage: %prog [options]")
@@ -176,10 +268,15 @@
     parser.add_option("", "--write-llvmbuild", dest="write_llvmbuild",
                       help="Write out the LLVMBuild.txt files to PATH",
                       action="store", default=None, metavar="PATH")
-    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")
+    parser.add_option("", "--write-library-table",
+                      dest="write_library_table", metavar="PATH",
+                      help="Write the C++ library dependency table to PATH",
+                      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.
@@ -211,5 +308,9 @@
     if opts.write_llvmbuild:
         project_info.write_components(opts.write_llvmbuild)
 
+    # Write out the required librariy, if requested.
+    if opts.write_library_table:
+        project_info.write_library_table(opts.write_library_table)
+
 if __name__=='__main__':
     main()





More information about the llvm-commits mailing list