1from __future__ import absolute_import 2import filecmp 3import os 4import sys 5 6import llvmbuild.componentinfo as componentinfo 7import llvmbuild.configutil as configutil 8 9from llvmbuild.util import fatal, note 10 11### 12 13def cmake_quote_string(value): 14 """ 15 cmake_quote_string(value) -> str 16 17 Return a quoted form of the given value that is suitable for use in CMake 18 language files. 19 """ 20 21 # Currently, we only handle escaping backslashes. 22 value = value.replace("\\", "\\\\") 23 24 return value 25 26def cmake_quote_path(value): 27 """ 28 cmake_quote_path(value) -> str 29 30 Return a quoted form of the given value that is suitable for use in CMake 31 language files. 32 """ 33 34 # CMake has a bug in it's Makefile generator that doesn't properly quote 35 # strings it generates. So instead of using proper quoting, we just use "/" 36 # style paths. Currently, we only handle escaping backslashes. 37 value = value.replace("\\", "/") 38 39 return value 40 41def mk_quote_string_for_target(value): 42 """ 43 mk_quote_string_for_target(target_name) -> str 44 45 Return a quoted form of the given target_name suitable for including in a 46 Makefile as a target name. 47 """ 48 49 # The only quoting we currently perform is for ':', to support msys users. 50 return value.replace(":", "\\:") 51 52def make_install_dir(path): 53 """ 54 make_install_dir(path) -> None 55 56 Create the given directory path for installation, including any parents. 57 """ 58 59 # os.makedirs considers it an error to be called with an existent path. 60 if not os.path.exists(path): 61 os.makedirs(path) 62 63### 64 65class LLVMProjectInfo(object): 66 @staticmethod 67 def load_infos_from_path(llvmbuild_source_root): 68 def recurse(subpath): 69 # Load the LLVMBuild file. 70 llvmbuild_path = os.path.join(llvmbuild_source_root + subpath, 71 'LLVMBuild.txt') 72 if not os.path.exists(llvmbuild_path): 73 fatal("missing LLVMBuild.txt file at: %r" % (llvmbuild_path,)) 74 75 # Parse the components from it. 76 common,info_iter = componentinfo.load_from_path(llvmbuild_path, 77 subpath) 78 for info in info_iter: 79 yield info 80 81 # Recurse into the specified subdirectories. 82 for subdir in common.get_list("subdirectories"): 83 for item in recurse(os.path.join(subpath, subdir)): 84 yield item 85 86 return recurse("/") 87 88 @staticmethod 89 def load_from_path(source_root, llvmbuild_source_root): 90 infos = list( 91 LLVMProjectInfo.load_infos_from_path(llvmbuild_source_root)) 92 93 return LLVMProjectInfo(source_root, infos) 94 95 def __init__(self, source_root, component_infos): 96 # Store our simple ivars. 97 self.source_root = source_root 98 self.component_infos = list(component_infos) 99 self.component_info_map = None 100 self.ordered_component_infos = None 101 102 def validate_components(self): 103 """validate_components() -> None 104 105 Validate that the project components are well-defined. Among other 106 things, this checks that: 107 - Components have valid references. 108 - Components references do not form cycles. 109 110 We also construct the map from component names to info, and the 111 topological ordering of components. 112 """ 113 114 # Create the component info map and validate that component names are 115 # unique. 116 self.component_info_map = {} 117 for ci in self.component_infos: 118 existing = self.component_info_map.get(ci.name) 119 if existing is not None: 120 # We found a duplicate component name, report it and error out. 121 fatal("found duplicate component %r (at %r and %r)" % ( 122 ci.name, ci.subpath, existing.subpath)) 123 self.component_info_map[ci.name] = ci 124 125 # Disallow 'all' as a component name, which is a special case. 126 if 'all' in self.component_info_map: 127 fatal("project is not allowed to define 'all' component") 128 129 # Add the root component. 130 if '$ROOT' in self.component_info_map: 131 fatal("project is not allowed to define $ROOT component") 132 self.component_info_map['$ROOT'] = componentinfo.GroupComponentInfo( 133 '/', '$ROOT', None) 134 self.component_infos.append(self.component_info_map['$ROOT']) 135 136 # Topologically order the component information according to their 137 # component references. 138 def visit_component_info(ci, current_stack, current_set): 139 # Check for a cycles. 140 if ci in current_set: 141 # We found a cycle, report it and error out. 142 cycle_description = ' -> '.join( 143 '%r (%s)' % (ci.name, relation) 144 for relation,ci in current_stack) 145 fatal("found cycle to %r after following: %s -> %s" % ( 146 ci.name, cycle_description, ci.name)) 147 148 # If we have already visited this item, we are done. 149 if ci not in components_to_visit: 150 return 151 152 # Otherwise, mark the component info as visited and traverse. 153 components_to_visit.remove(ci) 154 155 # Validate the parent reference, which we treat specially. 156 if ci.parent is not None: 157 parent = self.component_info_map.get(ci.parent) 158 if parent is None: 159 fatal("component %r has invalid reference %r (via %r)" % ( 160 ci.name, ci.parent, 'parent')) 161 ci.set_parent_instance(parent) 162 163 for relation,referent_name in ci.get_component_references(): 164 # Validate that the reference is ok. 165 referent = self.component_info_map.get(referent_name) 166 if referent is None: 167 fatal("component %r has invalid reference %r (via %r)" % ( 168 ci.name, referent_name, relation)) 169 170 # Visit the reference. 171 current_stack.append((relation,ci)) 172 current_set.add(ci) 173 visit_component_info(referent, current_stack, current_set) 174 current_set.remove(ci) 175 current_stack.pop() 176 177 # Finally, add the component info to the ordered list. 178 self.ordered_component_infos.append(ci) 179 180 # FIXME: We aren't actually correctly checking for cycles along the 181 # parent edges. Haven't decided how I want to handle this -- I thought 182 # about only checking cycles by relation type. If we do that, it falls 183 # out easily. If we don't, we should special case the check. 184 185 self.ordered_component_infos = [] 186 components_to_visit = sorted( 187 set(self.component_infos), 188 key = lambda c: c.name) 189 while components_to_visit: 190 visit_component_info(components_to_visit[0], [], set()) 191 192 # Canonicalize children lists. 193 for c in self.ordered_component_infos: 194 c.children.sort(key = lambda c: c.name) 195 196 def print_tree(self): 197 def visit(node, depth = 0): 198 print('%s%-40s (%s)' % (' '*depth, node.name, node.type_name)) 199 for c in node.children: 200 visit(c, depth + 1) 201 visit(self.component_info_map['$ROOT']) 202 203 def write_components(self, output_path): 204 # Organize all the components by the directory their LLVMBuild file 205 # should go in. 206 info_basedir = {} 207 for ci in self.component_infos: 208 # Ignore the $ROOT component. 209 if ci.parent is None: 210 continue 211 212 info_basedir[ci.subpath] = info_basedir.get(ci.subpath, []) + [ci] 213 214 # Compute the list of subdirectories to scan. 215 subpath_subdirs = {} 216 for ci in self.component_infos: 217 # Ignore root components. 218 if ci.subpath == '/': 219 continue 220 221 # Otherwise, append this subpath to the parent list. 222 parent_path = os.path.dirname(ci.subpath) 223 subpath_subdirs[parent_path] = parent_list = subpath_subdirs.get( 224 parent_path, set()) 225 parent_list.add(os.path.basename(ci.subpath)) 226 227 # Generate the build files. 228 for subpath, infos in info_basedir.items(): 229 # Order the components by name to have a canonical ordering. 230 infos.sort(key = lambda ci: ci.name) 231 232 # Format the components into llvmbuild fragments. 233 fragments = [] 234 235 # Add the common fragments. 236 subdirectories = subpath_subdirs.get(subpath) 237 if subdirectories: 238 fragment = """\ 239subdirectories = %s 240""" % (" ".join(sorted(subdirectories)),) 241 fragments.append(("common", fragment)) 242 243 # Add the component fragments. 244 num_common_fragments = len(fragments) 245 for ci in infos: 246 fragment = ci.get_llvmbuild_fragment() 247 if fragment is None: 248 continue 249 250 name = "component_%d" % (len(fragments) - num_common_fragments) 251 fragments.append((name, fragment)) 252 253 if not fragments: 254 continue 255 256 assert subpath.startswith('/') 257 directory_path = os.path.join(output_path, subpath[1:]) 258 259 # Create the directory if it does not already exist. 260 if not os.path.exists(directory_path): 261 os.makedirs(directory_path) 262 263 # In an effort to preserve comments (which aren't parsed), read in 264 # the original file and extract the comments. We only know how to 265 # associate comments that prefix a section name. 266 f = open(infos[0]._source_path) 267 comments_map = {} 268 comment_block = "" 269 for ln in f: 270 if ln.startswith(';'): 271 comment_block += ln 272 elif ln.startswith('[') and ln.endswith(']\n'): 273 comments_map[ln[1:-2]] = comment_block 274 else: 275 comment_block = "" 276 f.close() 277 278 # Create the LLVMBuild fil[e. 279 file_path = os.path.join(directory_path, 'LLVMBuild.txt') 280 f = open(file_path, "w") 281 282 # Write the header. 283 header_fmt = ';===- %s %s-*- Conf -*--===;' 284 header_name = '.' + os.path.join(subpath, 'LLVMBuild.txt') 285 header_pad = '-' * (80 - len(header_fmt % (header_name, ''))) 286 header_string = header_fmt % (header_name, header_pad) 287 f.write("""\ 288%s 289; 290; The LLVM Compiler Infrastructure 291; 292; This file is distributed under the University of Illinois Open Source 293; License. See LICENSE.TXT for details. 294; 295;===------------------------------------------------------------------------===; 296; 297; This is an LLVMBuild description file for the components in this subdirectory. 298; 299; For more information on the LLVMBuild system, please see: 300; 301; http://llvm.org/docs/LLVMBuild.html 302; 303;===------------------------------------------------------------------------===; 304 305""" % header_string) 306 307 # Write out each fragment.each component fragment. 308 for name,fragment in fragments: 309 comment = comments_map.get(name) 310 if comment is not None: 311 f.write(comment) 312 f.write("[%s]\n" % name) 313 f.write(fragment) 314 if fragment is not fragments[-1][1]: 315 f.write('\n') 316 317 f.close() 318 319 def write_library_table(self, output_path, enabled_optional_components): 320 # Write out the mapping from component names to required libraries. 321 # 322 # We do this in topological order so that we know we can append the 323 # dependencies for added library groups. 324 entries = {} 325 for c in self.ordered_component_infos: 326 # Skip optional components which are not enabled. 327 if c.type_name == 'OptionalLibrary' \ 328 and c.name not in enabled_optional_components: 329 continue 330 331 # Skip target groups which are not enabled. 332 tg = c.get_parent_target_group() 333 if tg and not tg.enabled: 334 continue 335 336 # Only certain components are in the table. 337 if c.type_name not in ('Library', 'OptionalLibrary', \ 338 'LibraryGroup', 'TargetGroup'): 339 continue 340 341 # Compute the llvm-config "component name". For historical reasons, 342 # this is lowercased based on the library name. 343 llvmconfig_component_name = c.get_llvmconfig_component_name() 344 345 # Get the library name, or None for LibraryGroups. 346 if c.type_name == 'Library' or c.type_name == 'OptionalLibrary': 347 library_name = c.get_prefixed_library_name() 348 is_installed = c.installed 349 else: 350 library_name = None 351 is_installed = True 352 353 # Get the component names of all the required libraries. 354 required_llvmconfig_component_names = [ 355 self.component_info_map[dep].get_llvmconfig_component_name() 356 for dep in c.required_libraries] 357 358 # Insert the entries for library groups we should add to. 359 for dep in c.add_to_library_groups: 360 entries[dep][2].append(llvmconfig_component_name) 361 362 # Add the entry. 363 entries[c.name] = (llvmconfig_component_name, library_name, 364 required_llvmconfig_component_names, 365 is_installed) 366 367 # Convert to a list of entries and sort by name. 368 entries = list(entries.values()) 369 370 # Create an 'all' pseudo component. We keep the dependency list small by 371 # only listing entries that have no other dependents. 372 root_entries = set(e[0] for e in entries) 373 for _,_,deps,_ in entries: 374 root_entries -= set(deps) 375 entries.append(('all', None, root_entries, True)) 376 377 entries.sort() 378 379 # Compute the maximum number of required libraries, plus one so there is 380 # always a sentinel. 381 max_required_libraries = max(len(deps) 382 for _,_,deps,_ in entries) + 1 383 384 # Write out the library table. 385 make_install_dir(os.path.dirname(output_path)) 386 f = open(output_path+'.new', 'w') 387 f.write("""\ 388//===- llvm-build generated file --------------------------------*- C++ -*-===// 389// 390// Component Library Depenedency Table 391// 392// Automatically generated file, do not edit! 393// 394//===----------------------------------------------------------------------===// 395 396""") 397 f.write('struct AvailableComponent {\n') 398 f.write(' /// The name of the component.\n') 399 f.write(' const char *Name;\n') 400 f.write('\n') 401 f.write(' /// The name of the library for this component (or NULL).\n') 402 f.write(' const char *Library;\n') 403 f.write('\n') 404 f.write(' /// Whether the component is installed.\n') 405 f.write(' bool IsInstalled;\n') 406 f.write('\n') 407 f.write('\ 408 /// The list of libraries required when linking this component.\n') 409 f.write(' const char *RequiredLibraries[%d];\n' % ( 410 max_required_libraries)) 411 f.write('} AvailableComponents[%d] = {\n' % len(entries)) 412 for name,library_name,required_names,is_installed in entries: 413 if library_name is None: 414 library_name_as_cstr = 'nullptr' 415 else: 416 library_name_as_cstr = '"%s"' % library_name 417 if is_installed: 418 is_installed_as_cstr = 'true' 419 else: 420 is_installed_as_cstr = 'false' 421 f.write(' { "%s", %s, %s, { %s } },\n' % ( 422 name, library_name_as_cstr, is_installed_as_cstr, 423 ', '.join('"%s"' % dep 424 for dep in required_names))) 425 f.write('};\n') 426 f.close() 427 428 if not os.path.isfile(output_path): 429 os.rename(output_path+'.new', output_path) 430 elif filecmp.cmp(output_path, output_path+'.new'): 431 os.remove(output_path+'.new') 432 else: 433 os.remove(output_path) 434 os.rename(output_path+'.new', output_path) 435 436 def get_required_libraries_for_component(self, ci, traverse_groups = False): 437 """ 438 get_required_libraries_for_component(component_info) -> iter 439 440 Given a Library component info descriptor, return an iterator over all 441 of the directly required libraries for linking with this component. If 442 traverse_groups is True, then library and target groups will be 443 traversed to include their required libraries. 444 """ 445 446 assert ci.type_name in ('Library', 'OptionalLibrary', 'LibraryGroup', 'TargetGroup') 447 448 for name in ci.required_libraries: 449 # Get the dependency info. 450 dep = self.component_info_map[name] 451 452 # If it is a library, yield it. 453 if dep.type_name == 'Library' or dep.type_name == 'OptionalLibrary': 454 yield dep 455 continue 456 457 # Otherwise if it is a group, yield or traverse depending on what 458 # was requested. 459 if dep.type_name in ('LibraryGroup', 'TargetGroup'): 460 if not traverse_groups: 461 yield dep 462 continue 463 464 for res in self.get_required_libraries_for_component(dep, True): 465 yield res 466 467 def get_fragment_dependencies(self): 468 """ 469 get_fragment_dependencies() -> iter 470 471 Compute the list of files (as absolute paths) on which the output 472 fragments depend (i.e., files for which a modification should trigger a 473 rebuild of the fragment). 474 """ 475 476 # Construct a list of all the dependencies of the Makefile fragment 477 # itself. These include all the LLVMBuild files themselves, as well as 478 # all of our own sources. 479 # 480 # Many components may come from the same file, so we make sure to unique 481 # these. 482 build_paths = set() 483 for ci in self.component_infos: 484 p = os.path.join(self.source_root, ci.subpath[1:], 'LLVMBuild.txt') 485 if p not in build_paths: 486 yield p 487 build_paths.add(p) 488 489 # Gather the list of necessary sources by just finding all loaded 490 # modules that are inside the LLVM source tree. 491 for module in sys.modules.values(): 492 # Find the module path. 493 if not hasattr(module, '__file__'): 494 continue 495 path = getattr(module, '__file__') 496 if not path: 497 continue 498 499 # Strip off any compiled suffix. 500 if os.path.splitext(path)[1] in ['.pyc', '.pyo', '.pyd']: 501 path = path[:-1] 502 503 # If the path exists and is in the source tree, consider it a 504 # dependency. 505 if (path.startswith(self.source_root) and os.path.exists(path)): 506 yield path 507 508 def foreach_cmake_library(self, f, 509 enabled_optional_components, 510 skip_disabled, 511 skip_not_installed): 512 for ci in self.ordered_component_infos: 513 # Skip optional components which are not enabled. 514 if ci.type_name == 'OptionalLibrary' \ 515 and ci.name not in enabled_optional_components: 516 continue 517 518 # We only write the information for libraries currently. 519 if ci.type_name not in ('Library', 'OptionalLibrary'): 520 continue 521 522 # Skip disabled targets. 523 if skip_disabled: 524 tg = ci.get_parent_target_group() 525 if tg and not tg.enabled: 526 continue 527 528 # Skip targets that will not be installed 529 if skip_not_installed and not ci.installed: 530 continue 531 532 f(ci) 533 534 535 def write_cmake_fragment(self, output_path, enabled_optional_components): 536 """ 537 write_cmake_fragment(output_path) -> None 538 539 Generate a CMake fragment which includes all of the collated LLVMBuild 540 information in a format that is easily digestible by a CMake. The exact 541 contents of this are closely tied to how the CMake configuration 542 integrates LLVMBuild, see CMakeLists.txt in the top-level. 543 """ 544 545 dependencies = list(self.get_fragment_dependencies()) 546 547 # Write out the CMake fragment. 548 make_install_dir(os.path.dirname(output_path)) 549 f = open(output_path, 'w') 550 551 # Write the header. 552 header_fmt = '\ 553#===-- %s - LLVMBuild Configuration for LLVM %s-*- CMake -*--===#' 554 header_name = os.path.basename(output_path) 555 header_pad = '-' * (80 - len(header_fmt % (header_name, ''))) 556 header_string = header_fmt % (header_name, header_pad) 557 f.write("""\ 558%s 559# 560# The LLVM Compiler Infrastructure 561# 562# This file is distributed under the University of Illinois Open Source 563# License. See LICENSE.TXT for details. 564# 565#===------------------------------------------------------------------------===# 566# 567# This file contains the LLVMBuild project information in a format easily 568# consumed by the CMake based build system. 569# 570# This file is autogenerated by llvm-build, do not edit! 571# 572#===------------------------------------------------------------------------===# 573 574""" % header_string) 575 576 # Write the dependency information in the best way we can. 577 f.write(""" 578# LLVMBuild CMake fragment dependencies. 579# 580# CMake has no builtin way to declare that the configuration depends on 581# a particular file. However, a side effect of configure_file is to add 582# said input file to CMake's internal dependency list. So, we use that 583# and a dummy output file to communicate the dependency information to 584# CMake. 585# 586# FIXME: File a CMake RFE to get a properly supported version of this 587# feature. 588""") 589 for dep in dependencies: 590 f.write("""\ 591configure_file(\"%s\" 592 ${CMAKE_CURRENT_BINARY_DIR}/DummyConfigureOutput)\n""" % ( 593 cmake_quote_path(dep),)) 594 595 # Write the properties we use to encode the required library dependency 596 # information in a form CMake can easily use directly. 597 f.write(""" 598# Explicit library dependency information. 599# 600# The following property assignments effectively create a map from component 601# names to required libraries, in a way that is easily accessed from CMake. 602""") 603 self.foreach_cmake_library( 604 lambda ci: 605 f.write("""\ 606set_property(GLOBAL PROPERTY LLVMBUILD_LIB_DEPS_%s %s)\n""" % ( 607 ci.get_prefixed_library_name(), " ".join(sorted( 608 dep.get_prefixed_library_name() 609 for dep in self.get_required_libraries_for_component(ci))))) 610 , 611 enabled_optional_components, 612 skip_disabled = False, 613 skip_not_installed = False # Dependency info must be emitted for internals libs too 614 ) 615 616 f.close() 617 618 def write_cmake_exports_fragment(self, output_path, enabled_optional_components): 619 """ 620 write_cmake_exports_fragment(output_path) -> None 621 622 Generate a CMake fragment which includes LLVMBuild library 623 dependencies expressed similarly to how CMake would write 624 them via install(EXPORT). 625 """ 626 627 dependencies = list(self.get_fragment_dependencies()) 628 629 # Write out the CMake exports fragment. 630 make_install_dir(os.path.dirname(output_path)) 631 f = open(output_path, 'w') 632 633 f.write("""\ 634# Explicit library dependency information. 635# 636# The following property assignments tell CMake about link 637# dependencies of libraries imported from LLVM. 638""") 639 self.foreach_cmake_library( 640 lambda ci: 641 f.write("""\ 642set_property(TARGET %s PROPERTY IMPORTED_LINK_INTERFACE_LIBRARIES %s)\n""" % ( 643 ci.get_prefixed_library_name(), " ".join(sorted( 644 dep.get_prefixed_library_name() 645 for dep in self.get_required_libraries_for_component(ci))))) 646 , 647 enabled_optional_components, 648 skip_disabled = True, 649 skip_not_installed = True # Do not export internal libraries like gtest 650 ) 651 652 f.close() 653 654 def write_make_fragment(self, output_path, enabled_optional_components): 655 """ 656 write_make_fragment(output_path) -> None 657 658 Generate a Makefile fragment which includes all of the collated 659 LLVMBuild information in a format that is easily digestible by a 660 Makefile. The exact contents of this are closely tied to how the LLVM 661 Makefiles integrate LLVMBuild, see Makefile.rules in the top-level. 662 """ 663 664 dependencies = list(self.get_fragment_dependencies()) 665 666 # Write out the Makefile fragment. 667 make_install_dir(os.path.dirname(output_path)) 668 f = open(output_path, 'w') 669 670 # Write the header. 671 header_fmt = '\ 672#===-- %s - LLVMBuild Configuration for LLVM %s-*- Makefile -*--===#' 673 header_name = os.path.basename(output_path) 674 header_pad = '-' * (80 - len(header_fmt % (header_name, ''))) 675 header_string = header_fmt % (header_name, header_pad) 676 f.write("""\ 677%s 678# 679# The LLVM Compiler Infrastructure 680# 681# This file is distributed under the University of Illinois Open Source 682# License. See LICENSE.TXT for details. 683# 684#===------------------------------------------------------------------------===# 685# 686# This file contains the LLVMBuild project information in a format easily 687# consumed by the Makefile based build system. 688# 689# This file is autogenerated by llvm-build, do not edit! 690# 691#===------------------------------------------------------------------------===# 692 693""" % header_string) 694 695 # Write the dependencies for the fragment. 696 # 697 # FIXME: Technically, we need to properly quote for Make here. 698 f.write("""\ 699# Clients must explicitly enable LLVMBUILD_INCLUDE_DEPENDENCIES to get 700# these dependencies. This is a compromise to help improve the 701# performance of recursive Make systems. 702""") 703 f.write('ifeq ($(LLVMBUILD_INCLUDE_DEPENDENCIES),1)\n') 704 f.write("# The dependencies for this Makefile fragment itself.\n") 705 f.write("%s: \\\n" % (mk_quote_string_for_target(output_path),)) 706 for dep in dependencies: 707 f.write("\t%s \\\n" % (dep,)) 708 f.write('\n') 709 710 # Generate dummy rules for each of the dependencies, so that things 711 # continue to work correctly if any of those files are moved or removed. 712 f.write("""\ 713# The dummy targets to allow proper regeneration even when files are moved or 714# removed. 715""") 716 for dep in dependencies: 717 f.write("%s:\n" % (mk_quote_string_for_target(dep),)) 718 f.write('endif\n') 719 720 f.write(""" 721# List of libraries to be exported for use by applications. 722# See 'cmake/modules/Makefile'. 723LLVM_LIBS_TO_EXPORT :=""") 724 self.foreach_cmake_library( 725 lambda ci: 726 f.write(' \\\n %s' % ci.get_prefixed_library_name()) 727 , 728 enabled_optional_components, 729 skip_disabled = True, 730 skip_not_installed = True # Do not export internal libraries like gtest 731 ) 732 f.write('\n') 733 f.close() 734 735def add_magic_target_components(parser, project, opts): 736 """add_magic_target_components(project, opts) -> None 737 738 Add the "magic" target based components to the project, which can only be 739 determined based on the target configuration options. 740 741 This currently is responsible for populating the required_libraries list of 742 the "all-targets", "Native", "NativeCodeGen", and "Engine" components. 743 """ 744 745 # Determine the available targets. 746 available_targets = dict((ci.name,ci) 747 for ci in project.component_infos 748 if ci.type_name == 'TargetGroup') 749 750 # Find the configured native target. 751 752 # We handle a few special cases of target names here for historical 753 # reasons, as these are the names configure currently comes up with. 754 native_target_name = { 'x86' : 'X86', 755 'x86_64' : 'X86', 756 'Unknown' : None }.get(opts.native_target, 757 opts.native_target) 758 if native_target_name is None: 759 native_target = None 760 else: 761 native_target = available_targets.get(native_target_name) 762 if native_target is None: 763 parser.error("invalid native target: %r (not in project)" % ( 764 opts.native_target,)) 765 if native_target.type_name != 'TargetGroup': 766 parser.error("invalid native target: %r (not a target)" % ( 767 opts.native_target,)) 768 769 # Find the list of targets to enable. 770 if opts.enable_targets is None: 771 enable_targets = available_targets.values() 772 else: 773 # We support both space separated and semi-colon separated lists. 774 if opts.enable_targets == '': 775 enable_target_names = [] 776 elif ' ' in opts.enable_targets: 777 enable_target_names = opts.enable_targets.split() 778 else: 779 enable_target_names = opts.enable_targets.split(';') 780 781 enable_targets = [] 782 for name in enable_target_names: 783 target = available_targets.get(name) 784 if target is None: 785 parser.error("invalid target to enable: %r (not in project)" % ( 786 name,)) 787 if target.type_name != 'TargetGroup': 788 parser.error("invalid target to enable: %r (not a target)" % ( 789 name,)) 790 enable_targets.append(target) 791 792 # Find the special library groups we are going to populate. We enforce that 793 # these appear in the project (instead of just adding them) so that they at 794 # least have an explicit representation in the project LLVMBuild files (and 795 # comments explaining how they are populated). 796 def find_special_group(name): 797 info = info_map.get(name) 798 if info is None: 799 fatal("expected project to contain special %r component" % ( 800 name,)) 801 802 if info.type_name != 'LibraryGroup': 803 fatal("special component %r should be a LibraryGroup" % ( 804 name,)) 805 806 if info.required_libraries: 807 fatal("special component %r must have empty %r list" % ( 808 name, 'required_libraries')) 809 if info.add_to_library_groups: 810 fatal("special component %r must have empty %r list" % ( 811 name, 'add_to_library_groups')) 812 813 info._is_special_group = True 814 return info 815 816 info_map = dict((ci.name, ci) for ci in project.component_infos) 817 all_targets = find_special_group('all-targets') 818 native_group = find_special_group('Native') 819 native_codegen_group = find_special_group('NativeCodeGen') 820 engine_group = find_special_group('Engine') 821 822 # Set the enabled bit in all the target groups, and append to the 823 # all-targets list. 824 for ci in enable_targets: 825 all_targets.required_libraries.append(ci.name) 826 ci.enabled = True 827 828 # If we have a native target, then that defines the native and 829 # native_codegen libraries. 830 if native_target and native_target.enabled: 831 native_group.required_libraries.append(native_target.name) 832 native_codegen_group.required_libraries.append( 833 '%sCodeGen' % native_target.name) 834 835 # If we have a native target with a JIT, use that for the engine. Otherwise, 836 # use the interpreter. 837 if native_target and native_target.enabled and native_target.has_jit: 838 engine_group.required_libraries.append('MCJIT') 839 engine_group.required_libraries.append(native_group.name) 840 else: 841 engine_group.required_libraries.append('Interpreter') 842 843def main(): 844 from optparse import OptionParser, OptionGroup 845 parser = OptionParser("usage: %prog [options]") 846 847 group = OptionGroup(parser, "Input Options") 848 group.add_option("", "--source-root", dest="source_root", metavar="PATH", 849 help="Path to the LLVM source (inferred if not given)", 850 action="store", default=None) 851 group.add_option("", "--llvmbuild-source-root", 852 dest="llvmbuild_source_root", 853 help=( 854 "If given, an alternate path to search for LLVMBuild.txt files"), 855 action="store", default=None, metavar="PATH") 856 group.add_option("", "--build-root", dest="build_root", metavar="PATH", 857 help="Path to the build directory (if needed) [%default]", 858 action="store", default=None) 859 parser.add_option_group(group) 860 861 group = OptionGroup(parser, "Output Options") 862 group.add_option("", "--print-tree", dest="print_tree", 863 help="Print out the project component tree [%default]", 864 action="store_true", default=False) 865 group.add_option("", "--write-llvmbuild", dest="write_llvmbuild", 866 help="Write out the LLVMBuild.txt files to PATH", 867 action="store", default=None, metavar="PATH") 868 group.add_option("", "--write-library-table", 869 dest="write_library_table", metavar="PATH", 870 help="Write the C++ library dependency table to PATH", 871 action="store", default=None) 872 group.add_option("", "--write-cmake-fragment", 873 dest="write_cmake_fragment", metavar="PATH", 874 help="Write the CMake project information to PATH", 875 action="store", default=None) 876 group.add_option("", "--write-cmake-exports-fragment", 877 dest="write_cmake_exports_fragment", metavar="PATH", 878 help="Write the CMake exports information to PATH", 879 action="store", default=None) 880 group.add_option("", "--write-make-fragment", 881 dest="write_make_fragment", metavar="PATH", 882 help="Write the Makefile project information to PATH", 883 action="store", default=None) 884 group.add_option("", "--configure-target-def-file", 885 dest="configure_target_def_files", 886 help="""Configure the given file at SUBPATH (relative to 887the inferred or given source root, and with a '.in' suffix) by replacing certain 888substitution variables with lists of targets that support certain features (for 889example, targets with AsmPrinters) and write the result to the build root (as 890given by --build-root) at the same SUBPATH""", 891 metavar="SUBPATH", action="append", default=None) 892 parser.add_option_group(group) 893 894 group = OptionGroup(parser, "Configuration Options") 895 group.add_option("", "--native-target", 896 dest="native_target", metavar="NAME", 897 help=("Treat the named target as the 'native' one, if " 898 "given [%default]"), 899 action="store", default=None) 900 group.add_option("", "--enable-targets", 901 dest="enable_targets", metavar="NAMES", 902 help=("Enable the given space or semi-colon separated " 903 "list of targets, or all targets if not present"), 904 action="store", default=None) 905 group.add_option("", "--enable-optional-components", 906 dest="optional_components", metavar="NAMES", 907 help=("Enable the given space or semi-colon separated " 908 "list of optional components"), 909 action="store", default="") 910 parser.add_option_group(group) 911 912 (opts, args) = parser.parse_args() 913 914 # Determine the LLVM source path, if not given. 915 source_root = opts.source_root 916 if source_root: 917 if not os.path.exists(os.path.join(source_root, 'lib', 'IR', 918 'Function.cpp')): 919 parser.error('invalid LLVM source root: %r' % source_root) 920 else: 921 llvmbuild_path = os.path.dirname(__file__) 922 llvm_build_path = os.path.dirname(llvmbuild_path) 923 utils_path = os.path.dirname(llvm_build_path) 924 source_root = os.path.dirname(utils_path) 925 if not os.path.exists(os.path.join(source_root, 'lib', 'IR', 926 'Function.cpp')): 927 parser.error('unable to infer LLVM source root, please specify') 928 929 # Construct the LLVM project information. 930 llvmbuild_source_root = opts.llvmbuild_source_root or source_root 931 project_info = LLVMProjectInfo.load_from_path( 932 source_root, llvmbuild_source_root) 933 934 # Add the magic target based components. 935 add_magic_target_components(parser, project_info, opts) 936 937 # Validate the project component info. 938 project_info.validate_components() 939 940 # Print the component tree, if requested. 941 if opts.print_tree: 942 project_info.print_tree() 943 944 # Write out the components, if requested. This is useful for auto-upgrading 945 # the schema. 946 if opts.write_llvmbuild: 947 project_info.write_components(opts.write_llvmbuild) 948 949 # Write out the required library table, if requested. 950 if opts.write_library_table: 951 project_info.write_library_table(opts.write_library_table, 952 opts.optional_components) 953 954 # Write out the make fragment, if requested. 955 if opts.write_make_fragment: 956 project_info.write_make_fragment(opts.write_make_fragment, 957 opts.optional_components) 958 959 # Write out the cmake fragment, if requested. 960 if opts.write_cmake_fragment: 961 project_info.write_cmake_fragment(opts.write_cmake_fragment, 962 opts.optional_components) 963 if opts.write_cmake_exports_fragment: 964 project_info.write_cmake_exports_fragment(opts.write_cmake_exports_fragment, 965 opts.optional_components) 966 967 # Configure target definition files, if requested. 968 if opts.configure_target_def_files: 969 # Verify we were given a build root. 970 if not opts.build_root: 971 parser.error("must specify --build-root when using " 972 "--configure-target-def-file") 973 974 # Create the substitution list. 975 available_targets = [ci for ci in project_info.component_infos 976 if ci.type_name == 'TargetGroup'] 977 substitutions = [ 978 ("@LLVM_ENUM_TARGETS@", 979 ' '.join('LLVM_TARGET(%s)' % ci.name 980 for ci in available_targets)), 981 ("@LLVM_ENUM_ASM_PRINTERS@", 982 ' '.join('LLVM_ASM_PRINTER(%s)' % ci.name 983 for ci in available_targets 984 if ci.has_asmprinter)), 985 ("@LLVM_ENUM_ASM_PARSERS@", 986 ' '.join('LLVM_ASM_PARSER(%s)' % ci.name 987 for ci in available_targets 988 if ci.has_asmparser)), 989 ("@LLVM_ENUM_DISASSEMBLERS@", 990 ' '.join('LLVM_DISASSEMBLER(%s)' % ci.name 991 for ci in available_targets 992 if ci.has_disassembler))] 993 994 # Configure the given files. 995 for subpath in opts.configure_target_def_files: 996 inpath = os.path.join(source_root, subpath + '.in') 997 outpath = os.path.join(opts.build_root, subpath) 998 result = configutil.configure_file(inpath, outpath, substitutions) 999 if not result: 1000 note("configured file %r hasn't changed" % outpath) 1001 1002if __name__=='__main__': 1003 main() 1004