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