Merge "sourcedr: Add list_ninja_build_dep.py to list deps"
This commit is contained in:
115
vndk/tools/sourcedr/sourcedr/list_ninja_build_dep.py
Executable file
115
vndk/tools/sourcedr/sourcedr/list_ninja_build_dep.py
Executable file
@@ -0,0 +1,115 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""List all transitive build rules of a target."""
|
||||
|
||||
import argparse
|
||||
import itertools
|
||||
import posixpath
|
||||
import re
|
||||
|
||||
try:
|
||||
import cPickle as pickle # Python 2
|
||||
except ImportError:
|
||||
import pickle # Python 3
|
||||
|
||||
import ninja
|
||||
|
||||
|
||||
def _parse_args():
|
||||
"""Parse the command line arguments."""
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
# Ninja input file options
|
||||
parser.add_argument('input_file', help='input ninja file')
|
||||
parser.add_argument('--ninja-deps', help='.ninja_deps file')
|
||||
parser.add_argument('--cwd', help='working directory for ninja')
|
||||
parser.add_argument('--encoding', default='utf-8',
|
||||
help='ninja file encoding')
|
||||
|
||||
# Options
|
||||
parser.add_argument('target', help='build target')
|
||||
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def _load_manifest_from_args(args):
|
||||
"""Load the ninja file specified in the command line arguments."""
|
||||
|
||||
input_file = args.input_file
|
||||
|
||||
# If the input file name ends with `.pickle`, load it with pickle.load().
|
||||
if input_file.endswith('.pickle'):
|
||||
with open(input_file, 'rb') as pickle_file:
|
||||
return pickle.load(pickle_file)
|
||||
|
||||
# Parse the ninja file
|
||||
ninja_parser = ninja.Parser(args.cwd)
|
||||
return ninja_parser.parse(input_file, args.encoding, args.ninja_deps)
|
||||
|
||||
|
||||
def collect_build_targets(graph, target):
|
||||
"""Collect the transitive build targets."""
|
||||
|
||||
# Search for the first target
|
||||
build = graph[target]
|
||||
|
||||
# Collect all source files
|
||||
dfs = [build]
|
||||
|
||||
visited = {build}
|
||||
stack = [build]
|
||||
while stack:
|
||||
build = stack.pop()
|
||||
for dep in itertools.chain(build.explicit_ins, build.implicit_ins,
|
||||
build.depfile_implicit_ins):
|
||||
dep = graph.get(dep)
|
||||
if not dep:
|
||||
continue
|
||||
if dep not in visited:
|
||||
visited.add(dep)
|
||||
dfs.append(dep)
|
||||
stack.append(dep)
|
||||
|
||||
return dfs
|
||||
|
||||
|
||||
def main():
|
||||
args = _parse_args()
|
||||
|
||||
# Build lookup map
|
||||
manifest = _load_manifest_from_args(args)
|
||||
graph = {}
|
||||
for build in manifest.builds:
|
||||
for path in build.explicit_outs:
|
||||
graph[path] = build
|
||||
for path in build.implicit_outs:
|
||||
graph[path] = build
|
||||
|
||||
# List all transitive targets
|
||||
try:
|
||||
builds = collect_build_targets(graph, args.target)
|
||||
except KeyError:
|
||||
print('error: Failed to find the target {}'.format(arg.target),
|
||||
file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
# Print all targets
|
||||
for build in builds:
|
||||
print('build')
|
||||
for path in build.explicit_outs:
|
||||
print(' explicit_out:', path)
|
||||
for path in build.implicit_outs:
|
||||
print(' implicit_out:', path)
|
||||
for path in build.explicit_ins:
|
||||
print(' explicit_in:', path)
|
||||
for path in build.implicit_ins:
|
||||
print(' implicit_in:', path)
|
||||
for path in build.prerequisites:
|
||||
print(' prerequisites:', path)
|
||||
for path in build.depfile_implicit_ins:
|
||||
print(' depfile_implicit_in:', path)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user