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