| #!/usr/bin/env python |
| # Copyright 2018 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. |
| # |
| # Generates a single BUILD.gn file with build targets generated using the |
| # manifest files in the SDK. |
| |
| import json |
| import os |
| import sys |
| |
| |
| # Inserted at the top of the generated BUILD.gn file. |
| _GENERATED_PREAMBLE = """# DO NOT EDIT! This file was generated by |
| # //third_party/fuchsia-sdk/gen_build_defs.py. |
| # Any changes made to this file will be discarded. |
| |
| import("//third_party/fuchsia-sdk/sdk/build/fuchsia_sdk_pkg.gni") |
| |
| """ |
| |
| def ReformatTargetName(dep_name): |
| """"Substitutes characters in |dep_name| which are not valid in GN target |
| names (e.g. dots become hyphens).""" |
| |
| reformatted_name = dep_name.replace('.','-') |
| return reformatted_name |
| |
| def ConvertCommonFields(json): |
| """Extracts fields from JSON manifest data which are used across all |
| target types. Note that FIDL packages do their own processing.""" |
| |
| return { |
| 'target_name': ReformatTargetName(json['name']), |
| 'public_deps': [':' + ReformatTargetName(dep) for dep in ( |
| json['deps'] + json.get('fidl_deps', []))] |
| } |
| |
| def FormatGNTarget(fields): |
| """Returns a GN target definition as a string. |
| |
| |fields|: The GN fields to include in the target body. |
| 'target_name' and 'type' are mandatory.""" |
| |
| output = '%s("%s") {\n' % (fields['type'], fields['target_name']) |
| del fields['target_name'] |
| del fields['type'] |
| |
| for key, val in fields.iteritems(): |
| if isinstance(val, str) or isinstance(val, unicode): |
| val_serialized = '\"%s\"' % val |
| elif isinstance(val, list): |
| # Serialize a list of strings in the prettiest possible manner. |
| if len(val) == 0: |
| val_serialized = '[]' |
| elif len(val) == 1: |
| val_serialized = '[ \"%s\" ]' % val[0] |
| else: |
| val_serialized = '[\n ' + ',\n '.join( |
| ['\"%s\"' % x for x in val]) + '\n ]' |
| else: |
| raise Exception('Could not serialize %r' % val) |
| |
| output += ' %s = %s\n' % (key, val_serialized) |
| output += '}' |
| |
| return output |
| |
| def ConvertToRedirectGroup(json): |
| """Creates a group() rule under the reformatted name, that redirects to the |
| SDK-provided rule. |
| |
| Arguments: |
| json: The parsed manifest JSON. |
| Returns: |
| The GN target definition, represented as a string.""" |
| |
| return { |
| 'public_deps': [ json['root'] ], |
| 'target_name': ReformatTargetName(json['name']), |
| 'type':'group', |
| } |
| |
| |
| def ConvertNoOp(json): |
| """Null implementation of a conversion function. No output is generated.""" |
| |
| return None |
| |
| |
| """Maps manifest types to conversion functions.""" |
| _CONVERSION_FUNCTION_MAP = { |
| 'fidl_library': ConvertToRedirectGroup, |
| 'cc_source_library': ConvertToRedirectGroup, |
| 'cc_prebuilt_library': ConvertToRedirectGroup, |
| |
| # No need to build targets for these types yet. |
| 'dart_library': ConvertNoOp, |
| 'device_profile': ConvertNoOp, |
| 'documentation': ConvertNoOp, |
| 'host_tool': ConvertNoOp, |
| 'image': ConvertNoOp, |
| 'loadable_module': ConvertNoOp, |
| 'sysroot': ConvertNoOp, |
| } |
| |
| |
| def ConvertSdkManifests(): |
| sdk_base_dir = os.path.join(os.path.dirname(__file__), 'sdk') |
| toplevel_meta = json.load(open(os.path.join(sdk_base_dir, 'meta', |
| 'manifest.json'))) |
| |
| build_output_path = os.path.join(sdk_base_dir, 'BUILD.gn') |
| with open(build_output_path, 'w') as buildfile: |
| buildfile.write(_GENERATED_PREAMBLE) |
| |
| for part in toplevel_meta['parts']: |
| parsed = json.load(open(os.path.join(sdk_base_dir, part['meta']))) |
| |
| convert_function = _CONVERSION_FUNCTION_MAP.get(part['type']) |
| if convert_function is None: |
| raise Exception('Unexpected SDK artifact type %s in %s.' % |
| (part['type'], part['meta'])) |
| |
| converted = convert_function(parsed) |
| if not converted: |
| continue |
| |
| buildfile.write(FormatGNTarget(converted) + '\n\n') |
| |
| if __name__ == '__main__': |
| sys.exit(ConvertSdkManifests()) |