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