Hash :
ed8d5ec7
        
        Author :
  
        
        Date :
2018-03-20T10:08:05
        
      
Add json build file generation gen_angle_gn_info_json.py can be used to generate a json description of the build for given targets. This information can then be used to generate build files for other tool chains (e.g. Android blueprint) Bug: angleproject:2418 Change-Id: Ief8f43e30ae1f469e3fcfa795306675e29a90a2f Reviewed-on: https://chromium-review.googlesource.com/967225 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Geoff Lang <geofflang@chromium.org>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
#!/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())