blob: cdd9196e322dfcd54456618dd51dfa546bc9fc00 [file] [log] [blame]
#!/usr/bin/env python2.7
# 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.
import argparse
import json
import os
import re
import sys
from common import FUCHSIA_ROOT
class Sdk(object):
SOURCE = 'source'
STATIC = 'static'
SHARED = 'shared'
NOPE = ''
class Library(object):
FINGERPRINT_PARAMS = ['kernel', 'static', 'shared', 'host']
PARAMS = FINGERPRINT_PARAMS + [ 'sdk_publishable' ]
def __init__(self, name, file):
self.name = name
self.file = os.path.relpath(file, os.path.join(FUCHSIA_ROOT, 'zircon'))
self.sdk = Sdk.NOPE
for param in Library.PARAMS:
setattr(self, param, False)
def set(self, param):
setattr(self, param, True)
def set_sdk(self, value):
self.sdk = value
def to_json(self):
result = {
'name': self.name,
'file': self.file,
}
for param in Library.PARAMS + ['sdk']:
result[param] = getattr(self, param, False)
return result
def fingerprint(self):
params = [p for p in Library.FINGERPRINT_PARAMS if getattr(self, p, False)]
return '|'.join(params) if params else 'none'
def __repr__(self):
return json.dumps(self.to_json(), indent=2, sort_keys=True,
separators=(',', ': '))
def get_library_stats(build_path):
result = []
with open(build_path, 'r') as build_file:
lines = build_file.readlines()
current_library = None
bracket_count = 0
for line in lines:
match = re.match('^\s*zx_library\("([^"]+)"\)\s*{$', line)
if match:
current_library = Library(match.group(1), build_path)
bracket_count = 1
continue
if not current_library:
continue
for param in Library.PARAMS:
if param + ' = true' in line:
current_library.set(param)
match = re.match('^\s*sdk = "([^"]+)"\s*$', line)
if match:
current_library.set_sdk(match.group(1))
bracket_count += line.count('{')
bracket_count -= line.count('}')
if bracket_count <= 0:
result.append(current_library)
current_library = None
bracket_count = 0
return result
class CustomJSONEncoder(json.JSONEncoder):
def default(self, object):
if isinstance(object, Library):
return object.to_json()
return json.JSONEncoder.default(self, object)
def main():
parser = argparse.ArgumentParser(description='Analyzes Zircon libraries')
parser.add_argument('--output',
help='file to write library information to',
required=False)
args = parser.parse_args()
libraries = []
for base, _, files in os.walk(os.path.join(FUCHSIA_ROOT, 'zircon')):
for file in files:
if file != 'BUILD.gn':
continue
build_path = os.path.join(base, file)
libraries.extend(get_library_stats(build_path))
if args.output:
with open(args.output, 'w') as output_file:
json.dump(libraries, output_file, cls=CustomJSONEncoder, indent=2,
sort_keys=True, separators=(',', ': '))
stats = {}
for lib in libraries:
fingerprint = lib.fingerprint()
stats[fingerprint] = stats.setdefault(fingerprint, 0) + 1
for stat in sorted(stats.items(), key=lambda item: item[1]):
print('{:>18}{:>5}'.format(*stat))
return 0
if __name__ == '__main__':
sys.exit(main())