| #!/usr/bin/env fuchsia-vendored-python | |
| # Copyright 2020 The Fuchsia Authors. All rights reserved. | |
| # Use of this source code is governed by a BSD-style license that can be | |
| # found in the LICENSE file. | |
| """ | |
| Compares two or more elf_sizes.json files. | |
| """ | |
| import argparse | |
| import json | |
| import sys | |
| from tabulate import tabulate | |
| FIELDS = [ | |
| "blob", | |
| "bss", | |
| "code", | |
| "data", | |
| "file", | |
| "memory", | |
| "rel", | |
| "rela", | |
| "relcount", | |
| "relr", | |
| "relro", | |
| "rodata", | |
| "zbi", | |
| ] | |
| def main(): | |
| parser = argparse.ArgumentParser(description=__doc__) | |
| parser.add_argument("--field", choices=FIELDS, default="code") | |
| parser.add_argument("file", nargs="+", metavar="elf_sizes.json") | |
| args = parser.parse_args() | |
| files = {} | |
| totals = [] | |
| def load(f): | |
| data = json.load(f) | |
| assert set(data["totals"].keys()) == set(FIELDS) | |
| for file in data["files"]: | |
| build_id = file["build_id"] | |
| if build_id: | |
| files.setdefault(file["path"], []).append(file) | |
| totals.append(data["totals"]) | |
| for file in args.file: | |
| with open(file) as f: | |
| load(f) | |
| table = [] | |
| header = ["path", "baseline"] | |
| for i, _ in enumerate(args.file[1:]): | |
| header.extend(["%s %d" % (args.field, i + 1), "ratio %d" % (i + 1)]) | |
| def compute_row(name, data, field): | |
| if not field in data[0]: | |
| return [0] * len(data) | |
| baseline = data[0][field] | |
| row = [name, baseline] | |
| for f in data[1:]: | |
| row.extend( | |
| [f[field], float(f[field]) / baseline if baseline else 0.0] | |
| ) | |
| return row | |
| for path in sorted(files.keys()): | |
| file = files[path] | |
| if len(file) < 2: | |
| print( | |
| "%s not present in every elf_sizes.json" % path, file=sys.stderr | |
| ) | |
| continue | |
| if len(set([f["build_id"] for f in file])) == 1: | |
| print("%s is unchanged" % path, file=sys.stderr) | |
| continue | |
| table.append(compute_row(path, file, args.field)) | |
| table.append(compute_row("TOTAL", totals, args.field)) | |
| print(tabulate(table, headers=header, floatfmt=".3f")) | |
| return 0 | |
| if __name__ == "__main__": | |
| sys.exit(main()) |