96 lines
3.0 KiB
Python
96 lines
3.0 KiB
Python
|
# Copyright 2013 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.
|
||
|
|
||
|
import json
|
||
|
import os
|
||
|
import string
|
||
|
import subprocess
|
||
|
import sys
|
||
|
|
||
|
|
||
|
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
||
|
|
||
|
|
||
|
def Run(*args):
|
||
|
with open(os.devnull, 'w') as null:
|
||
|
subprocess.check_call(args, stdout=null, stderr=null)
|
||
|
|
||
|
|
||
|
def FindNode(node, component):
|
||
|
for child in node['children']:
|
||
|
if child['name'] == component:
|
||
|
return child
|
||
|
return None
|
||
|
|
||
|
|
||
|
def InsertIntoTree(tree, source_name, size):
|
||
|
components = source_name.replace(':', '').split('\\')
|
||
|
node = tree
|
||
|
for index, component in enumerate(components):
|
||
|
data = FindNode(node, component)
|
||
|
if not data:
|
||
|
data = { 'name': component }
|
||
|
if index == len(components) - 1:
|
||
|
data['size'] = size
|
||
|
else:
|
||
|
data['children'] = []
|
||
|
node['children'].append(data)
|
||
|
node = data
|
||
|
|
||
|
|
||
|
def main():
|
||
|
out_dir = os.path.join(BASE_DIR, '..', '..', '..', 'out', 'Release')
|
||
|
jsons = []
|
||
|
for dll in ('chrome.dll', 'chrome_child.dll'):
|
||
|
dll_path = os.path.normpath(os.path.join(out_dir, dll))
|
||
|
if os.path.exists(dll_path):
|
||
|
print 'Tallying %s...' % dll_path
|
||
|
json_path = dll_path + '.json'
|
||
|
Run(os.path.join(BASE_DIR, 'code_tally.exe'),
|
||
|
'--input-image=' + dll_path,
|
||
|
'--input-pdb=' + dll_path + '.pdb',
|
||
|
'--output-file=' + json_path)
|
||
|
jsons.append(json_path)
|
||
|
if not jsons:
|
||
|
print 'Couldn\'t find binaries, looking in', out_dir
|
||
|
return 1
|
||
|
|
||
|
for json_name in jsons:
|
||
|
with open(json_name, 'r') as jsonf:
|
||
|
all_data = json.load(jsonf)
|
||
|
html_path = os.path.splitext(json_name)[0] + '.html'
|
||
|
print 'Generating %s...' % html_path
|
||
|
by_source = {}
|
||
|
for obj_name, obj_data in all_data['objects'].iteritems():
|
||
|
for symbol, symbol_data in obj_data.iteritems():
|
||
|
size = int(symbol_data['size'])
|
||
|
# Sometimes there's symbols with no source file, we just ignore those.
|
||
|
if 'contribs' in symbol_data:
|
||
|
# There may be more than one file in the list, we just assign to the
|
||
|
# first source file that contains the symbol, rather than try to
|
||
|
# split or duplicate info.
|
||
|
src_index = symbol_data['contribs'][0]
|
||
|
source = all_data['sources'][int(src_index)]
|
||
|
if source not in by_source:
|
||
|
by_source[source] = []
|
||
|
by_source[source].append(size)
|
||
|
binary_name = all_data['executable']['name']
|
||
|
data = {}
|
||
|
data['name'] = binary_name
|
||
|
data['children'] = []
|
||
|
for source, sizes in by_source.iteritems():
|
||
|
InsertIntoTree(data, source, sum(sizes))
|
||
|
with open(html_path, 'w') as f:
|
||
|
with open(os.path.join(BASE_DIR, 'template.html'), 'r') as templatef:
|
||
|
template = templatef.read()
|
||
|
f.write(string.Template(template).substitute(
|
||
|
{'data': json.dumps(data, indent=2),
|
||
|
'dllname': binary_name + ' ' + all_data['executable']['version']}))
|
||
|
|
||
|
return 0
|
||
|
|
||
|
|
||
|
if __name__ == '__main__':
|
||
|
sys.exit(main())
|