1"""Contains helper functions to compute checksums for LLVM checkouts. 2""" 3from __future__ import absolute_import 4from __future__ import division 5from __future__ import print_function 6 7import logging 8import os 9import os.path 10import sys 11 12 13class LLVMProject(object): 14 """An LLVM project with a descriptive name and a relative checkout path. 15 """ 16 17 def __init__(self, name, relpath): 18 self.name = name 19 self.relpath = relpath 20 21 def is_subproject(self, other_project): 22 """ Check if self is checked out as a subdirectory of other_project. 23 """ 24 return self.relpath.startswith(other_project.relpath) 25 26 27def WalkProjectFiles(checkout_root, all_projects, project, visitor): 28 """ Walk over all files inside a project without recursing into subprojects, '.git' and '.svn' subfolders. 29 30 checkout_root: root of the LLVM checkout. 31 all_projects: projects in the LLVM checkout. 32 project: a project to walk the files of. Must be inside all_projects. 33 visitor: a function called on each visited file. 34 """ 35 assert project in all_projects 36 37 ignored_paths = set() 38 for other_project in all_projects: 39 if other_project != project and other_project.is_subproject(project): 40 ignored_paths.add(os.path.join(checkout_root, other_project.relpath)) 41 42 def raise_error(err): 43 raise err 44 45 project_root = os.path.join(checkout_root, project.relpath) 46 for root, dirs, files in os.walk(project_root, onerror=raise_error): 47 dirs[:] = [ 48 d for d in dirs 49 if d != ".svn" and d != ".git" and 50 os.path.join(root, d) not in ignored_paths 51 ] 52 for f in files: 53 visitor(os.path.join(root, f)) 54 55 56def CreateLLVMProjects(single_tree_checkout): 57 """Returns a list of LLVMProject instances, describing relative paths of a typical LLVM checkout. 58 59 Args: 60 single_tree_checkout: 61 When True, relative paths for each project points to a typical single 62 source tree checkout. 63 When False, relative paths for each projects points to a separate 64 directory. However, clang-tools-extra is an exception, its relative path 65 will always be 'clang/tools/extra'. 66 """ 67 # FIXME: cover all of llvm projects. 68 69 # Projects that reside inside 'projects/' in a single source tree checkout. 70 ORDINARY_PROJECTS = [ 71 "compiler-rt", "dragonegg", "libcxx", "libcxxabi", "libunwind", 72 "parallel-libs", "test-suite" 73 ] 74 # Projects that reside inside 'tools/' in a single source tree checkout. 75 TOOLS_PROJECTS = ["clang", "lld", "lldb"] 76 77 if single_tree_checkout: 78 projects = [LLVMProject("llvm", "")] 79 projects += [ 80 LLVMProject(p, os.path.join("projects", p)) for p in ORDINARY_PROJECTS 81 ] 82 projects += [ 83 LLVMProject(p, os.path.join("tools", p)) for p in TOOLS_PROJECTS 84 ] 85 projects.append( 86 LLVMProject("clang-tools-extra", 87 os.path.join("tools", "clang", "tools", "extra"))) 88 else: 89 projects = [LLVMProject("llvm", "llvm")] 90 projects += [LLVMProject(p, p) for p in ORDINARY_PROJECTS] 91 projects += [LLVMProject(p, p) for p in TOOLS_PROJECTS] 92 projects.append( 93 LLVMProject("clang-tools-extra", os.path.join("clang", "tools", 94 "extra"))) 95 return projects 96