+import StringIO
import os
import sys
info_basedir[ci.subpath] = info_basedir.get(ci.subpath, []) + [ci]
+ # Compute the list of subdirectories to scan.
+ subpath_subdirs = {}
+ for ci in self.component_infos:
+ # Ignore root components.
+ if ci.subpath == '/':
+ continue
+
+ # Otherwise, append this subpath to the parent list.
+ parent_path = os.path.dirname(ci.subpath)
+ subpath_subdirs[parent_path] = parent_list = subpath_subdirs.get(
+ parent_path, set())
+ parent_list.add(os.path.basename(ci.subpath))
+
# Generate the build files.
for subpath, infos in info_basedir.items():
# Order the components by name to have a canonical ordering.
infos.sort(key = lambda ci: ci.name)
# Format the components into llvmbuild fragments.
- fragments = filter(None, [ci.get_llvmbuild_fragment()
- for ci in infos])
+ fragments = []
+
+ # Add the common fragments.
+ subdirectories = subpath_subdirs.get(subpath)
+ if subdirectories:
+ fragment = """\
+subdirectories = %s
+""" % (" ".join(sorted(subdirectories)),)
+ fragments.append(("common", fragment))
+
+ # Add the component fragments.
+ num_common_fragments = len(fragments)
+ for ci in infos:
+ fragment = ci.get_llvmbuild_fragment()
+ if fragment is None:
+ continue
+
+ name = "component_%d" % (len(fragments) - num_common_fragments)
+ fragments.append((name, fragment))
+
if not fragments:
continue
if not os.path.exists(directory_path):
os.makedirs(directory_path)
- # Create the LLVMBuild file.
+ # In an effort to preserve comments (which aren't parsed), read in
+ # the original file and extract the comments. We only know how to
+ # associate comments that prefix a section name.
+ f = open(infos[0]._source_path)
+ comments_map = {}
+ comment_block = ""
+ for ln in f:
+ if ln.startswith(';'):
+ comment_block += ln
+ elif ln.startswith('[') and ln.endswith(']\n'):
+ comments_map[ln[1:-2]] = comment_block
+ else:
+ comment_block = ""
+ f.close()
+
+ # Create the LLVMBuild fil[e.
file_path = os.path.join(directory_path, 'LLVMBuild.txt')
f = open(file_path, "w")
;===------------------------------------------------------------------------===;
""" % header_string
- for i,fragment in enumerate(fragments):
- print >>f, '[component_%d]' % i
+ # Write out each fragment.each component fragment.
+ for name,fragment in fragments:
+ comment = comments_map.get(name)
+ if comment is not None:
+ f.write(comment)
+ print >>f, "[%s]" % name
f.write(fragment)
- print >>f
+ if fragment is not fragments[-1][1]:
+ print >>f
+
f.close()
def write_library_table(self, output_path):
# Construct a list of all the dependencies of the Makefile fragment
# itself. These include all the LLVMBuild files themselves, as well as
# all of our own sources.
+ #
+ # Many components may come from the same file, so we make sure to unique
+ # these.
+ build_paths = set()
for ci in self.component_infos:
- yield os.path.join(self.source_root, ci.subpath[1:],
- 'LLVMBuild.txt')
+ p = os.path.join(self.source_root, ci.subpath[1:], 'LLVMBuild.txt')
+ if p not in build_paths:
+ yield p
+ build_paths.add(p)
# Gather the list of necessary sources by just finding all loaded
# modules that are inside the LLVM source tree.
fatal("special component %r must have empty %r list" % (
name, 'add_to_library_groups'))
+ info._is_special_group = True
return info
info_map = dict((ci.name, ci) for ci in project.component_infos)