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