blob: ee64b345c20a3887255a3e2e563144b96a2c0b23 [file] [log] [blame]
# 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.
import("//build/components/fuchsia_component.gni")
import("//build/dist/distribution_manifest.gni")
import("//build/drivers/driver_manifest.gni")
import("//tools/cmc/build/cmc.gni")
# Defines a Fuchsia driver component.
# A driver component is a normal component that launches a driver.
# For more information on components see:
# https://fuchsia.dev/fuchsia-src/development/components/build
#
# At the moment this template will generate the Component Manifest
# at build time. If you'd like to write your own Component Manifest,
# simply use the fuchsia_component build template.
#
# The component manifest is automatically generated that points to the
# correct driver library and bind file. If 'deps' includes more than
# one driver library or more than one bind file, this will cause a build-time
# error.
#
# Parameters
#
# manifest (optional)
# The component manifest. Either this or `cm_label` must be specified.
# Type: path
# cm_label (optional)
# A `fuchsia_component_manifest` target label. Either this or `manifest` must be specified.
# Type: GN label, e.g. `:my_manifest`
# is_v1_driver (optional)
# If this is true then the driver is a v1 driver and it will be placed in a
# compatibility shim when running in a DFv2 environment.
# Type: bool
# Default: true
# fallback (optional)
# If this is true then the driver is a fallback driver.
# Type: bool
# Default: false
# colocate
# If this is true, the driver will be put in the same DriverHost as its parent if possible. This
# is advisory, and the driver manager may still put the driver in a separate DriverHost, for
# instance if the parent device has MUST_ISOLATE set. In DFv1, a driver is always colocated if
# the parent device is a composite; isolation may still be enforced by setting MUST_ISOLATE on
# the primary fragment of the composite.
# Type: boolean
# uses_profiles (optional)
# If this is true, the driver will be given access to the profile provider service.
# Type: bool
# Default: false
# uses_sysmem (optional)
# If this is true, the driver will be given access to sysmem.
# Type: bool
# Default: false
# uses_boot_args (optional)
# If this is true, the driver will be given access to boot arguments service.
# Type: bool
# Default: false
# default_dispatcher_opts (optional)
# If this is set, then the default dispatcher for the driver will be
# created with these options.
# Type: array of strings
# Default: []
# default_dispatcher_scheduler_role (optional)
# If this is set, then the default dispatcher for the driver will be
# created with this scheduler role.
# Type: string
# Default: ""
# info (mandatory for //src and //zircon)
# Name of the file containing the driver information file.
# Type: file
# device_categories (optional)
# The device categories this driver is for. (The values must be from FHCP.json)
# This is a requirement for certification of the driver.
# Type: array of scopes
# applicable_licenses
# deps
# testonly
# visibility
template("fuchsia_driver_component") {
if (current_toolchain == default_toolchain) {
assert(!(defined(invoker.manifest) && defined(invoker.cm_label)),
"`manifest` and `cm_label` cannot be defined simultaneously")
assert(defined(invoker.manifest) || defined(invoker.cm_label),
"`manifest` or `cm_label` must be defined")
is_v1_driver = true
if (defined(invoker.is_v1_driver)) {
is_v1_driver = invoker.is_v1_driver
}
driver_path =
get_path_info(get_path_info(invoker.target_name, "abspath"), "dir")
splitted_path = string_split(driver_path, "/")
base_folder = splitted_path[2] # after removing "//"
create_driver_doc = false
if (base_folder == "src" || base_folder == "zircon") {
# Public drivers (defined as drivers in //src and //zircon) must provide an 'info' field with
# a driver information file.
assert(defined(invoker.info), "Must include driver info")
create_driver_doc = true
} else {
# Ignore info assignment if present, e.g. from //tools templates.
if (defined(invoker.info)) {
not_needed(invoker, [ "info" ])
}
}
if (create_driver_doc) {
doc_output = "${target_gen_dir}/${target_name}-doc.json"
doc_target = "${target_name}-driver-info"
name = invoker.target_name
if (defined(invoker.component_name)) {
name = invoker.component_name
}
doc_input = invoker.info
action(doc_target) {
visibility = [ ":*" ]
forward_variables_from(invoker,
[
"applicable_licenses",
"testonly",
])
script = "//build/drivers/create_driver_doc.py"
inputs = [
driver_path,
doc_input,
]
outputs = [ "${doc_output}" ]
args = [
"--name",
name,
"--driver_path",
driver_path,
"--doc_input",
rebase_path(doc_input, root_build_dir),
"--doc_output",
rebase_path(outputs[0], root_build_dir),
]
}
}
fuchsia_component(target_name) {
# TODO(https://fxbug.dev/42161384): Remove check_includes = false.
if (!defined(invoker.cm_label)) {
check_includes = false
}
forward_variables_from(invoker,
[
"applicable_licenses",
"cm_label",
"component_name",
"deps",
"manifest",
"manifest_deps",
"restricted_features",
"testonly",
"visibility",
])
if (!defined(deps)) {
deps = []
}
if (create_driver_doc) {
deps += [ ":${doc_target}" ]
not_needed(invoker, [ ":${doc_target}" ])
}
if (is_v1_driver) {
deps += [ "//src/devices/misc/drivers/compat:driver" ]
}
metadata = {
# Used by the assert_driver_components template.
driver_component_barrier = []
if (create_driver_doc) {
# Used by the create_all_drivers_doc template.
fuchsia_driver_doc_file = [ doc_output ]
}
}
}
} else {
group(target_name) {
forward_variables_from(invoker,
[
"applicable_licenses",
"testonly",
])
deps = [ ":$target_name($default_toolchain)" ]
}
not_needed(invoker, "*")
}
}