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