#!/usr/bin/env python # Copyright (c) 2011 The Chromium Authors. All rights reserved. # 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())