blob: 5d4d757aaabe593c86e4d0e77402b690fd64e73a [file] [log] [blame]
#!/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())