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