You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
116 lines
4.0 KiB
116 lines
4.0 KiB
#!/usr/bin/env python
|
|
|
|
# Copyright 2018 The ANGLE Project Authors. All rights reserved.
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
|
|
# This tool will create a json description of the GN build environment that
|
|
# can then be used by gen_angle_android_bp.py to build an Android.bp file for
|
|
# the Android Soong build system.
|
|
# The input to this tool is a list of GN labels for which to capture the build
|
|
# information in json:
|
|
#
|
|
# Generating angle.json needs to be done from within a Chromium build:
|
|
# cd <chromium>/src
|
|
# gen_angle_gn_info_json.py //third_party/angle:libGLESv2 //third_party/angle:libEGL
|
|
#
|
|
# This will output an angle.json that can be copied to the angle directory
|
|
# within Android.
|
|
#
|
|
# Optional arguments:
|
|
# --gn_out <file> GN output config to use (e.g., out/Default or out/Debug.)
|
|
# --output <file> json file to create, default is angle.json
|
|
#
|
|
|
|
import argparse
|
|
import json
|
|
import logging
|
|
import subprocess
|
|
import sys
|
|
|
|
|
|
def get_json_description(gn_out, target_name):
|
|
try:
|
|
text_desc = subprocess.check_output(['gn', 'desc', '--format=json', gn_out, target_name])
|
|
except subprocess.CalledProcessError as e:
|
|
logging.error("e.retcode = %s" % e.returncode)
|
|
logging.error("e.cmd = %s" % e.cmd)
|
|
logging.error("e.output = %s" % e.output)
|
|
try:
|
|
json_out = json.loads(text_desc)
|
|
except ValueError:
|
|
raise ValueError("Unable to decode JSON\ncmd: %s\noutput:\n%s" % (subprocess.list2cmdline(
|
|
['gn', 'desc', '--format=json', gn_out, target_name]), text_desc))
|
|
|
|
return json_out
|
|
|
|
|
|
def load_json_deps(desc, gn_out, target_name, all_desc, indent=" "):
|
|
"""Extracts dependencies from the given target json description
|
|
and recursively extracts json descriptions.
|
|
|
|
desc: json description for target_name that includes dependencies
|
|
gn_out: GN output file with configuration info
|
|
target_name: name of target in desc to lookup deps
|
|
all_desc: dependent descriptions added here
|
|
indent: Print with indent to show recursion depth
|
|
"""
|
|
target = desc[target_name]
|
|
text_descriptions = []
|
|
for dep in target.get('deps', []):
|
|
if dep not in all_desc:
|
|
logging.debug("dep: %s%s" % (indent, dep))
|
|
new_desc = get_json_description(gn_out, dep)
|
|
all_desc[dep] = new_desc[dep]
|
|
load_json_deps(new_desc, gn_out, dep, all_desc, indent + " ")
|
|
else:
|
|
logging.debug("dup: %s%s" % (indent, dep))
|
|
|
|
|
|
def create_build_description(gn_out, targets):
|
|
"""Creates the JSON build description by running GN."""
|
|
|
|
logging.debug("targets = %s" % targets)
|
|
json_descriptions = {}
|
|
for target in targets:
|
|
logging.debug("target: %s" % (target))
|
|
target_desc = get_json_description(gn_out, target)
|
|
if (target in target_desc and target not in json_descriptions):
|
|
json_descriptions[target] = target_desc[target]
|
|
load_json_deps(target_desc, gn_out, target, json_descriptions)
|
|
else:
|
|
logging.debug("Invalid target: %s" % target)
|
|
return json_descriptions
|
|
|
|
|
|
def main():
|
|
logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
|
|
parser = argparse.ArgumentParser(
|
|
description='Generate json build information from a GN description.')
|
|
parser.add_argument(
|
|
'--gn_out',
|
|
help='GN output config to use (e.g., out/Default or out/Debug.)',
|
|
default='out/Default',
|
|
)
|
|
parser.add_argument(
|
|
'--output',
|
|
help='json file to create',
|
|
default='angle.json',
|
|
)
|
|
parser.add_argument(
|
|
'targets',
|
|
nargs=argparse.REMAINDER,
|
|
help='Targets to include in the json (e.g., "//libEGL")')
|
|
args = parser.parse_args()
|
|
|
|
desc = create_build_description(args.gn_out, args.targets)
|
|
fh = open(args.output, "w")
|
|
fh.write(json.dumps(desc, indent=4, sort_keys=True))
|
|
fh.close()
|
|
|
|
print("Output written to: %s" % args.output)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(main())
|