| 1 | #!/usr/bin/env python3
|
|---|
| 2 |
|
|---|
| 3 | # Copyright (c) 2012 Google Inc. All rights reserved.
|
|---|
| 4 | # Use of this source code is governed by a BSD-style license that can be
|
|---|
| 5 | # found in the LICENSE file.
|
|---|
| 6 |
|
|---|
| 7 | """Prints the information in a sln file in a diffable way.
|
|---|
| 8 |
|
|---|
| 9 | It first outputs each projects in alphabetical order with their
|
|---|
| 10 | dependencies.
|
|---|
| 11 |
|
|---|
| 12 | Then it outputs a possible build order.
|
|---|
| 13 | """
|
|---|
| 14 |
|
|---|
| 15 |
|
|---|
| 16 | import os
|
|---|
| 17 | import re
|
|---|
| 18 | import sys
|
|---|
| 19 | import pretty_vcproj
|
|---|
| 20 |
|
|---|
| 21 | __author__ = "nsylvain (Nicolas Sylvain)"
|
|---|
| 22 |
|
|---|
| 23 |
|
|---|
| 24 | def BuildProject(project, built, projects, deps):
|
|---|
| 25 | # if all dependencies are done, we can build it, otherwise we try to build the
|
|---|
| 26 | # dependency.
|
|---|
| 27 | # This is not infinite-recursion proof.
|
|---|
| 28 | for dep in deps[project]:
|
|---|
| 29 | if dep not in built:
|
|---|
| 30 | BuildProject(dep, built, projects, deps)
|
|---|
| 31 | print(project)
|
|---|
| 32 | built.append(project)
|
|---|
| 33 |
|
|---|
| 34 |
|
|---|
| 35 | def ParseSolution(solution_file):
|
|---|
| 36 | # All projects, their clsid and paths.
|
|---|
| 37 | projects = dict()
|
|---|
| 38 |
|
|---|
| 39 | # A list of dependencies associated with a project.
|
|---|
| 40 | dependencies = dict()
|
|---|
| 41 |
|
|---|
| 42 | # Regular expressions that matches the SLN format.
|
|---|
| 43 | # The first line of a project definition.
|
|---|
| 44 | begin_project = re.compile(
|
|---|
| 45 | r'^Project\("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942'
|
|---|
| 46 | r'}"\) = "(.*)", "(.*)", "(.*)"$'
|
|---|
| 47 | )
|
|---|
| 48 | # The last line of a project definition.
|
|---|
| 49 | end_project = re.compile("^EndProject$")
|
|---|
| 50 | # The first line of a dependency list.
|
|---|
| 51 | begin_dep = re.compile(r"ProjectSection\(ProjectDependencies\) = postProject$")
|
|---|
| 52 | # The last line of a dependency list.
|
|---|
| 53 | end_dep = re.compile("EndProjectSection$")
|
|---|
| 54 | # A line describing a dependency.
|
|---|
| 55 | dep_line = re.compile(" *({.*}) = ({.*})$")
|
|---|
| 56 |
|
|---|
| 57 | in_deps = False
|
|---|
| 58 | solution = open(solution_file)
|
|---|
| 59 | for line in solution:
|
|---|
| 60 | results = begin_project.search(line)
|
|---|
| 61 | if results:
|
|---|
| 62 | # Hack to remove icu because the diff is too different.
|
|---|
| 63 | if results.group(1).find("icu") != -1:
|
|---|
| 64 | continue
|
|---|
| 65 | # We remove "_gyp" from the names because it helps to diff them.
|
|---|
| 66 | current_project = results.group(1).replace("_gyp", "")
|
|---|
| 67 | projects[current_project] = [
|
|---|
| 68 | results.group(2).replace("_gyp", ""),
|
|---|
| 69 | results.group(3),
|
|---|
| 70 | results.group(2),
|
|---|
| 71 | ]
|
|---|
| 72 | dependencies[current_project] = []
|
|---|
| 73 | continue
|
|---|
| 74 |
|
|---|
| 75 | results = end_project.search(line)
|
|---|
| 76 | if results:
|
|---|
| 77 | current_project = None
|
|---|
| 78 | continue
|
|---|
| 79 |
|
|---|
| 80 | results = begin_dep.search(line)
|
|---|
| 81 | if results:
|
|---|
| 82 | in_deps = True
|
|---|
| 83 | continue
|
|---|
| 84 |
|
|---|
| 85 | results = end_dep.search(line)
|
|---|
| 86 | if results:
|
|---|
| 87 | in_deps = False
|
|---|
| 88 | continue
|
|---|
| 89 |
|
|---|
| 90 | results = dep_line.search(line)
|
|---|
| 91 | if results and in_deps and current_project:
|
|---|
| 92 | dependencies[current_project].append(results.group(1))
|
|---|
| 93 | continue
|
|---|
| 94 |
|
|---|
| 95 | # Change all dependencies clsid to name instead.
|
|---|
| 96 | for project in dependencies:
|
|---|
| 97 | # For each dependencies in this project
|
|---|
| 98 | new_dep_array = []
|
|---|
| 99 | for dep in dependencies[project]:
|
|---|
| 100 | # Look for the project name matching this cldis
|
|---|
| 101 | for project_info in projects:
|
|---|
| 102 | if projects[project_info][1] == dep:
|
|---|
| 103 | new_dep_array.append(project_info)
|
|---|
| 104 | dependencies[project] = sorted(new_dep_array)
|
|---|
| 105 |
|
|---|
| 106 | return (projects, dependencies)
|
|---|
| 107 |
|
|---|
| 108 |
|
|---|
| 109 | def PrintDependencies(projects, deps):
|
|---|
| 110 | print("---------------------------------------")
|
|---|
| 111 | print("Dependencies for all projects")
|
|---|
| 112 | print("---------------------------------------")
|
|---|
| 113 | print("-- --")
|
|---|
| 114 |
|
|---|
| 115 | for (project, dep_list) in sorted(deps.items()):
|
|---|
| 116 | print("Project : %s" % project)
|
|---|
| 117 | print("Path : %s" % projects[project][0])
|
|---|
| 118 | if dep_list:
|
|---|
| 119 | for dep in dep_list:
|
|---|
| 120 | print(" - %s" % dep)
|
|---|
| 121 | print("")
|
|---|
| 122 |
|
|---|
| 123 | print("-- --")
|
|---|
| 124 |
|
|---|
| 125 |
|
|---|
| 126 | def PrintBuildOrder(projects, deps):
|
|---|
| 127 | print("---------------------------------------")
|
|---|
| 128 | print("Build order ")
|
|---|
| 129 | print("---------------------------------------")
|
|---|
| 130 | print("-- --")
|
|---|
| 131 |
|
|---|
| 132 | built = []
|
|---|
| 133 | for (project, _) in sorted(deps.items()):
|
|---|
| 134 | if project not in built:
|
|---|
| 135 | BuildProject(project, built, projects, deps)
|
|---|
| 136 |
|
|---|
| 137 | print("-- --")
|
|---|
| 138 |
|
|---|
| 139 |
|
|---|
| 140 | def PrintVCProj(projects):
|
|---|
| 141 |
|
|---|
| 142 | for project in projects:
|
|---|
| 143 | print("-------------------------------------")
|
|---|
| 144 | print("-------------------------------------")
|
|---|
| 145 | print(project)
|
|---|
| 146 | print(project)
|
|---|
| 147 | print(project)
|
|---|
| 148 | print("-------------------------------------")
|
|---|
| 149 | print("-------------------------------------")
|
|---|
| 150 |
|
|---|
| 151 | project_path = os.path.abspath(
|
|---|
| 152 | os.path.join(os.path.dirname(sys.argv[1]), projects[project][2])
|
|---|
| 153 | )
|
|---|
| 154 |
|
|---|
| 155 | pretty = pretty_vcproj
|
|---|
| 156 | argv = [
|
|---|
| 157 | "",
|
|---|
| 158 | project_path,
|
|---|
| 159 | "$(SolutionDir)=%s\\" % os.path.dirname(sys.argv[1]),
|
|---|
| 160 | ]
|
|---|
| 161 | argv.extend(sys.argv[3:])
|
|---|
| 162 | pretty.main(argv)
|
|---|
| 163 |
|
|---|
| 164 |
|
|---|
| 165 | def main():
|
|---|
| 166 | # check if we have exactly 1 parameter.
|
|---|
| 167 | if len(sys.argv) < 2:
|
|---|
| 168 | print('Usage: %s "c:\\path\\to\\project.sln"' % sys.argv[0])
|
|---|
| 169 | return 1
|
|---|
| 170 |
|
|---|
| 171 | (projects, deps) = ParseSolution(sys.argv[1])
|
|---|
| 172 | PrintDependencies(projects, deps)
|
|---|
| 173 | PrintBuildOrder(projects, deps)
|
|---|
| 174 |
|
|---|
| 175 | if "--recursive" in sys.argv:
|
|---|
| 176 | PrintVCProj(projects)
|
|---|
| 177 | return 0
|
|---|
| 178 |
|
|---|
| 179 |
|
|---|
| 180 | if __name__ == "__main__":
|
|---|
| 181 | sys.exit(main())
|
|---|