| #!/usr/bin/env python |
| # Copyright 2011 The Chromium Authors |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| # based on an almost identical script by: jyrki@google.com (Jyrki Alakuijala) |
| |
| """Prints out include dependencies in chrome. |
| |
| Since it ignores defines, it gives just a rough estimation of file size. |
| |
| Usage: |
| tools/include_tracer.py -Iout/Default/gen chrome/browser/ui/browser.h |
| """ |
| |
| from __future__ import print_function |
| |
| import argparse |
| import os |
| import re |
| import sys |
| |
| # Created by copying the command line for prerender_browsertest.cc, replacing |
| # spaces with newlines, and dropping everything except -F and -I switches. |
| # TODO(port): Add windows, linux directories. |
| INCLUDE_PATHS = [ |
| '', |
| 'gpu', |
| 'skia/config', |
| 'skia/ext', |
| 'testing/gmock/include', |
| 'testing/gtest/include', |
| 'third_party/google_toolbox_for_mac/src', |
| 'third_party/icu/public/common', |
| 'third_party/icu/public/i18n', |
| 'third_party/protobuf', |
| 'third_party/protobuf/src', |
| 'third_party/skia/gpu/include', |
| 'third_party/skia/include/config', |
| 'third_party/skia/include/core', |
| 'third_party/skia/include/effects', |
| 'third_party/skia/include/gpu', |
| 'third_party/skia/include/pdf', |
| 'third_party/skia/include/ports', |
| 'v8/include', |
| ] |
| |
| |
| def Walk(include_dirs, seen, filename, parent, indent): |
| """Returns the size of |filename| plus the size of all files included by |
| |filename| and prints the include tree of |filename| to stdout. Every file |
| is visited at most once. |
| """ |
| total_bytes = 0 |
| |
| # .proto(devel) filename translation |
| if filename.endswith('.pb.h'): |
| basename = filename[:-5] |
| if os.path.exists(basename + '.proto'): |
| filename = basename + '.proto' |
| else: |
| print('could not find ', filename) |
| |
| # Show and count files only once. |
| if filename in seen: |
| return total_bytes |
| seen.add(filename) |
| |
| # Display the paths. |
| print(' ' * indent + filename) |
| |
| # Skip system includes. |
| if filename[0] == '<': |
| return total_bytes |
| |
| # Find file in all include paths. |
| resolved_filename = filename |
| for root in INCLUDE_PATHS + [os.path.dirname(parent)] + include_dirs: |
| if os.path.exists(os.path.join(root, filename)): |
| resolved_filename = os.path.join(root, filename) |
| break |
| |
| # Recurse. |
| if os.path.exists(resolved_filename): |
| lines = open(resolved_filename).readlines() |
| else: |
| print(' ' * (indent + 2) + "-- not found") |
| lines = [] |
| for line in lines: |
| line = line.strip() |
| match = re.match(r'#include\s+(\S+).*', line) |
| if match: |
| include = match.group(1) |
| if include.startswith('"'): |
| include = include[1:-1] |
| total_bytes += Walk( |
| include_dirs, seen, include, resolved_filename, indent + 2) |
| elif line.startswith('import '): |
| total_bytes += Walk( |
| include_dirs, seen, line.split('"')[1], resolved_filename, indent + 2) |
| return total_bytes + len("".join(lines)) |
| |
| |
| def main(): |
| parser = argparse.ArgumentParser() |
| parser.add_argument('-I', action='append', dest='include_dirs') |
| parser.add_argument('source_file') |
| options = parser.parse_args(sys.argv[1:]) |
| if not options.include_dirs: |
| options.include_dirs = [] |
| |
| bytes = Walk(options.include_dirs, set(), options.source_file, '', 0) |
| print() |
| print(float(bytes) / (1 << 20), "megabytes of chrome source") |
| |
| |
| if __name__ == '__main__': |
| sys.exit(main()) |