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