blob: 4533c65063093a0a35c5b029617783cdb0d1bebb [file] [log] [blame]
Daniel Dunbar25ff9f62013-08-14 23:15:39 +00001from __future__ import absolute_import
Peter Collingbourne4fdb6ec2014-11-19 03:34:20 +00002import filecmp
Daniel Dunbar01b05882011-11-03 17:56:03 +00003import os
Daniel Dunbar8844e3c2011-11-03 17:56:12 +00004import sys
Daniel Dunbar01b05882011-11-03 17:56:03 +00005
Daniel Dunbar25ff9f62013-08-14 23:15:39 +00006import llvmbuild.componentinfo as componentinfo
Daniel Dunbardd3fb562011-11-03 17:56:06 +00007
Anders Waldenborg91527ef2014-04-23 19:17:42 +00008from llvmbuild.util import fatal, note
Daniel Dunbar8844e3c2011-11-03 17:56:12 +00009
10###
11
Daniel Dunbar9057a3d2011-11-05 04:07:43 +000012def 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
Daniel Dunbar52f71222011-11-17 01:19:53 +000025def 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
Daniel Dunbar0edba5c92011-11-05 04:07:49 +000040def 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
Benjamin Kramerbde91762012-06-02 10:20:22 +000047 # os.makedirs considers it an error to be called with an existent path.
Daniel Dunbar0edba5c92011-11-05 04:07:49 +000048 if not os.path.exists(path):
49 os.makedirs(path)
50
Daniel Dunbarb814ee42011-11-04 23:40:11 +000051###
52
Daniel Dunbardd3fb562011-11-03 17:56:06 +000053class LLVMProjectInfo(object):
54 @staticmethod
55 def load_infos_from_path(llvmbuild_source_root):
Daniel Dunbare29ffff2011-12-12 22:45:59 +000056 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,))
Daniel Dunbardd3fb562011-11-03 17:56:06 +000062
Daniel Dunbare29ffff2011-12-12 22:45:59 +000063 # Parse the components from it.
64 common,info_iter = componentinfo.load_from_path(llvmbuild_path,
65 subpath)
66 for info in info_iter:
Daniel Dunbardd3fb562011-11-03 17:56:06 +000067 yield info
68
Daniel Dunbare29ffff2011-12-12 22:45:59 +000069 # 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
Daniel Dunbardd3fb562011-11-03 17:56:06 +000076 @staticmethod
77 def load_from_path(source_root, llvmbuild_source_root):
78 infos = list(
79 LLVMProjectInfo.load_infos_from_path(llvmbuild_source_root))
80
81 return LLVMProjectInfo(source_root, infos)
82
83 def __init__(self, source_root, component_infos):
Daniel Dunbar8844e3c2011-11-03 17:56:12 +000084 # Store our simple ivars.
Daniel Dunbardd3fb562011-11-03 17:56:06 +000085 self.source_root = source_root
Daniel Dunbar79fa1e82011-11-10 00:49:58 +000086 self.component_infos = list(component_infos)
87 self.component_info_map = None
88 self.ordered_component_infos = None
89
90 def validate_components(self):
91 """validate_components() -> None
92
93 Validate that the project components are well-defined. Among other
94 things, this checks that:
95 - Components have valid references.
96 - Components references do not form cycles.
97
98 We also construct the map from component names to info, and the
99 topological ordering of components.
100 """
Daniel Dunbardd3fb562011-11-03 17:56:06 +0000101
Daniel Dunbar8844e3c2011-11-03 17:56:12 +0000102 # Create the component info map and validate that component names are
103 # unique.
104 self.component_info_map = {}
Daniel Dunbar79fa1e82011-11-10 00:49:58 +0000105 for ci in self.component_infos:
Daniel Dunbar8844e3c2011-11-03 17:56:12 +0000106 existing = self.component_info_map.get(ci.name)
107 if existing is not None:
108 # We found a duplicate component name, report it and error out.
109 fatal("found duplicate component %r (at %r and %r)" % (
110 ci.name, ci.subpath, existing.subpath))
111 self.component_info_map[ci.name] = ci
112
Daniel Dunbar445e8f92011-11-03 17:56:28 +0000113 # Disallow 'all' as a component name, which is a special case.
114 if 'all' in self.component_info_map:
115 fatal("project is not allowed to define 'all' component")
116
Daniel Dunbarf45369d2011-11-03 17:56:18 +0000117 # Add the root component.
Daniel Dunbar48972552011-11-03 17:56:16 +0000118 if '$ROOT' in self.component_info_map:
119 fatal("project is not allowed to define $ROOT component")
120 self.component_info_map['$ROOT'] = componentinfo.GroupComponentInfo(
121 '/', '$ROOT', None)
Daniel Dunbarf45369d2011-11-03 17:56:18 +0000122 self.component_infos.append(self.component_info_map['$ROOT'])
Daniel Dunbar48972552011-11-03 17:56:16 +0000123
Daniel Dunbar8844e3c2011-11-03 17:56:12 +0000124 # Topologically order the component information according to their
125 # component references.
126 def visit_component_info(ci, current_stack, current_set):
127 # Check for a cycles.
128 if ci in current_set:
129 # We found a cycle, report it and error out.
130 cycle_description = ' -> '.join(
131 '%r (%s)' % (ci.name, relation)
132 for relation,ci in current_stack)
133 fatal("found cycle to %r after following: %s -> %s" % (
134 ci.name, cycle_description, ci.name))
135
136 # If we have already visited this item, we are done.
137 if ci not in components_to_visit:
138 return
139
140 # Otherwise, mark the component info as visited and traverse.
141 components_to_visit.remove(ci)
142
Daniel Dunbar48972552011-11-03 17:56:16 +0000143 # Validate the parent reference, which we treat specially.
Daniel Dunbarf45369d2011-11-03 17:56:18 +0000144 if ci.parent is not None:
145 parent = self.component_info_map.get(ci.parent)
146 if parent is None:
147 fatal("component %r has invalid reference %r (via %r)" % (
148 ci.name, ci.parent, 'parent'))
149 ci.set_parent_instance(parent)
Daniel Dunbar48972552011-11-03 17:56:16 +0000150
Daniel Dunbar8844e3c2011-11-03 17:56:12 +0000151 for relation,referent_name in ci.get_component_references():
152 # Validate that the reference is ok.
153 referent = self.component_info_map.get(referent_name)
154 if referent is None:
155 fatal("component %r has invalid reference %r (via %r)" % (
156 ci.name, referent_name, relation))
157
158 # Visit the reference.
159 current_stack.append((relation,ci))
160 current_set.add(ci)
161 visit_component_info(referent, current_stack, current_set)
162 current_set.remove(ci)
163 current_stack.pop()
164
165 # Finally, add the component info to the ordered list.
166 self.ordered_component_infos.append(ci)
167
Daniel Dunbar48972552011-11-03 17:56:16 +0000168 # FIXME: We aren't actually correctly checking for cycles along the
169 # parent edges. Haven't decided how I want to handle this -- I thought
170 # about only checking cycles by relation type. If we do that, it falls
171 # out easily. If we don't, we should special case the check.
172
Daniel Dunbar8844e3c2011-11-03 17:56:12 +0000173 self.ordered_component_infos = []
NAKAMURA Takumia1d528b2012-12-20 10:35:18 +0000174 components_to_visit = sorted(
175 set(self.component_infos),
176 key = lambda c: c.name)
Daniel Dunbar8844e3c2011-11-03 17:56:12 +0000177 while components_to_visit:
Daniel Dunbar25ff9f62013-08-14 23:15:39 +0000178 visit_component_info(components_to_visit[0], [], set())
Daniel Dunbar8844e3c2011-11-03 17:56:12 +0000179
Daniel Dunbarf45369d2011-11-03 17:56:18 +0000180 # 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):
Daniel Dunbar25ff9f62013-08-14 23:15:39 +0000186 print('%s%-40s (%s)' % (' '*depth, node.name, node.type_name))
Daniel Dunbarf45369d2011-11-03 17:56:18 +0000187 for c in node.children:
188 visit(c, depth + 1)
189 visit(self.component_info_map['$ROOT'])
190
Daniel Dunbardbbb2582011-11-03 17:56:21 +0000191 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
Daniel Dunbar8889bb02011-12-12 22:45:54 +0000202 # 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
Daniel Dunbardbbb2582011-11-03 17:56:21 +0000215 # 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.
Daniel Dunbar8889bb02011-12-12 22:45:54 +0000221 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
Daniel Dunbardbbb2582011-11-03 17:56:21 +0000241 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
Daniel Dunbarea07f342011-12-12 22:45:35 +0000251 # 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'):
Daniel Dunbar8889bb02011-12-12 22:45:54 +0000261 comments_map[ln[1:-2]] = comment_block
Daniel Dunbarea07f342011-12-12 22:45:35 +0000262 else:
263 comment_block = ""
264 f.close()
265
266 # Create the LLVMBuild fil[e.
Daniel Dunbardbbb2582011-11-03 17:56:21 +0000267 file_path = os.path.join(directory_path, 'LLVMBuild.txt')
268 f = open(file_path, "w")
Daniel Dunbar453146e2011-11-03 17:56:31 +0000269
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)
Daniel Dunbar25ff9f62013-08-14 23:15:39 +0000275 f.write("""\
Daniel Dunbar453146e2011-11-03 17:56:31 +0000276%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;===------------------------------------------------------------------------===;
Daniel Dunbar25ff9f62013-08-14 23:15:39 +0000292
293""" % header_string)
Daniel Dunbar453146e2011-11-03 17:56:31 +0000294
Daniel Dunbar8889bb02011-12-12 22:45:54 +0000295 # Write out each fragment.each component fragment.
296 for name,fragment in fragments:
Daniel Dunbarea07f342011-12-12 22:45:35 +0000297 comment = comments_map.get(name)
298 if comment is not None:
299 f.write(comment)
Daniel Dunbar25ff9f62013-08-14 23:15:39 +0000300 f.write("[%s]\n" % name)
Daniel Dunbardbbb2582011-11-03 17:56:21 +0000301 f.write(fragment)
Daniel Dunbar8889bb02011-12-12 22:45:54 +0000302 if fragment is not fragments[-1][1]:
Daniel Dunbar25ff9f62013-08-14 23:15:39 +0000303 f.write('\n')
Daniel Dunbar8889bb02011-12-12 22:45:54 +0000304
Daniel Dunbardbbb2582011-11-03 17:56:21 +0000305 f.close()
306
Preston Gurde65f4e62012-05-07 19:38:40 +0000307 def write_library_table(self, output_path, enabled_optional_components):
Daniel Dunbar445e8f92011-11-03 17:56:28 +0000308 # 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:
Daniel Dunbarf876da12012-05-15 18:44:12 +0000314 # Skip optional components which are not enabled.
Preston Gurde65f4e62012-05-07 19:38:40 +0000315 if c.type_name == 'OptionalLibrary' \
316 and c.name not in enabled_optional_components:
317 continue
318
Daniel Dunbarf876da12012-05-15 18:44:12 +0000319 # Skip target groups which are not enabled.
320 tg = c.get_parent_target_group()
321 if tg and not tg.enabled:
322 continue
323
Daniel Dunbar82219ad2011-11-10 00:49:51 +0000324 # Only certain components are in the table.
Preston Gurde65f4e62012-05-07 19:38:40 +0000325 if c.type_name not in ('Library', 'OptionalLibrary', \
326 'LibraryGroup', 'TargetGroup'):
Daniel Dunbar445e8f92011-11-03 17:56:28 +0000327 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()
Michael Kupersteinf9c34802014-10-29 09:18:49 +0000332
Daniel Dunbar445e8f92011-11-03 17:56:28 +0000333 # Get the library name, or None for LibraryGroups.
Preston Gurde65f4e62012-05-07 19:38:40 +0000334 if c.type_name == 'Library' or c.type_name == 'OptionalLibrary':
Daniel Dunbar06bb7982011-12-15 23:35:08 +0000335 library_name = c.get_prefixed_library_name()
Daniel Dunbarc364d682012-05-15 18:44:17 +0000336 is_installed = c.installed
Daniel Dunbar82219ad2011-11-10 00:49:51 +0000337 else:
338 library_name = None
Daniel Dunbarc364d682012-05-15 18:44:17 +0000339 is_installed = True
Daniel Dunbar445e8f92011-11-03 17:56:28 +0000340
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,
Daniel Dunbarc364d682012-05-15 18:44:17 +0000352 required_llvmconfig_component_names,
353 is_installed)
Daniel Dunbar445e8f92011-11-03 17:56:28 +0000354
355 # Convert to a list of entries and sort by name.
Daniel Dunbar25ff9f62013-08-14 23:15:39 +0000356 entries = list(entries.values())
Daniel Dunbar445e8f92011-11-03 17:56:28 +0000357
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)
Daniel Dunbarc364d682012-05-15 18:44:17 +0000361 for _,_,deps,_ in entries:
Daniel Dunbar445e8f92011-11-03 17:56:28 +0000362 root_entries -= set(deps)
Daniel Dunbarc364d682012-05-15 18:44:17 +0000363 entries.append(('all', None, root_entries, True))
Daniel Dunbar445e8f92011-11-03 17:56:28 +0000364
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)
Daniel Dunbarc364d682012-05-15 18:44:17 +0000370 for _,_,deps,_ in entries) + 1
Daniel Dunbar445e8f92011-11-03 17:56:28 +0000371
372 # Write out the library table.
Daniel Dunbar0edba5c92011-11-05 04:07:49 +0000373 make_install_dir(os.path.dirname(output_path))
Peter Collingbourne4fdb6ec2014-11-19 03:34:20 +0000374 f = open(output_path+'.new', 'w')
Daniel Dunbar25ff9f62013-08-14 23:15:39 +0000375 f.write("""\
Daniel Dunbar445e8f92011-11-03 17:56:28 +0000376//===- llvm-build generated file --------------------------------*- C++ -*-===//
377//
Nico Weber3a1b6972018-04-20 17:21:10 +0000378// Component Library Dependency Table
Daniel Dunbar445e8f92011-11-03 17:56:28 +0000379//
380// Automatically generated file, do not edit!
381//
382//===----------------------------------------------------------------------===//
Daniel Dunbar25ff9f62013-08-14 23:15:39 +0000383
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))
Daniel Dunbarc364d682012-05-15 18:44:17 +0000400 for name,library_name,required_names,is_installed in entries:
Daniel Dunbar445e8f92011-11-03 17:56:28 +0000401 if library_name is None:
Hans Wennborg083ca9b2015-10-06 23:24:35 +0000402 library_name_as_cstr = 'nullptr'
Daniel Dunbar445e8f92011-11-03 17:56:28 +0000403 else:
Ehsan Akhgari155ca8f2016-02-09 19:41:14 +0000404 library_name_as_cstr = '"%s"' % library_name
Hans Wennborg083ca9b2015-10-06 23:24:35 +0000405 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,
Daniel Dunbar445e8f92011-11-03 17:56:28 +0000411 ', '.join('"%s"' % dep
Daniel Dunbar25ff9f62013-08-14 23:15:39 +0000412 for dep in required_names)))
413 f.write('};\n')
Daniel Dunbar445e8f92011-11-03 17:56:28 +0000414 f.close()
415
Peter Collingbourne4fdb6ec2014-11-19 03:34:20 +0000416 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
Daniel Dunbar4128db92011-11-29 00:06:50 +0000424 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
Michael Kupersteinf9c34802014-10-29 09:18:49 +0000434 assert ci.type_name in ('Library', 'OptionalLibrary', 'LibraryGroup', 'TargetGroup')
Daniel Dunbar4128db92011-11-29 00:06:50 +0000435
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.
Michael Kupersteinf9c34802014-10-29 09:18:49 +0000441 if dep.type_name == 'Library' or dep.type_name == 'OptionalLibrary':
Daniel Dunbar4128db92011-11-29 00:06:50 +0000442 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
Daniel Dunbare9733852011-11-04 23:10:37 +0000455 def get_fragment_dependencies(self):
Daniel Dunbarab3b1802011-11-03 22:46:19 +0000456 """
Daniel Dunbare9733852011-11-04 23:10:37 +0000457 get_fragment_dependencies() -> iter
Daniel Dunbarab3b1802011-11-03 22:46:19 +0000458
Daniel Dunbare9733852011-11-04 23:10:37 +0000459 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).
Daniel Dunbarab3b1802011-11-03 22:46:19 +0000462 """
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.
Daniel Dunbarcda2a892011-12-06 23:13:42 +0000467 #
468 # Many components may come from the same file, so we make sure to unique
469 # these.
470 build_paths = set()
Daniel Dunbarab3b1802011-11-03 22:46:19 +0000471 for ci in self.component_infos:
Daniel Dunbarcda2a892011-12-06 23:13:42 +0000472 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)
Daniel Dunbarab3b1802011-11-03 22:46:19 +0000476
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)):
Daniel Dunbare9733852011-11-04 23:10:37 +0000494 yield path
495
Dan Liewa70fb6e2015-08-21 18:10:51 +0000496 def foreach_cmake_library(self, f,
497 enabled_optional_components,
Dan Liew1e3dc522015-08-21 18:10:57 +0000498 skip_disabled,
499 skip_not_installed):
Dan Liewa70fb6e2015-08-21 18:10:51 +0000500 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
Dan Liew1e3dc522015-08-21 18:10:57 +0000516 # Skip targets that will not be installed
517 if skip_not_installed and not ci.installed:
518 continue
519
Dan Liewa70fb6e2015-08-21 18:10:51 +0000520 f(ci)
521
522
Michael Kupersteinf9c34802014-10-29 09:18:49 +0000523 def write_cmake_fragment(self, output_path, enabled_optional_components):
Daniel Dunbare9733852011-11-04 23:10:37 +0000524 """
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.
Daniel Dunbar0edba5c92011-11-05 04:07:49 +0000536 make_install_dir(os.path.dirname(output_path))
Daniel Dunbare9733852011-11-04 23:10:37 +0000537 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)
Daniel Dunbar25ff9f62013-08-14 23:15:39 +0000545 f.write("""\
Daniel Dunbare9733852011-11-04 23:10:37 +0000546%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#===------------------------------------------------------------------------===#
Daniel Dunbar25ff9f62013-08-14 23:15:39 +0000561
562""" % header_string)
Daniel Dunbare9733852011-11-04 23:10:37 +0000563
564 # Write the dependency information in the best way we can.
Daniel Dunbar25ff9f62013-08-14 23:15:39 +0000565 f.write("""
Daniel Dunbare9733852011-11-04 23:10:37 +0000566# 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
Daniel Dunbar25ff9f62013-08-14 23:15:39 +0000575# feature.
576""")
Daniel Dunbare9733852011-11-04 23:10:37 +0000577 for dep in dependencies:
Daniel Dunbar25ff9f62013-08-14 23:15:39 +0000578 f.write("""\
Daniel Dunbare9733852011-11-04 23:10:37 +0000579configure_file(\"%s\"
Daniel Dunbar25ff9f62013-08-14 23:15:39 +0000580 ${CMAKE_CURRENT_BINARY_DIR}/DummyConfigureOutput)\n""" % (
581 cmake_quote_path(dep),))
Daniel Dunbar9057a3d2011-11-05 04:07:43 +0000582
Daniel Dunbar4128db92011-11-29 00:06:50 +0000583 # Write the properties we use to encode the required library dependency
584 # information in a form CMake can easily use directly.
Daniel Dunbar25ff9f62013-08-14 23:15:39 +0000585 f.write("""
Daniel Dunbar4128db92011-11-29 00:06:50 +0000586# Explicit library dependency information.
587#
588# The following property assignments effectively create a map from component
Daniel Dunbar25ff9f62013-08-14 23:15:39 +0000589# names to required libraries, in a way that is easily accessed from CMake.
590""")
Dan Liewa70fb6e2015-08-21 18:10:51 +0000591 self.foreach_cmake_library(
592 lambda ci:
593 f.write("""\
Daniel Dunbar25ff9f62013-08-14 23:15:39 +0000594set_property(GLOBAL PROPERTY LLVMBUILD_LIB_DEPS_%s %s)\n""" % (
Daniel Dunbar4128db92011-11-29 00:06:50 +0000595 ci.get_prefixed_library_name(), " ".join(sorted(
596 dep.get_prefixed_library_name()
Daniel Dunbar25ff9f62013-08-14 23:15:39 +0000597 for dep in self.get_required_libraries_for_component(ci)))))
Dan Liewa70fb6e2015-08-21 18:10:51 +0000598 ,
599 enabled_optional_components,
Dan Liew1e3dc522015-08-21 18:10:57 +0000600 skip_disabled = False,
601 skip_not_installed = False # Dependency info must be emitted for internals libs too
Dan Liewa70fb6e2015-08-21 18:10:51 +0000602 )
Daniel Dunbar4128db92011-11-29 00:06:50 +0000603
Daniel Dunbare9733852011-11-04 23:10:37 +0000604 f.close()
605
Michael Kupersteinf9c34802014-10-29 09:18:49 +0000606 def write_cmake_exports_fragment(self, output_path, enabled_optional_components):
NAKAMURA Takumi01e3c64f2014-02-09 16:37:02 +0000607 """
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""")
Dan Liewa70fb6e2015-08-21 18:10:51 +0000627 self.foreach_cmake_library(
628 lambda ci:
629 f.write("""\
NAKAMURA Takumi01e3c64f2014-02-09 16:37:02 +0000630set_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)))))
Dan Liewa70fb6e2015-08-21 18:10:51 +0000634 ,
635 enabled_optional_components,
Dan Liew1e3dc522015-08-21 18:10:57 +0000636 skip_disabled = True,
637 skip_not_installed = True # Do not export internal libraries like gtest
Dan Liewa70fb6e2015-08-21 18:10:51 +0000638 )
NAKAMURA Takumi01e3c64f2014-02-09 16:37:02 +0000639
640 f.close()
641
Daniel Dunbar233c9302011-11-10 00:50:07 +0000642def 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
Daniel Dunbar807c6e42011-11-10 01:16:48 +0000649 the "all-targets", "Native", "NativeCodeGen", and "Engine" components.
Daniel Dunbar233c9302011-11-10 00:50:07 +0000650 """
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:
Daniel Dunbar807c6e42011-11-10 01:16:48 +0000680 # We support both space separated and semi-colon separated lists.
Greg Fitzgerald986b4072014-04-18 17:39:50 +0000681 if opts.enable_targets == '':
682 enable_target_names = []
683 elif ' ' in opts.enable_targets:
Daniel Dunbar807c6e42011-11-10 01:16:48 +0000684 enable_target_names = opts.enable_targets.split()
685 else:
686 enable_target_names = opts.enable_targets.split(';')
687
Daniel Dunbar233c9302011-11-10 00:50:07 +0000688 enable_targets = []
Daniel Dunbar807c6e42011-11-10 01:16:48 +0000689 for name in enable_target_names:
Daniel Dunbar233c9302011-11-10 00:50:07 +0000690 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
Daniel Dunbar088f81b2011-12-12 22:45:41 +0000720 info._is_special_group = True
Daniel Dunbar233c9302011-11-10 00:50:07 +0000721 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:
Eric Christopher79cc1e32014-09-02 22:28:02 +0000745 engine_group.required_libraries.append('MCJIT')
Daniel Dunbar233c9302011-11-10 00:50:07 +0000746 engine_group.required_libraries.append(native_group.name)
747 else:
748 engine_group.required_libraries.append('Interpreter')
749
Daniel Dunbar01b05882011-11-03 17:56:03 +0000750def main():
751 from optparse import OptionParser, OptionGroup
752 parser = OptionParser("usage: %prog [options]")
Daniel Dunbarc83a4592011-11-10 00:49:42 +0000753
754 group = OptionGroup(parser, "Input Options")
755 group.add_option("", "--source-root", dest="source_root", metavar="PATH",
Daniel Dunbar01b05882011-11-03 17:56:03 +0000756 help="Path to the LLVM source (inferred if not given)",
757 action="store", default=None)
Daniel Dunbarc83a4592011-11-10 00:49:42 +0000758 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",
Daniel Dunbardbbb2582011-11-03 17:56:21 +0000770 help="Write out the LLVMBuild.txt files to PATH",
771 action="store", default=None, metavar="PATH")
Daniel Dunbarc83a4592011-11-10 00:49:42 +0000772 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)
NAKAMURA Takumi01e3c64f2014-02-09 16:37:02 +0000780 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)
Daniel Dunbarc83a4592011-11-10 00:49:42 +0000784 parser.add_option_group(group)
Daniel Dunbar233c9302011-11-10 00:50:07 +0000785
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",
Daniel Dunbar807c6e42011-11-10 01:16:48 +0000794 help=("Enable the given space or semi-colon separated "
795 "list of targets, or all targets if not present"),
Daniel Dunbarab3b1802011-11-03 22:46:19 +0000796 action="store", default=None)
Preston Gurde65f4e62012-05-07 19:38:40 +0000797 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"),
Daniel Dunbar25ff9f62013-08-14 23:15:39 +0000801 action="store", default="")
Daniel Dunbarc83a4592011-11-10 00:49:42 +0000802 parser.add_option_group(group)
803
Daniel Dunbar01b05882011-11-03 17:56:03 +0000804 (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:
Chandler Carruthef860a22013-01-02 09:10:48 +0000809 if not os.path.exists(os.path.join(source_root, 'lib', 'IR',
Daniel Dunbar01b05882011-11-03 17:56:03 +0000810 '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)
Chandler Carruthef860a22013-01-02 09:10:48 +0000817 if not os.path.exists(os.path.join(source_root, 'lib', 'IR',
Daniel Dunbar01b05882011-11-03 17:56:03 +0000818 'Function.cpp')):
819 parser.error('unable to infer LLVM source root, please specify')
820
Daniel Dunbardd3fb562011-11-03 17:56:06 +0000821 # 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
Daniel Dunbar233c9302011-11-10 00:50:07 +0000826 # Add the magic target based components.
827 add_magic_target_components(parser, project_info, opts)
828
Daniel Dunbar79fa1e82011-11-10 00:49:58 +0000829 # Validate the project component info.
830 project_info.validate_components()
831
Daniel Dunbarf45369d2011-11-03 17:56:18 +0000832 # Print the component tree, if requested.
833 if opts.print_tree:
834 project_info.print_tree()
835
Daniel Dunbardbbb2582011-11-03 17:56:21 +0000836 # 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
Daniel Dunbare9733852011-11-04 23:10:37 +0000841 # Write out the required library table, if requested.
Daniel Dunbar445e8f92011-11-03 17:56:28 +0000842 if opts.write_library_table:
Preston Gurde65f4e62012-05-07 19:38:40 +0000843 project_info.write_library_table(opts.write_library_table,
844 opts.optional_components)
Daniel Dunbar445e8f92011-11-03 17:56:28 +0000845
Daniel Dunbare9733852011-11-04 23:10:37 +0000846 # Write out the cmake fragment, if requested.
847 if opts.write_cmake_fragment:
Michael Kupersteinf9c34802014-10-29 09:18:49 +0000848 project_info.write_cmake_fragment(opts.write_cmake_fragment,
849 opts.optional_components)
NAKAMURA Takumi01e3c64f2014-02-09 16:37:02 +0000850 if opts.write_cmake_exports_fragment:
Michael Kupersteinf9c34802014-10-29 09:18:49 +0000851 project_info.write_cmake_exports_fragment(opts.write_cmake_exports_fragment,
852 opts.optional_components)
Daniel Dunbare9733852011-11-04 23:10:37 +0000853
Daniel Dunbar01b05882011-11-03 17:56:03 +0000854if __name__=='__main__':
855 main()