main.py 38 KB

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