blob: 7e738387c78f5581fe0034aea3f1e29b418d15f4 [file] [log] [blame]
#!/usr/bin/env python3.8
# Copyright 2021 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.
"""Create a Component Manifest from a list of items"""
import json
import argparse
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
'--distribution_manifest_file',
type=argparse.FileType('r', encoding='UTF-8'),
help=
'Path to a distribution_manifest file which is a JSON file that contains driver paths.'
)
parser.add_argument(
'--output',
type=argparse.FileType('w', encoding='UTF-8'),
help='The path where this script will output the driver manifest.')
parser.add_argument(
'--is_v1',
action='store_const',
const=True,
default=False,
help=
'Generates a DFv1 component manifest. (If this is not included a DFv2 manifest is generated)'
)
parser.add_argument(
'--colocate',
action='store_true',
help='If this exists then the driver should be colocated with its parent'
)
parser.add_argument(
'--fallback',
action='store_true',
help='Whether or not the driver is a fallback driver')
parser.add_argument(
'--root_resource',
action='store_true',
help='Whether or not to give the driver access to the root resource')
parser.add_argument(
'--profile_provider',
action='store_true',
help=
'Whether or not to give the driver access to fuchsia.scheduler.ProfileProvider',
)
parser.add_argument(
'--sysmem',
action='store_true',
help=
'Whether or not to give the driver access to fuchsia.sysmem.Allocator',
)
parser.add_argument(
'--default_dispatcher_opts',
nargs="*",
help=
'A space separated list of options for creating the default dispatcher',
)
args = parser.parse_args()
distribution_manifest = json.load(args.distribution_manifest_file)
program = False
bind = False
for entry in distribution_manifest:
destination = entry['destination']
if destination.startswith("driver/"):
if destination == "driver/compat.so":
continue
if program:
raise Exception(
"fuchsia_driver_component cannot depend on two drivers: " +
program + " " + destination)
program = destination
if destination.startswith("meta/bind/"):
if bind:
raise Exception(
"fuchsia_driver_component cannot depend on two bind programs: "
+ bind + " " + destination)
bind = destination
if not program:
raise Exception("fuchsia_driver_component must contain a driver")
if not bind:
raise Exception("fuchsia_driver_component must contain a bind file")
manifest = {
'program':
{
'runner': 'driver',
'binary': program,
'bind': bind,
'fallback': 'true' if args.fallback else 'false'
},
'use': []
}
if args.is_v1:
manifest["program"]["binary"] = "driver/compat.so"
manifest["program"]["compat"] = program
manifest["include"] = [
'inspect/client.shard.cml',
'syslog/client.shard.cml',
]
manifest['use'] = [
{
'protocol': "fuchsia.device.fs.Exporter"
}, {
'service': "fuchsia.driver.compat.Service"
}, {
'protocol': "fuchsia.boot.Items"
}
]
manifest['capabilities'] = [
{
'service': "fuchsia.driver.compat.Service"
}
]
manifest['expose'] = [
{
'service': "fuchsia.driver.compat.Service",
'from': "self",
}
]
else:
manifest["program"]["binary"] = program
if args.colocate:
manifest["program"]["colocate"] = "true"
if args.root_resource:
manifest['use'].append({'protocol': "fuchsia.boot.RootResource"})
if args.profile_provider:
manifest['use'].append(
{'protocol': "fuchsia.scheduler.ProfileProvider"})
if args.sysmem:
manifest['use'].append({'protocol': "fuchsia.sysmem.Allocator"})
if args.default_dispatcher_opts:
manifest["program"][
"default_dispatcher_opts"] = args.default_dispatcher_opts
json_manifest = json.dumps(manifest)
args.output.write(json_manifest)
if __name__ == "__main__":
main()