blob: fe852a0c4e2a38bd58205af143c75c9fab81e5ef [file] [log] [blame]
Daniel Dunbarad5e0122011-11-03 17:56:03 +00001import os
Daniel Dunbar1cf14af2011-11-03 17:56:12 +00002import sys
Daniel Dunbarad5e0122011-11-03 17:56:03 +00003
Daniel Dunbardf578252011-11-03 17:56:06 +00004import componentinfo
5
Daniel Dunbar1cf14af2011-11-03 17:56:12 +00006from util import *
7
8###
9
Daniel Dunbar57574fa2011-11-05 04:07:43 +000010def 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
Daniel Dunbar20fb32b2011-11-04 23:40:11 +000023def 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
Daniel Dunbar195c6f32011-11-05 04:07:49 +000034def 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
Daniel Dunbar20fb32b2011-11-04 23:40:11 +000045###
46
Daniel Dunbardf578252011-11-03 17:56:06 +000047class 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.
Daniel Dunbare10233b2011-11-03 19:45:52 +000054 #
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):
Daniel Dunbardf578252011-11-03 17:56:06 +000061 # 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):
Daniel Dunbar1cf14af2011-11-03 17:56:12 +000084 # Store our simple ivars.
Daniel Dunbardf578252011-11-03 17:56:06 +000085 self.source_root = source_root
Daniel Dunbarb4eaee72011-11-10 00:49:58 +000086 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 """
Daniel Dunbardf578252011-11-03 17:56:06 +0000101
Daniel Dunbar1cf14af2011-11-03 17:56:12 +0000102 # Create the component info map and validate that component names are
103 # unique.
104 self.component_info_map = {}
Daniel Dunbarb4eaee72011-11-10 00:49:58 +0000105 for ci in self.component_infos:
Daniel Dunbar1cf14af2011-11-03 17:56:12 +0000106 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
Daniel Dunbarefe2f642011-11-03 17:56:28 +0000113 # 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
Daniel Dunbar00b4b4f2011-11-03 17:56:18 +0000117 # Add the root component.
Daniel Dunbar86c119a2011-11-03 17:56:16 +0000118 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)
Daniel Dunbar00b4b4f2011-11-03 17:56:18 +0000122 self.component_infos.append(self.component_info_map['$ROOT'])
Daniel Dunbar86c119a2011-11-03 17:56:16 +0000123
Daniel Dunbar1cf14af2011-11-03 17:56:12 +0000124 # 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
Daniel Dunbar86c119a2011-11-03 17:56:16 +0000143 # Validate the parent reference, which we treat specially.
Daniel Dunbar00b4b4f2011-11-03 17:56:18 +0000144 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)
Daniel Dunbar86c119a2011-11-03 17:56:16 +0000150
Daniel Dunbar1cf14af2011-11-03 17:56:12 +0000151 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
Daniel Dunbar86c119a2011-11-03 17:56:16 +0000168 # 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
Daniel Dunbar1cf14af2011-11-03 17:56:12 +0000173 self.ordered_component_infos = []
Daniel Dunbarb4eaee72011-11-10 00:49:58 +0000174 components_to_visit = set(self.component_infos)
Daniel Dunbar1cf14af2011-11-03 17:56:12 +0000175 while components_to_visit:
176 visit_component_info(iter(components_to_visit).next(), [], set())
177
Daniel Dunbar00b4b4f2011-11-03 17:56:18 +0000178 # 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
Daniel Dunbar43120df2011-11-03 17:56:21 +0000189 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")
Daniel Dunbarfb6d79a2011-11-03 17:56:31 +0000221
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
Daniel Dunbar43120df2011-11-03 17:56:21 +0000246 for i,fragment in enumerate(fragments):
247 print >>f, '[component_%d]' % i
248 f.write(fragment)
249 print >>f
250 f.close()
251
Daniel Dunbarefe2f642011-11-03 17:56:28 +0000252 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:
Daniel Dunbarc352caf2011-11-10 00:49:51 +0000259 # Only certain components are in the table.
260 if c.type_name not in ('Library', 'LibraryGroup', 'TargetGroup'):
Daniel Dunbarefe2f642011-11-03 17:56:28 +0000261 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.
Daniel Dunbarc352caf2011-11-10 00:49:51 +0000268 if c.type_name == 'Library':
Daniel Dunbarefe2f642011-11-03 17:56:28 +0000269 library_name = c.get_library_name()
Daniel Dunbarc352caf2011-11-10 00:49:51 +0000270 else:
271 library_name = None
Daniel Dunbarefe2f642011-11-03 17:56:28 +0000272
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.
Daniel Dunbar195c6f32011-11-05 04:07:49 +0000304 make_install_dir(os.path.dirname(output_path))
Daniel Dunbarefe2f642011-11-03 17:56:28 +0000305 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
Daniel Dunbar16889612011-11-04 23:10:37 +0000341 def get_fragment_dependencies(self):
Daniel Dunbar02271a72011-11-03 22:46:19 +0000342 """
Daniel Dunbar16889612011-11-04 23:10:37 +0000343 get_fragment_dependencies() -> iter
Daniel Dunbar02271a72011-11-03 22:46:19 +0000344
Daniel Dunbar16889612011-11-04 23:10:37 +0000345 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).
Daniel Dunbar02271a72011-11-03 22:46:19 +0000348 """
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.
Daniel Dunbar02271a72011-11-03 22:46:19 +0000353 for ci in self.component_infos:
Daniel Dunbar16889612011-11-04 23:10:37 +0000354 yield os.path.join(self.source_root, ci.subpath[1:],
355 'LLVMBuild.txt')
Daniel Dunbar02271a72011-11-03 22:46:19 +0000356
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)):
Daniel Dunbar16889612011-11-04 23:10:37 +0000374 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.
Daniel Dunbar195c6f32011-11-05 04:07:49 +0000389 make_install_dir(os.path.dirname(output_path))
Daniel Dunbar16889612011-11-04 23:10:37 +0000390 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, """\
430configure_file(\"%s\"
Daniel Dunbar57574fa2011-11-05 04:07:43 +0000431 ${CMAKE_CURRENT_BINARY_DIR}/DummyConfigureOutput)""" % (
432 cmake_quote_string(dep),)
433
Daniel Dunbar16889612011-11-04 23:10:37 +0000434 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())
Daniel Dunbar02271a72011-11-03 22:46:19 +0000447
448 # Write out the Makefile fragment.
Daniel Dunbar195c6f32011-11-05 04:07:49 +0000449 make_install_dir(os.path.dirname(output_path))
Daniel Dunbar02271a72011-11-03 22:46:19 +0000450 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."
Daniel Dunbar20fb32b2011-11-04 23:40:11 +0000485 print >>f, "%s: \\" % (mk_quote_string_for_target(output_path),)
Daniel Dunbar02271a72011-11-03 22:46:19 +0000486 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:
Daniel Dunbar20fb32b2011-11-04 23:40:11 +0000496 print >>f, "%s:" % (mk_quote_string_for_target(dep),)
Daniel Dunbar02271a72011-11-03 22:46:19 +0000497 print >>f, 'endif'
498
499 f.close()
500
Daniel Dunbaraffc6cf2011-11-10 00:50:07 +0000501def 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
Daniel Dunbarad5e0122011-11-03 17:56:03 +0000600def main():
601 from optparse import OptionParser, OptionGroup
602 parser = OptionParser("usage: %prog [options]")
Daniel Dunbar1e5b2432011-11-10 00:49:42 +0000603
604 group = OptionGroup(parser, "Input Options")
605 group.add_option("", "--source-root", dest="source_root", metavar="PATH",
Daniel Dunbarad5e0122011-11-03 17:56:03 +0000606 help="Path to the LLVM source (inferred if not given)",
607 action="store", default=None)
Daniel Dunbar1e5b2432011-11-10 00:49:42 +0000608 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",
Daniel Dunbar43120df2011-11-03 17:56:21 +0000620 help="Write out the LLVMBuild.txt files to PATH",
621 action="store", default=None, metavar="PATH")
Daniel Dunbar1e5b2432011-11-10 00:49:42 +0000622 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",
Daniel Dunbar02271a72011-11-03 22:46:19 +0000631 dest="write_make_fragment", metavar="PATH",
Daniel Dunbar1e5b2432011-11-10 00:49:42 +0000632 help="Write the Makefile project information to PATH",
633 action="store", default=None)
634 parser.add_option_group(group)
Daniel Dunbaraffc6cf2011-11-10 00:50:07 +0000635
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"),
Daniel Dunbar02271a72011-11-03 22:46:19 +0000646 action="store", default=None)
Daniel Dunbar1e5b2432011-11-10 00:49:42 +0000647 parser.add_option_group(group)
648
Daniel Dunbarad5e0122011-11-03 17:56:03 +0000649 (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
Daniel Dunbardf578252011-11-03 17:56:06 +0000666 # 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
Daniel Dunbaraffc6cf2011-11-10 00:50:07 +0000671 # Add the magic target based components.
672 add_magic_target_components(parser, project_info, opts)
673
Daniel Dunbarb4eaee72011-11-10 00:49:58 +0000674 # Validate the project component info.
675 project_info.validate_components()
676
Daniel Dunbar00b4b4f2011-11-03 17:56:18 +0000677 # Print the component tree, if requested.
678 if opts.print_tree:
679 project_info.print_tree()
680
Daniel Dunbar43120df2011-11-03 17:56:21 +0000681 # 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
Daniel Dunbar16889612011-11-04 23:10:37 +0000686 # Write out the required library table, if requested.
Daniel Dunbarefe2f642011-11-03 17:56:28 +0000687 if opts.write_library_table:
688 project_info.write_library_table(opts.write_library_table)
689
Daniel Dunbar16889612011-11-04 23:10:37 +0000690 # Write out the make fragment, if requested.
Daniel Dunbar02271a72011-11-03 22:46:19 +0000691 if opts.write_make_fragment:
692 project_info.write_make_fragment(opts.write_make_fragment)
693
Daniel Dunbar16889612011-11-04 23:10:37 +0000694 # Write out the cmake fragment, if requested.
695 if opts.write_cmake_fragment:
696 project_info.write_cmake_fragment(opts.write_cmake_fragment)
697
Daniel Dunbarad5e0122011-11-03 17:56:03 +0000698if __name__=='__main__':
699 main()