Home | History | Annotate | Download | only in llvmbuild
      1 from __future__ import absolute_import
      2 import filecmp
      3 import os
      4 import sys
      5 
      6 import llvmbuild.componentinfo as componentinfo
      7 
      8 from llvmbuild.util import fatal, note
      9 
     10 ###
     11 
     12 def cmake_quote_string(value):
     13     """
     14     cmake_quote_string(value) -> str
     15 
     16     Return a quoted form of the given value that is suitable for use in CMake
     17     language files.
     18     """
     19 
     20     # Currently, we only handle escaping backslashes.
     21     value = value.replace("\\", "\\\\")
     22 
     23     return value
     24 
     25 def cmake_quote_path(value):
     26     """
     27     cmake_quote_path(value) -> str
     28 
     29     Return a quoted form of the given value that is suitable for use in CMake
     30     language files.
     31     """
     32 
     33     # CMake has a bug in it's Makefile generator that doesn't properly quote
     34     # strings it generates. So instead of using proper quoting, we just use "/"
     35     # style paths.  Currently, we only handle escaping backslashes.
     36     value = value.replace("\\", "/")
     37 
     38     return value
     39 
     40 def make_install_dir(path):
     41     """
     42     make_install_dir(path) -> None
     43 
     44     Create the given directory path for installation, including any parents.
     45     """
     46 
     47     # os.makedirs considers it an error to be called with an existent path.
     48     if not os.path.exists(path):
     49         os.makedirs(path)
     50 
     51 ###
     52 
     53 class LLVMProjectInfo(object):
     54     @staticmethod
     55     def load_infos_from_path(llvmbuild_source_root):
     56         def recurse(subpath):
     57             # Load the LLVMBuild file.
     58             llvmbuild_path = os.path.join(llvmbuild_source_root + subpath,
     59                                           'LLVMBuild.txt')
     60             if not os.path.exists(llvmbuild_path):
     61                 fatal("missing LLVMBuild.txt file at: %r" % (llvmbuild_path,))
     62 
     63             # Parse the components from it.
     64             common,info_iter = componentinfo.load_from_path(llvmbuild_path,
     65                                                             subpath)
     66             for info in info_iter:
     67                 yield info
     68 
     69             # Recurse into the specified subdirectories.
     70             for subdir in common.get_list("subdirectories"):
     71                 for item in recurse(os.path.join(subpath, subdir)):
     72                     yield item
     73 
     74         return recurse("/")
     75 
     76     @staticmethod
     77     def load_from_path(source_root, llvmbuild_source_root):
     78         infos = list(
     79             LLVMProjectInfo.load_infos_from_path(llvmbuild_source_root))
     80 
     81         return LLVMProjectInfo(source_root, infos)
     82 
     83     def __init__(self, source_root, component_infos):
     84         # Store our simple ivars.
     85         self.source_root = source_root
     86         self.component_infos = list(component_infos)
     87         self.component_info_map = None
     88         self.ordered_component_infos = None
     89 
     90     def validate_components(self):
     91         """validate_components() -> None
     92 
     93         Validate that the project components are well-defined. Among other
     94         things, this checks that:
     95           - Components have valid references.
     96           - Components references do not form cycles.
     97 
     98         We also construct the map from component names to info, and the
     99         topological ordering of components.
    100         """
    101 
    102         # Create the component info map and validate that component names are
    103         # unique.
    104         self.component_info_map = {}
    105         for ci in self.component_infos:
    106             existing = self.component_info_map.get(ci.name)
    107             if existing is not None:
    108                 # We found a duplicate component name, report it and error out.
    109                 fatal("found duplicate component %r (at %r and %r)" % (
    110                         ci.name, ci.subpath, existing.subpath))
    111             self.component_info_map[ci.name] = ci
    112 
    113         # Disallow 'all' as a component name, which is a special case.
    114         if 'all' in self.component_info_map:
    115             fatal("project is not allowed to define 'all' component")
    116 
    117         # Add the root component.
    118         if '$ROOT' in self.component_info_map:
    119             fatal("project is not allowed to define $ROOT component")
    120         self.component_info_map['$ROOT'] = componentinfo.GroupComponentInfo(
    121             '/', '$ROOT', None)
    122         self.component_infos.append(self.component_info_map['$ROOT'])
    123 
    124         # Topologically order the component information according to their
    125         # component references.
    126         def visit_component_info(ci, current_stack, current_set):
    127             # Check for a cycles.
    128             if ci in current_set:
    129                 # We found a cycle, report it and error out.
    130                 cycle_description = ' -> '.join(
    131                     '%r (%s)' % (ci.name, relation)
    132                     for relation,ci in current_stack)
    133                 fatal("found cycle to %r after following: %s -> %s" % (
    134                         ci.name, cycle_description, ci.name))
    135 
    136             # If we have already visited this item, we are done.
    137             if ci not in components_to_visit:
    138                 return
    139 
    140             # Otherwise, mark the component info as visited and traverse.
    141             components_to_visit.remove(ci)
    142 
    143             # Validate the parent reference, which we treat specially.
    144             if ci.parent is not None:
    145                 parent = self.component_info_map.get(ci.parent)
    146                 if parent is None:
    147                     fatal("component %r has invalid reference %r (via %r)" % (
    148                             ci.name, ci.parent, 'parent'))
    149                 ci.set_parent_instance(parent)
    150 
    151             for relation,referent_name in ci.get_component_references():
    152                 # Validate that the reference is ok.
    153                 referent = self.component_info_map.get(referent_name)
    154                 if referent is None:
    155                     fatal("component %r has invalid reference %r (via %r)" % (
    156                             ci.name, referent_name, relation))
    157 
    158                 # Visit the reference.
    159                 current_stack.append((relation,ci))
    160                 current_set.add(ci)
    161                 visit_component_info(referent, current_stack, current_set)
    162                 current_set.remove(ci)
    163                 current_stack.pop()
    164 
    165             # Finally, add the component info to the ordered list.
    166             self.ordered_component_infos.append(ci)
    167 
    168         # FIXME: We aren't actually correctly checking for cycles along the
    169         # parent edges. Haven't decided how I want to handle this -- I thought
    170         # about only checking cycles by relation type. If we do that, it falls
    171         # out easily. If we don't, we should special case the check.
    172 
    173         self.ordered_component_infos = []
    174         components_to_visit = sorted(
    175             set(self.component_infos),
    176             key = lambda c: c.name)
    177         while components_to_visit:
    178             visit_component_info(components_to_visit[0], [], set())
    179 
    180         # Canonicalize children lists.
    181         for c in self.ordered_component_infos:
    182             c.children.sort(key = lambda c: c.name)
    183 
    184     def print_tree(self):
    185         def visit(node, depth = 0):
    186             print('%s%-40s (%s)' % ('  '*depth, node.name, node.type_name))
    187             for c in node.children:
    188                 visit(c, depth + 1)
    189         visit(self.component_info_map['$ROOT'])
    190 
    191     def write_components(self, output_path):
    192         # Organize all the components by the directory their LLVMBuild file
    193         # should go in.
    194         info_basedir = {}
    195         for ci in self.component_infos:
    196             # Ignore the $ROOT component.
    197             if ci.parent is None:
    198                 continue
    199 
    200             info_basedir[ci.subpath] = info_basedir.get(ci.subpath, []) + [ci]
    201 
    202         # Compute the list of subdirectories to scan.
    203         subpath_subdirs = {}
    204         for ci in self.component_infos:
    205             # Ignore root components.
    206             if ci.subpath == '/':
    207                 continue
    208 
    209             # Otherwise, append this subpath to the parent list.
    210             parent_path = os.path.dirname(ci.subpath)
    211             subpath_subdirs[parent_path] = parent_list = subpath_subdirs.get(
    212                 parent_path, set())
    213             parent_list.add(os.path.basename(ci.subpath))
    214 
    215         # Generate the build files.
    216         for subpath, infos in info_basedir.items():
    217             # Order the components by name to have a canonical ordering.
    218             infos.sort(key = lambda ci: ci.name)
    219 
    220             # Format the components into llvmbuild fragments.
    221             fragments = []
    222 
    223             # Add the common fragments.
    224             subdirectories = subpath_subdirs.get(subpath)
    225             if subdirectories:
    226                 fragment = """\
    227 subdirectories = %s
    228 """ % (" ".join(sorted(subdirectories)),)
    229                 fragments.append(("common", fragment))
    230 
    231             # Add the component fragments.
    232             num_common_fragments = len(fragments)
    233             for ci in infos:
    234                 fragment = ci.get_llvmbuild_fragment()
    235                 if fragment is None:
    236                     continue
    237 
    238                 name = "component_%d" % (len(fragments) - num_common_fragments)
    239                 fragments.append((name, fragment))
    240 
    241             if not fragments:
    242                 continue
    243 
    244             assert subpath.startswith('/')
    245             directory_path = os.path.join(output_path, subpath[1:])
    246 
    247             # Create the directory if it does not already exist.
    248             if not os.path.exists(directory_path):
    249                 os.makedirs(directory_path)
    250 
    251             # In an effort to preserve comments (which aren't parsed), read in
    252             # the original file and extract the comments. We only know how to
    253             # associate comments that prefix a section name.
    254             f = open(infos[0]._source_path)
    255             comments_map = {}
    256             comment_block = ""
    257             for ln in f:
    258                 if ln.startswith(';'):
    259                     comment_block += ln
    260                 elif ln.startswith('[') and ln.endswith(']\n'):
    261                     comments_map[ln[1:-2]] = comment_block
    262                 else:
    263                     comment_block = ""
    264             f.close()
    265 
    266             # Create the LLVMBuild fil[e.
    267             file_path = os.path.join(directory_path, 'LLVMBuild.txt')
    268             f = open(file_path, "w")
    269 
    270             # Write the header.
    271             header_fmt = ';===- %s %s-*- Conf -*--===;'
    272             header_name = '.' + os.path.join(subpath, 'LLVMBuild.txt')
    273             header_pad = '-' * (80 - len(header_fmt % (header_name, '')))
    274             header_string = header_fmt % (header_name, header_pad)
    275             f.write("""\
    276 %s
    277 ;
    278 ;                     The LLVM Compiler Infrastructure
    279 ;
    280 ; This file is distributed under the University of Illinois Open Source
    281 ; License. See LICENSE.TXT for details.
    282 ;
    283 ;===------------------------------------------------------------------------===;
    284 ;
    285 ; This is an LLVMBuild description file for the components in this subdirectory.
    286 ;
    287 ; For more information on the LLVMBuild system, please see:
    288 ;
    289 ;   http://llvm.org/docs/LLVMBuild.html
    290 ;
    291 ;===------------------------------------------------------------------------===;
    292 
    293 """ % header_string)
    294 
    295             # Write out each fragment.each component fragment.
    296             for name,fragment in fragments:
    297                 comment = comments_map.get(name)
    298                 if comment is not None:
    299                     f.write(comment)
    300                 f.write("[%s]\n" % name)
    301                 f.write(fragment)
    302                 if fragment is not fragments[-1][1]:
    303                     f.write('\n')
    304 
    305             f.close()
    306 
    307     def write_library_table(self, output_path, enabled_optional_components):
    308         # Write out the mapping from component names to required libraries.
    309         #
    310         # We do this in topological order so that we know we can append the
    311         # dependencies for added library groups.
    312         entries = {}
    313         for c in self.ordered_component_infos:
    314             # Skip optional components which are not enabled.
    315             if c.type_name == 'OptionalLibrary' \
    316                 and c.name not in enabled_optional_components:
    317                 continue
    318 
    319             # Skip target groups which are not enabled.
    320             tg = c.get_parent_target_group()
    321             if tg and not tg.enabled:
    322                 continue
    323 
    324             # Only certain components are in the table.
    325             if c.type_name not in ('Library', 'OptionalLibrary', \
    326                                    'LibraryGroup', 'TargetGroup'):
    327                 continue
    328 
    329             # Compute the llvm-config "component name". For historical reasons,
    330             # this is lowercased based on the library name.
    331             llvmconfig_component_name = c.get_llvmconfig_component_name()
    332 
    333             # Get the library name, or None for LibraryGroups.
    334             if c.type_name == 'Library' or c.type_name == 'OptionalLibrary':
    335                 library_name = c.get_prefixed_library_name()
    336                 is_installed = c.installed
    337             else:
    338                 library_name = None
    339                 is_installed = True
    340 
    341             # Get the component names of all the required libraries.
    342             required_llvmconfig_component_names = [
    343                 self.component_info_map[dep].get_llvmconfig_component_name()
    344                 for dep in c.required_libraries]
    345 
    346             # Insert the entries for library groups we should add to.
    347             for dep in c.add_to_library_groups:
    348                 entries[dep][2].append(llvmconfig_component_name)
    349 
    350             # Add the entry.
    351             entries[c.name] = (llvmconfig_component_name, library_name,
    352                                required_llvmconfig_component_names,
    353                                is_installed)
    354 
    355         # Convert to a list of entries and sort by name.
    356         entries = list(entries.values())
    357 
    358         # Create an 'all' pseudo component. We keep the dependency list small by
    359         # only listing entries that have no other dependents.
    360         root_entries = set(e[0] for e in entries)
    361         for _,_,deps,_ in entries:
    362             root_entries -= set(deps)
    363         entries.append(('all', None, root_entries, True))
    364 
    365         entries.sort()
    366 
    367         # Compute the maximum number of required libraries, plus one so there is
    368         # always a sentinel.
    369         max_required_libraries = max(len(deps)
    370                                      for _,_,deps,_ in entries) + 1
    371 
    372         # Write out the library table.
    373         make_install_dir(os.path.dirname(output_path))
    374         f = open(output_path+'.new', 'w')
    375         f.write("""\
    376 //===- llvm-build generated file --------------------------------*- C++ -*-===//
    377 //
    378 // Component Library Dependency Table
    379 //
    380 // Automatically generated file, do not edit!
    381 //
    382 //===----------------------------------------------------------------------===//
    383 
    384 """)
    385         f.write('struct AvailableComponent {\n')
    386         f.write('  /// The name of the component.\n')
    387         f.write('  const char *Name;\n')
    388         f.write('\n')
    389         f.write('  /// The name of the library for this component (or NULL).\n')
    390         f.write('  const char *Library;\n')
    391         f.write('\n')
    392         f.write('  /// Whether the component is installed.\n')
    393         f.write('  bool IsInstalled;\n')
    394         f.write('\n')
    395         f.write('\
    396   /// The list of libraries required when linking this component.\n')
    397         f.write('  const char *RequiredLibraries[%d];\n' % (
    398             max_required_libraries))
    399         f.write('} AvailableComponents[%d] = {\n' % len(entries))
    400         for name,library_name,required_names,is_installed in entries:
    401             if library_name is None:
    402                 library_name_as_cstr = 'nullptr'
    403             else:
    404                 library_name_as_cstr = '"%s"' % library_name
    405             if is_installed:
    406                 is_installed_as_cstr = 'true'
    407             else:
    408                 is_installed_as_cstr = 'false'
    409             f.write('  { "%s", %s, %s, { %s } },\n' % (
    410                 name, library_name_as_cstr, is_installed_as_cstr,
    411                 ', '.join('"%s"' % dep
    412                           for dep in required_names)))
    413         f.write('};\n')
    414         f.close()
    415 
    416         if not os.path.isfile(output_path):
    417             os.rename(output_path+'.new', output_path)
    418         elif filecmp.cmp(output_path, output_path+'.new'):
    419             os.remove(output_path+'.new')
    420         else:
    421             os.remove(output_path)
    422             os.rename(output_path+'.new', output_path)
    423 
    424     def get_required_libraries_for_component(self, ci, traverse_groups = False):
    425         """
    426         get_required_libraries_for_component(component_info) -> iter
    427 
    428         Given a Library component info descriptor, return an iterator over all
    429         of the directly required libraries for linking with this component. If
    430         traverse_groups is True, then library and target groups will be
    431         traversed to include their required libraries.
    432         """
    433 
    434         assert ci.type_name in ('Library', 'OptionalLibrary', 'LibraryGroup', 'TargetGroup')
    435 
    436         for name in ci.required_libraries:
    437             # Get the dependency info.
    438             dep = self.component_info_map[name]
    439 
    440             # If it is a library, yield it.
    441             if dep.type_name == 'Library' or dep.type_name == 'OptionalLibrary':
    442                 yield dep
    443                 continue
    444 
    445             # Otherwise if it is a group, yield or traverse depending on what
    446             # was requested.
    447             if dep.type_name in ('LibraryGroup', 'TargetGroup'):
    448                 if not traverse_groups:
    449                     yield dep
    450                     continue
    451 
    452                 for res in self.get_required_libraries_for_component(dep, True):
    453                     yield res
    454 
    455     def get_fragment_dependencies(self):
    456         """
    457         get_fragment_dependencies() -> iter
    458 
    459         Compute the list of files (as absolute paths) on which the output
    460         fragments depend (i.e., files for which a modification should trigger a
    461         rebuild of the fragment).
    462         """
    463 
    464         # Construct a list of all the dependencies of the Makefile fragment
    465         # itself. These include all the LLVMBuild files themselves, as well as
    466         # all of our own sources.
    467         #
    468         # Many components may come from the same file, so we make sure to unique
    469         # these.
    470         build_paths = set()
    471         for ci in self.component_infos:
    472             p = os.path.join(self.source_root, ci.subpath[1:], 'LLVMBuild.txt')
    473             if p not in build_paths:
    474                 yield p
    475                 build_paths.add(p)
    476 
    477         # Gather the list of necessary sources by just finding all loaded
    478         # modules that are inside the LLVM source tree.
    479         for module in sys.modules.values():
    480             # Find the module path.
    481             if not hasattr(module, '__file__'):
    482                 continue
    483             path = getattr(module, '__file__')
    484             if not path:
    485                 continue
    486 
    487             # Strip off any compiled suffix.
    488             if os.path.splitext(path)[1] in ['.pyc', '.pyo', '.pyd']:
    489                 path = path[:-1]
    490 
    491             # If the path exists and is in the source tree, consider it a
    492             # dependency.
    493             if (path.startswith(self.source_root) and os.path.exists(path)):
    494                 yield path
    495 
    496     def foreach_cmake_library(self, f,
    497                               enabled_optional_components,
    498                               skip_disabled,
    499                               skip_not_installed):
    500         for ci in self.ordered_component_infos:
    501             # Skip optional components which are not enabled.
    502             if ci.type_name == 'OptionalLibrary' \
    503                 and ci.name not in enabled_optional_components:
    504                 continue
    505 
    506             # We only write the information for libraries currently.
    507             if ci.type_name not in ('Library', 'OptionalLibrary'):
    508                 continue
    509 
    510             # Skip disabled targets.
    511             if skip_disabled:
    512                 tg = ci.get_parent_target_group()
    513                 if tg and not tg.enabled:
    514                     continue
    515 
    516             # Skip targets that will not be installed
    517             if skip_not_installed and not ci.installed:
    518                 continue
    519 
    520             f(ci)
    521 
    522 
    523     def write_cmake_fragment(self, output_path, enabled_optional_components):
    524         """
    525         write_cmake_fragment(output_path) -> None
    526 
    527         Generate a CMake fragment which includes all of the collated LLVMBuild
    528         information in a format that is easily digestible by a CMake. The exact
    529         contents of this are closely tied to how the CMake configuration
    530         integrates LLVMBuild, see CMakeLists.txt in the top-level.
    531         """
    532 
    533         dependencies = list(self.get_fragment_dependencies())
    534 
    535         # Write out the CMake fragment.
    536         make_install_dir(os.path.dirname(output_path))
    537         f = open(output_path, 'w')
    538 
    539         # Write the header.
    540         header_fmt = '\
    541 #===-- %s - LLVMBuild Configuration for LLVM %s-*- CMake -*--===#'
    542         header_name = os.path.basename(output_path)
    543         header_pad = '-' * (80 - len(header_fmt % (header_name, '')))
    544         header_string = header_fmt % (header_name, header_pad)
    545         f.write("""\
    546 %s
    547 #
    548 #                     The LLVM Compiler Infrastructure
    549 #
    550 # This file is distributed under the University of Illinois Open Source
    551 # License. See LICENSE.TXT for details.
    552 #
    553 #===------------------------------------------------------------------------===#
    554 #
    555 # This file contains the LLVMBuild project information in a format easily
    556 # consumed by the CMake based build system.
    557 #
    558 # This file is autogenerated by llvm-build, do not edit!
    559 #
    560 #===------------------------------------------------------------------------===#
    561 
    562 """ % header_string)
    563 
    564         # Write the dependency information in the best way we can.
    565         f.write("""
    566 # LLVMBuild CMake fragment dependencies.
    567 #
    568 # CMake has no builtin way to declare that the configuration depends on
    569 # a particular file. However, a side effect of configure_file is to add
    570 # said input file to CMake's internal dependency list. So, we use that
    571 # and a dummy output file to communicate the dependency information to
    572 # CMake.
    573 #
    574 # FIXME: File a CMake RFE to get a properly supported version of this
    575 # feature.
    576 """)
    577         for dep in dependencies:
    578             f.write("""\
    579 configure_file(\"%s\"
    580                ${CMAKE_CURRENT_BINARY_DIR}/DummyConfigureOutput)\n""" % (
    581                 cmake_quote_path(dep),))
    582 
    583         # Write the properties we use to encode the required library dependency
    584         # information in a form CMake can easily use directly.
    585         f.write("""
    586 # Explicit library dependency information.
    587 #
    588 # The following property assignments effectively create a map from component
    589 # names to required libraries, in a way that is easily accessed from CMake.
    590 """)
    591         self.foreach_cmake_library(
    592             lambda ci:
    593               f.write("""\
    594 set_property(GLOBAL PROPERTY LLVMBUILD_LIB_DEPS_%s %s)\n""" % (
    595                 ci.get_prefixed_library_name(), " ".join(sorted(
    596                      dep.get_prefixed_library_name()
    597                      for dep in self.get_required_libraries_for_component(ci)))))
    598             ,
    599             enabled_optional_components,
    600             skip_disabled = False,
    601             skip_not_installed = False # Dependency info must be emitted for internals libs too
    602             )
    603 
    604         f.close()
    605 
    606     def write_cmake_exports_fragment(self, output_path, enabled_optional_components):
    607         """
    608         write_cmake_exports_fragment(output_path) -> None
    609 
    610         Generate a CMake fragment which includes LLVMBuild library
    611         dependencies expressed similarly to how CMake would write
    612         them via install(EXPORT).
    613         """
    614 
    615         dependencies = list(self.get_fragment_dependencies())
    616 
    617         # Write out the CMake exports fragment.
    618         make_install_dir(os.path.dirname(output_path))
    619         f = open(output_path, 'w')
    620 
    621         f.write("""\
    622 # Explicit library dependency information.
    623 #
    624 # The following property assignments tell CMake about link
    625 # dependencies of libraries imported from LLVM.
    626 """)
    627         self.foreach_cmake_library(
    628             lambda ci:
    629               f.write("""\
    630 set_property(TARGET %s PROPERTY IMPORTED_LINK_INTERFACE_LIBRARIES %s)\n""" % (
    631                 ci.get_prefixed_library_name(), " ".join(sorted(
    632                      dep.get_prefixed_library_name()
    633                      for dep in self.get_required_libraries_for_component(ci)))))
    634             ,
    635             enabled_optional_components,
    636             skip_disabled = True,
    637             skip_not_installed = True # Do not export internal libraries like gtest
    638             )
    639 
    640         f.close()
    641 
    642 def add_magic_target_components(parser, project, opts):
    643     """add_magic_target_components(project, opts) -> None
    644 
    645     Add the "magic" target based components to the project, which can only be
    646     determined based on the target configuration options.
    647 
    648     This currently is responsible for populating the required_libraries list of
    649     the "all-targets", "Native", "NativeCodeGen", and "Engine" components.
    650     """
    651 
    652     # Determine the available targets.
    653     available_targets = dict((ci.name,ci)
    654                              for ci in project.component_infos
    655                              if ci.type_name == 'TargetGroup')
    656 
    657     # Find the configured native target.
    658 
    659     # We handle a few special cases of target names here for historical
    660     # reasons, as these are the names configure currently comes up with.
    661     native_target_name = { 'x86' : 'X86',
    662                            'x86_64' : 'X86',
    663                            'Unknown' : None }.get(opts.native_target,
    664                                                   opts.native_target)
    665     if native_target_name is None:
    666         native_target = None
    667     else:
    668         native_target = available_targets.get(native_target_name)
    669         if native_target is None:
    670             parser.error("invalid native target: %r (not in project)" % (
    671                     opts.native_target,))
    672         if native_target.type_name != 'TargetGroup':
    673             parser.error("invalid native target: %r (not a target)" % (
    674                     opts.native_target,))
    675 
    676     # Find the list of targets to enable.
    677     if opts.enable_targets is None:
    678         enable_targets = available_targets.values()
    679     else:
    680         # We support both space separated and semi-colon separated lists.
    681         if opts.enable_targets == '':
    682             enable_target_names = []
    683         elif ' ' in opts.enable_targets:
    684             enable_target_names = opts.enable_targets.split()
    685         else:
    686             enable_target_names = opts.enable_targets.split(';')
    687 
    688         enable_targets = []
    689         for name in enable_target_names:
    690             target = available_targets.get(name)
    691             if target is None:
    692                 parser.error("invalid target to enable: %r (not in project)" % (
    693                         name,))
    694             if target.type_name != 'TargetGroup':
    695                 parser.error("invalid target to enable: %r (not a target)" % (
    696                         name,))
    697             enable_targets.append(target)
    698 
    699     # Find the special library groups we are going to populate. We enforce that
    700     # these appear in the project (instead of just adding them) so that they at
    701     # least have an explicit representation in the project LLVMBuild files (and
    702     # comments explaining how they are populated).
    703     def find_special_group(name):
    704         info = info_map.get(name)
    705         if info is None:
    706             fatal("expected project to contain special %r component" % (
    707                     name,))
    708 
    709         if info.type_name != 'LibraryGroup':
    710             fatal("special component %r should be a LibraryGroup" % (
    711                     name,))
    712 
    713         if info.required_libraries:
    714             fatal("special component %r must have empty %r list" % (
    715                     name, 'required_libraries'))
    716         if info.add_to_library_groups:
    717             fatal("special component %r must have empty %r list" % (
    718                     name, 'add_to_library_groups'))
    719 
    720         info._is_special_group = True
    721         return info
    722 
    723     info_map = dict((ci.name, ci) for ci in project.component_infos)
    724     all_targets = find_special_group('all-targets')
    725     native_group = find_special_group('Native')
    726     native_codegen_group = find_special_group('NativeCodeGen')
    727     engine_group = find_special_group('Engine')
    728 
    729     # Set the enabled bit in all the target groups, and append to the
    730     # all-targets list.
    731     for ci in enable_targets:
    732         all_targets.required_libraries.append(ci.name)
    733         ci.enabled = True
    734 
    735     # If we have a native target, then that defines the native and
    736     # native_codegen libraries.
    737     if native_target and native_target.enabled:
    738         native_group.required_libraries.append(native_target.name)
    739         native_codegen_group.required_libraries.append(
    740             '%sCodeGen' % native_target.name)
    741 
    742     # If we have a native target with a JIT, use that for the engine. Otherwise,
    743     # use the interpreter.
    744     if native_target and native_target.enabled and native_target.has_jit:
    745         engine_group.required_libraries.append('MCJIT')
    746         engine_group.required_libraries.append(native_group.name)
    747     else:
    748         engine_group.required_libraries.append('Interpreter')
    749 
    750 def main():
    751     from optparse import OptionParser, OptionGroup
    752     parser = OptionParser("usage: %prog [options]")
    753 
    754     group = OptionGroup(parser, "Input Options")
    755     group.add_option("", "--source-root", dest="source_root", metavar="PATH",
    756                       help="Path to the LLVM source (inferred if not given)",
    757                       action="store", default=None)
    758     group.add_option("", "--llvmbuild-source-root",
    759                      dest="llvmbuild_source_root",
    760                      help=(
    761             "If given, an alternate path to search for LLVMBuild.txt files"),
    762                      action="store", default=None, metavar="PATH")
    763     parser.add_option_group(group)
    764 
    765     group = OptionGroup(parser, "Output Options")
    766     group.add_option("", "--print-tree", dest="print_tree",
    767                      help="Print out the project component tree [%default]",
    768                      action="store_true", default=False)
    769     group.add_option("", "--write-llvmbuild", dest="write_llvmbuild",
    770                       help="Write out the LLVMBuild.txt files to PATH",
    771                       action="store", default=None, metavar="PATH")
    772     group.add_option("", "--write-library-table",
    773                      dest="write_library_table", metavar="PATH",
    774                      help="Write the C++ library dependency table to PATH",
    775                      action="store", default=None)
    776     group.add_option("", "--write-cmake-fragment",
    777                      dest="write_cmake_fragment", metavar="PATH",
    778                      help="Write the CMake project information to PATH",
    779                      action="store", default=None)
    780     group.add_option("", "--write-cmake-exports-fragment",
    781                      dest="write_cmake_exports_fragment", metavar="PATH",
    782                      help="Write the CMake exports information to PATH",
    783                      action="store", default=None)
    784     parser.add_option_group(group)
    785 
    786     group = OptionGroup(parser, "Configuration Options")
    787     group.add_option("", "--native-target",
    788                       dest="native_target", metavar="NAME",
    789                       help=("Treat the named target as the 'native' one, if "
    790                             "given [%default]"),
    791                       action="store", default=None)
    792     group.add_option("", "--enable-targets",
    793                       dest="enable_targets", metavar="NAMES",
    794                       help=("Enable the given space or semi-colon separated "
    795                             "list of targets, or all targets if not present"),
    796                       action="store", default=None)
    797     group.add_option("", "--enable-optional-components",
    798                       dest="optional_components", metavar="NAMES",
    799                       help=("Enable the given space or semi-colon separated "
    800                             "list of optional components"),
    801                       action="store", default="")
    802     parser.add_option_group(group)
    803 
    804     (opts, args) = parser.parse_args()
    805 
    806     # Determine the LLVM source path, if not given.
    807     source_root = opts.source_root
    808     if source_root:
    809         if not os.path.exists(os.path.join(source_root, 'lib', 'IR',
    810                                            'Function.cpp')):
    811             parser.error('invalid LLVM source root: %r' % source_root)
    812     else:
    813         llvmbuild_path = os.path.dirname(__file__)
    814         llvm_build_path = os.path.dirname(llvmbuild_path)
    815         utils_path = os.path.dirname(llvm_build_path)
    816         source_root = os.path.dirname(utils_path)
    817         if not os.path.exists(os.path.join(source_root, 'lib', 'IR',
    818                                            'Function.cpp')):
    819             parser.error('unable to infer LLVM source root, please specify')
    820 
    821     # Construct the LLVM project information.
    822     llvmbuild_source_root = opts.llvmbuild_source_root or source_root
    823     project_info = LLVMProjectInfo.load_from_path(
    824         source_root, llvmbuild_source_root)
    825 
    826     # Add the magic target based components.
    827     add_magic_target_components(parser, project_info, opts)
    828 
    829     # Validate the project component info.
    830     project_info.validate_components()
    831 
    832     # Print the component tree, if requested.
    833     if opts.print_tree:
    834         project_info.print_tree()
    835 
    836     # Write out the components, if requested. This is useful for auto-upgrading
    837     # the schema.
    838     if opts.write_llvmbuild:
    839         project_info.write_components(opts.write_llvmbuild)
    840 
    841     # Write out the required library table, if requested.
    842     if opts.write_library_table:
    843         project_info.write_library_table(opts.write_library_table,
    844                                          opts.optional_components)
    845 
    846     # Write out the cmake fragment, if requested.
    847     if opts.write_cmake_fragment:
    848         project_info.write_cmake_fragment(opts.write_cmake_fragment,
    849                                           opts.optional_components)
    850     if opts.write_cmake_exports_fragment:
    851         project_info.write_cmake_exports_fragment(opts.write_cmake_exports_fragment,
    852                                                   opts.optional_components)
    853 
    854 if __name__=='__main__':
    855     main()
    856