| """Contains helper functions to compute checksums for LLVM checkouts. |
| """ |
| from __future__ import absolute_import |
| from __future__ import division |
| from __future__ import print_function |
| |
| import logging |
| import os |
| import os.path |
| import sys |
| |
| |
| class LLVMProject(object): |
| """An LLVM project with a descriptive name and a relative checkout path. |
| """ |
| |
| def __init__(self, name, relpath): |
| self.name = name |
| self.relpath = relpath |
| |
| def is_subproject(self, other_project): |
| """ Check if self is checked out as a subdirectory of other_project. |
| """ |
| return self.relpath.startswith(other_project.relpath) |
| |
| |
| def WalkProjectFiles(checkout_root, all_projects, project, visitor): |
| """ Walk over all files inside a project without recursing into subprojects, '.git' and '.svn' subfolders. |
| |
| checkout_root: root of the LLVM checkout. |
| all_projects: projects in the LLVM checkout. |
| project: a project to walk the files of. Must be inside all_projects. |
| visitor: a function called on each visited file. |
| """ |
| assert project in all_projects |
| |
| ignored_paths = set() |
| for other_project in all_projects: |
| if other_project != project and other_project.is_subproject(project): |
| ignored_paths.add(os.path.join(checkout_root, other_project.relpath)) |
| |
| def raise_error(err): |
| raise err |
| |
| project_root = os.path.join(checkout_root, project.relpath) |
| for root, dirs, files in os.walk(project_root, onerror=raise_error): |
| dirs[:] = [ |
| d for d in dirs |
| if d != ".svn" and d != ".git" and |
| os.path.join(root, d) not in ignored_paths |
| ] |
| for f in files: |
| visitor(os.path.join(root, f)) |
| |
| |
| def CreateLLVMProjects(single_tree_checkout): |
| """Returns a list of LLVMProject instances, describing relative paths of a typical LLVM checkout. |
| |
| Args: |
| single_tree_checkout: |
| When True, relative paths for each project points to a typical single |
| source tree checkout. |
| When False, relative paths for each projects points to a separate |
| directory. However, clang-tools-extra is an exception, its relative path |
| will always be 'clang/tools/extra'. |
| """ |
| # FIXME: cover all of llvm projects. |
| |
| # Projects that reside inside 'projects/' in a single source tree checkout. |
| ORDINARY_PROJECTS = [ |
| "compiler-rt", "dragonegg", "libcxx", "libcxxabi", "libunwind", |
| "parallel-libs", "test-suite" |
| ] |
| # Projects that reside inside 'tools/' in a single source tree checkout. |
| TOOLS_PROJECTS = ["clang", "lld", "lldb", "llgo"] |
| |
| if single_tree_checkout: |
| projects = [LLVMProject("llvm", "")] |
| projects += [ |
| LLVMProject(p, os.path.join("projects", p)) for p in ORDINARY_PROJECTS |
| ] |
| projects += [ |
| LLVMProject(p, os.path.join("tools", p)) for p in TOOLS_PROJECTS |
| ] |
| projects.append( |
| LLVMProject("clang-tools-extra", |
| os.path.join("tools", "clang", "tools", "extra"))) |
| else: |
| projects = [LLVMProject("llvm", "llvm")] |
| projects += [LLVMProject(p, p) for p in ORDINARY_PROJECTS] |
| projects += [LLVMProject(p, p) for p in TOOLS_PROJECTS] |
| projects.append( |
| LLVMProject("clang-tools-extra", os.path.join("clang", "tools", |
| "extra"))) |
| return projects |