78bd7967ad01010ba040303373930c4f4e511041
[oota-llvm.git] / utils / llvm-build / llvmbuild / main.py
1 from __future__ import absolute_import
2 import filecmp
3 import os
4 import sys
5
6 import llvmbuild.componentinfo as componentinfo
7 import llvmbuild.configutil as configutil
8
9 from llvmbuild.util import fatal, note
10
11 ###
12
13 def 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
26 def 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
41 def 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
52 def 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
65 class 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 = """\
239 subdirectories = %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 foreach_cmake_library(self, f,
505                               enabled_optional_components,
506                               skip_disabled,
507                               skip_not_installed):
508         for ci in self.ordered_component_infos:
509             # Skip optional components which are not enabled.
510             if ci.type_name == 'OptionalLibrary' \
511                 and ci.name not in enabled_optional_components:
512                 continue
513
514             # We only write the information for libraries currently.
515             if ci.type_name not in ('Library', 'OptionalLibrary'):
516                 continue
517
518             # Skip disabled targets.
519             if skip_disabled:
520                 tg = ci.get_parent_target_group()
521                 if tg and not tg.enabled:
522                     continue
523
524             # Skip targets that will not be installed
525             if skip_not_installed and not ci.installed:
526                 continue
527
528             f(ci)
529
530
531     def write_cmake_fragment(self, output_path, enabled_optional_components):
532         """
533         write_cmake_fragment(output_path) -> None
534
535         Generate a CMake fragment which includes all of the collated LLVMBuild
536         information in a format that is easily digestible by a CMake. The exact
537         contents of this are closely tied to how the CMake configuration
538         integrates LLVMBuild, see CMakeLists.txt in the top-level.
539         """
540
541         dependencies = list(self.get_fragment_dependencies())
542
543         # Write out the CMake fragment.
544         make_install_dir(os.path.dirname(output_path))
545         f = open(output_path, 'w')
546
547         # Write the header.
548         header_fmt = '\
549 #===-- %s - LLVMBuild Configuration for LLVM %s-*- CMake -*--===#'
550         header_name = os.path.basename(output_path)
551         header_pad = '-' * (80 - len(header_fmt % (header_name, '')))
552         header_string = header_fmt % (header_name, header_pad)
553         f.write("""\
554 %s
555 #
556 #                     The LLVM Compiler Infrastructure
557 #
558 # This file is distributed under the University of Illinois Open Source
559 # License. See LICENSE.TXT for details.
560 #
561 #===------------------------------------------------------------------------===#
562 #
563 # This file contains the LLVMBuild project information in a format easily
564 # consumed by the CMake based build system.
565 #
566 # This file is autogenerated by llvm-build, do not edit!
567 #
568 #===------------------------------------------------------------------------===#
569
570 """ % header_string)
571
572         # Write the dependency information in the best way we can.
573         f.write("""
574 # LLVMBuild CMake fragment dependencies.
575 #
576 # CMake has no builtin way to declare that the configuration depends on
577 # a particular file. However, a side effect of configure_file is to add
578 # said input file to CMake's internal dependency list. So, we use that
579 # and a dummy output file to communicate the dependency information to
580 # CMake.
581 #
582 # FIXME: File a CMake RFE to get a properly supported version of this
583 # feature.
584 """)
585         for dep in dependencies:
586             f.write("""\
587 configure_file(\"%s\"
588                ${CMAKE_CURRENT_BINARY_DIR}/DummyConfigureOutput)\n""" % (
589                 cmake_quote_path(dep),))
590
591         # Write the properties we use to encode the required library dependency
592         # information in a form CMake can easily use directly.
593         f.write("""
594 # Explicit library dependency information.
595 #
596 # The following property assignments effectively create a map from component
597 # names to required libraries, in a way that is easily accessed from CMake.
598 """)
599         self.foreach_cmake_library(
600             lambda ci:
601               f.write("""\
602 set_property(GLOBAL PROPERTY LLVMBUILD_LIB_DEPS_%s %s)\n""" % (
603                 ci.get_prefixed_library_name(), " ".join(sorted(
604                      dep.get_prefixed_library_name()
605                      for dep in self.get_required_libraries_for_component(ci)))))
606             ,
607             enabled_optional_components,
608             skip_disabled = False,
609             skip_not_installed = False # Dependency info must be emitted for internals libs too
610             )
611
612         f.close()
613
614     def write_cmake_exports_fragment(self, output_path, enabled_optional_components):
615         """
616         write_cmake_exports_fragment(output_path) -> None
617
618         Generate a CMake fragment which includes LLVMBuild library
619         dependencies expressed similarly to how CMake would write
620         them via install(EXPORT).
621         """
622
623         dependencies = list(self.get_fragment_dependencies())
624
625         # Write out the CMake exports fragment.
626         make_install_dir(os.path.dirname(output_path))
627         f = open(output_path, 'w')
628
629         f.write("""\
630 # Explicit library dependency information.
631 #
632 # The following property assignments tell CMake about link
633 # dependencies of libraries imported from LLVM.
634 """)
635         self.foreach_cmake_library(
636             lambda ci:
637               f.write("""\
638 set_property(TARGET %s PROPERTY IMPORTED_LINK_INTERFACE_LIBRARIES %s)\n""" % (
639                 ci.get_prefixed_library_name(), " ".join(sorted(
640                      dep.get_prefixed_library_name()
641                      for dep in self.get_required_libraries_for_component(ci)))))
642             ,
643             enabled_optional_components,
644             skip_disabled = True,
645             skip_not_installed = True # Do not export internal libraries like gtest
646             )
647
648         f.close()
649
650     def write_make_fragment(self, output_path, enabled_optional_components):
651         """
652         write_make_fragment(output_path) -> None
653
654         Generate a Makefile fragment which includes all of the collated
655         LLVMBuild information in a format that is easily digestible by a
656         Makefile. The exact contents of this are closely tied to how the LLVM
657         Makefiles integrate LLVMBuild, see Makefile.rules in the top-level.
658         """
659
660         dependencies = list(self.get_fragment_dependencies())
661
662         # Write out the Makefile fragment.
663         make_install_dir(os.path.dirname(output_path))
664         f = open(output_path, 'w')
665
666         # Write the header.
667         header_fmt = '\
668 #===-- %s - LLVMBuild Configuration for LLVM %s-*- Makefile -*--===#'
669         header_name = os.path.basename(output_path)
670         header_pad = '-' * (80 - len(header_fmt % (header_name, '')))
671         header_string = header_fmt % (header_name, header_pad)
672         f.write("""\
673 %s
674 #
675 #                     The LLVM Compiler Infrastructure
676 #
677 # This file is distributed under the University of Illinois Open Source
678 # License. See LICENSE.TXT for details.
679 #
680 #===------------------------------------------------------------------------===#
681 #
682 # This file contains the LLVMBuild project information in a format easily
683 # consumed by the Makefile based build system.
684 #
685 # This file is autogenerated by llvm-build, do not edit!
686 #
687 #===------------------------------------------------------------------------===#
688
689 """ % header_string)
690
691         # Write the dependencies for the fragment.
692         #
693         # FIXME: Technically, we need to properly quote for Make here.
694         f.write("""\
695 # Clients must explicitly enable LLVMBUILD_INCLUDE_DEPENDENCIES to get
696 # these dependencies. This is a compromise to help improve the
697 # performance of recursive Make systems.
698 """)
699         f.write('ifeq ($(LLVMBUILD_INCLUDE_DEPENDENCIES),1)\n')
700         f.write("# The dependencies for this Makefile fragment itself.\n")
701         f.write("%s: \\\n" % (mk_quote_string_for_target(output_path),))
702         for dep in dependencies:
703             f.write("\t%s \\\n" % (dep,))
704         f.write('\n')
705
706         # Generate dummy rules for each of the dependencies, so that things
707         # continue to work correctly if any of those files are moved or removed.
708         f.write("""\
709 # The dummy targets to allow proper regeneration even when files are moved or
710 # removed.
711 """)
712         for dep in dependencies:
713             f.write("%s:\n" % (mk_quote_string_for_target(dep),))
714         f.write('endif\n')
715
716         f.write("""
717 # List of libraries to be exported for use by applications.
718 # See 'cmake/modules/Makefile'.
719 LLVM_LIBS_TO_EXPORT :=""")
720         self.foreach_cmake_library(
721             lambda ci:
722                 f.write(' \\\n  %s' % ci.get_prefixed_library_name())
723             ,
724             enabled_optional_components,
725             skip_disabled = True,
726             skip_not_installed = True # Do not export internal libraries like gtest
727             )
728         f.write('\n')
729         f.close()
730
731 def add_magic_target_components(parser, project, opts):
732     """add_magic_target_components(project, opts) -> None
733
734     Add the "magic" target based components to the project, which can only be
735     determined based on the target configuration options.
736
737     This currently is responsible for populating the required_libraries list of
738     the "all-targets", "Native", "NativeCodeGen", and "Engine" components.
739     """
740
741     # Determine the available targets.
742     available_targets = dict((ci.name,ci)
743                              for ci in project.component_infos
744                              if ci.type_name == 'TargetGroup')
745
746     # Find the configured native target.
747
748     # We handle a few special cases of target names here for historical
749     # reasons, as these are the names configure currently comes up with.
750     native_target_name = { 'x86' : 'X86',
751                            'x86_64' : 'X86',
752                            'Unknown' : None }.get(opts.native_target,
753                                                   opts.native_target)
754     if native_target_name is None:
755         native_target = None
756     else:
757         native_target = available_targets.get(native_target_name)
758         if native_target is None:
759             parser.error("invalid native target: %r (not in project)" % (
760                     opts.native_target,))
761         if native_target.type_name != 'TargetGroup':
762             parser.error("invalid native target: %r (not a target)" % (
763                     opts.native_target,))
764
765     # Find the list of targets to enable.
766     if opts.enable_targets is None:
767         enable_targets = available_targets.values()
768     else:
769         # We support both space separated and semi-colon separated lists.
770         if opts.enable_targets == '':
771             enable_target_names = []
772         elif ' ' in opts.enable_targets:
773             enable_target_names = opts.enable_targets.split()
774         else:
775             enable_target_names = opts.enable_targets.split(';')
776
777         enable_targets = []
778         for name in enable_target_names:
779             target = available_targets.get(name)
780             if target is None:
781                 parser.error("invalid target to enable: %r (not in project)" % (
782                         name,))
783             if target.type_name != 'TargetGroup':
784                 parser.error("invalid target to enable: %r (not a target)" % (
785                         name,))
786             enable_targets.append(target)
787
788     # Find the special library groups we are going to populate. We enforce that
789     # these appear in the project (instead of just adding them) so that they at
790     # least have an explicit representation in the project LLVMBuild files (and
791     # comments explaining how they are populated).
792     def find_special_group(name):
793         info = info_map.get(name)
794         if info is None:
795             fatal("expected project to contain special %r component" % (
796                     name,))
797
798         if info.type_name != 'LibraryGroup':
799             fatal("special component %r should be a LibraryGroup" % (
800                     name,))
801
802         if info.required_libraries:
803             fatal("special component %r must have empty %r list" % (
804                     name, 'required_libraries'))
805         if info.add_to_library_groups:
806             fatal("special component %r must have empty %r list" % (
807                     name, 'add_to_library_groups'))
808
809         info._is_special_group = True
810         return info
811
812     info_map = dict((ci.name, ci) for ci in project.component_infos)
813     all_targets = find_special_group('all-targets')
814     native_group = find_special_group('Native')
815     native_codegen_group = find_special_group('NativeCodeGen')
816     engine_group = find_special_group('Engine')
817
818     # Set the enabled bit in all the target groups, and append to the
819     # all-targets list.
820     for ci in enable_targets:
821         all_targets.required_libraries.append(ci.name)
822         ci.enabled = True
823
824     # If we have a native target, then that defines the native and
825     # native_codegen libraries.
826     if native_target and native_target.enabled:
827         native_group.required_libraries.append(native_target.name)
828         native_codegen_group.required_libraries.append(
829             '%sCodeGen' % native_target.name)
830
831     # If we have a native target with a JIT, use that for the engine. Otherwise,
832     # use the interpreter.
833     if native_target and native_target.enabled and native_target.has_jit:
834         engine_group.required_libraries.append('MCJIT')
835         engine_group.required_libraries.append(native_group.name)
836     else:
837         engine_group.required_libraries.append('Interpreter')
838
839 def main():
840     from optparse import OptionParser, OptionGroup
841     parser = OptionParser("usage: %prog [options]")
842
843     group = OptionGroup(parser, "Input Options")
844     group.add_option("", "--source-root", dest="source_root", metavar="PATH",
845                       help="Path to the LLVM source (inferred if not given)",
846                       action="store", default=None)
847     group.add_option("", "--llvmbuild-source-root",
848                      dest="llvmbuild_source_root",
849                      help=(
850             "If given, an alternate path to search for LLVMBuild.txt files"),
851                      action="store", default=None, metavar="PATH")
852     group.add_option("", "--build-root", dest="build_root", metavar="PATH",
853                       help="Path to the build directory (if needed) [%default]",
854                       action="store", default=None)
855     parser.add_option_group(group)
856
857     group = OptionGroup(parser, "Output Options")
858     group.add_option("", "--print-tree", dest="print_tree",
859                      help="Print out the project component tree [%default]",
860                      action="store_true", default=False)
861     group.add_option("", "--write-llvmbuild", dest="write_llvmbuild",
862                       help="Write out the LLVMBuild.txt files to PATH",
863                       action="store", default=None, metavar="PATH")
864     group.add_option("", "--write-library-table",
865                      dest="write_library_table", metavar="PATH",
866                      help="Write the C++ library dependency table to PATH",
867                      action="store", default=None)
868     group.add_option("", "--write-cmake-fragment",
869                      dest="write_cmake_fragment", metavar="PATH",
870                      help="Write the CMake project information to PATH",
871                      action="store", default=None)
872     group.add_option("", "--write-cmake-exports-fragment",
873                      dest="write_cmake_exports_fragment", metavar="PATH",
874                      help="Write the CMake exports information to PATH",
875                      action="store", default=None)
876     group.add_option("", "--write-make-fragment",
877                       dest="write_make_fragment", metavar="PATH",
878                      help="Write the Makefile project information to PATH",
879                      action="store", default=None)
880     group.add_option("", "--configure-target-def-file",
881                      dest="configure_target_def_files",
882                      help="""Configure the given file at SUBPATH (relative to
883 the inferred or given source root, and with a '.in' suffix) by replacing certain
884 substitution variables with lists of targets that support certain features (for
885 example, targets with AsmPrinters) and write the result to the build root (as
886 given by --build-root) at the same SUBPATH""",
887                      metavar="SUBPATH", action="append", default=None)
888     parser.add_option_group(group)
889
890     group = OptionGroup(parser, "Configuration Options")
891     group.add_option("", "--native-target",
892                       dest="native_target", metavar="NAME",
893                       help=("Treat the named target as the 'native' one, if "
894                             "given [%default]"),
895                       action="store", default=None)
896     group.add_option("", "--enable-targets",
897                       dest="enable_targets", metavar="NAMES",
898                       help=("Enable the given space or semi-colon separated "
899                             "list of targets, or all targets if not present"),
900                       action="store", default=None)
901     group.add_option("", "--enable-optional-components",
902                       dest="optional_components", metavar="NAMES",
903                       help=("Enable the given space or semi-colon separated "
904                             "list of optional components"),
905                       action="store", default="")
906     parser.add_option_group(group)
907
908     (opts, args) = parser.parse_args()
909
910     # Determine the LLVM source path, if not given.
911     source_root = opts.source_root
912     if source_root:
913         if not os.path.exists(os.path.join(source_root, 'lib', 'IR',
914                                            'Function.cpp')):
915             parser.error('invalid LLVM source root: %r' % source_root)
916     else:
917         llvmbuild_path = os.path.dirname(__file__)
918         llvm_build_path = os.path.dirname(llvmbuild_path)
919         utils_path = os.path.dirname(llvm_build_path)
920         source_root = os.path.dirname(utils_path)
921         if not os.path.exists(os.path.join(source_root, 'lib', 'IR',
922                                            'Function.cpp')):
923             parser.error('unable to infer LLVM source root, please specify')
924
925     # Construct the LLVM project information.
926     llvmbuild_source_root = opts.llvmbuild_source_root or source_root
927     project_info = LLVMProjectInfo.load_from_path(
928         source_root, llvmbuild_source_root)
929
930     # Add the magic target based components.
931     add_magic_target_components(parser, project_info, opts)
932
933     # Validate the project component info.
934     project_info.validate_components()
935
936     # Print the component tree, if requested.
937     if opts.print_tree:
938         project_info.print_tree()
939
940     # Write out the components, if requested. This is useful for auto-upgrading
941     # the schema.
942     if opts.write_llvmbuild:
943         project_info.write_components(opts.write_llvmbuild)
944
945     # Write out the required library table, if requested.
946     if opts.write_library_table:
947         project_info.write_library_table(opts.write_library_table,
948                                          opts.optional_components)
949
950     # Write out the make fragment, if requested.
951     if opts.write_make_fragment:
952         project_info.write_make_fragment(opts.write_make_fragment,
953                                          opts.optional_components)
954
955     # Write out the cmake fragment, if requested.
956     if opts.write_cmake_fragment:
957         project_info.write_cmake_fragment(opts.write_cmake_fragment,
958                                           opts.optional_components)
959     if opts.write_cmake_exports_fragment:
960         project_info.write_cmake_exports_fragment(opts.write_cmake_exports_fragment,
961                                                   opts.optional_components)
962
963     # Configure target definition files, if requested.
964     if opts.configure_target_def_files:
965         # Verify we were given a build root.
966         if not opts.build_root:
967             parser.error("must specify --build-root when using "
968                          "--configure-target-def-file")
969
970         # Create the substitution list.
971         available_targets = [ci for ci in project_info.component_infos
972                              if ci.type_name == 'TargetGroup']
973         substitutions = [
974             ("@LLVM_ENUM_TARGETS@",
975              ' '.join('LLVM_TARGET(%s)' % ci.name
976                       for ci in available_targets)),
977             ("@LLVM_ENUM_ASM_PRINTERS@",
978              ' '.join('LLVM_ASM_PRINTER(%s)' % ci.name
979                       for ci in available_targets
980                       if ci.has_asmprinter)),
981             ("@LLVM_ENUM_ASM_PARSERS@",
982              ' '.join('LLVM_ASM_PARSER(%s)' % ci.name
983                       for ci in available_targets
984                       if ci.has_asmparser)),
985             ("@LLVM_ENUM_DISASSEMBLERS@",
986              ' '.join('LLVM_DISASSEMBLER(%s)' % ci.name
987                       for ci in available_targets
988                       if ci.has_disassembler))]
989
990         # Configure the given files.
991         for subpath in opts.configure_target_def_files:
992             inpath = os.path.join(source_root, subpath + '.in')
993             outpath = os.path.join(opts.build_root, subpath)
994             result = configutil.configure_file(inpath, outpath, substitutions)
995             if not result:
996                 note("configured file %r hasn't changed" % outpath)
997
998 if __name__=='__main__':
999     main()