blob: 6c06b45286ebca12902da655b44efac6bbc0a79a [file] [log] [blame]
# Copyright 2013 The Flutter 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("cmc.gni")
declare_args() {
# Enable code coverage for Fuchsia components. Only applies to v1 components.
fuchsia_code_coverage = false
}
# Defines a Fuchsia component.
# See: https://fuchsia.dev/fuchsia-src/glossary#component
#
# A component is defined by a component manifest.
# A component is a unit of executable software on Fuchsia. When the componet is executed, there are usually many files
# needed at runtime, such as the executable itself, shared libraries, and possibly other data resources. These files are
# specified by using the GN concept of "data_deps".
#
# Components are distributed using a fuchsia package which can contain multiple components. The component manifest and
# the runtime dependencies of the component are packaged using the fuchsia_package rule.
#
# By default, the runtime depenencies of the component are included in the package using relative paths calcualted from
# the "closest" root of: $root_gen_dir, $root_dir, $out_dir. If a specific path is desired in the package, the "resources" parameter can
# be used to explicitly specify the path of a specific file.
#
# A component is launched by a URL which identifies the package and the component manifest.
# See: https://fuchsia.dev/fuchsia-src/glossary#component_url
#
# Example
#
# ```
# fuchsia_component("my_component") {
# manifest = "meta/component-manifest.cmx"
# resources = [
# {
# path = "testdata/use_case1.json"
# dest = "data/testdata/use_case1.json"
# },
# ]
# data_deps = [ ":hello_world_executable"]
# }
# ```
#
# Parameters
#
# manifest
# The source manifest file for this component. This can be either v1 (.cmx)
# or v2 (.cml) manifest.
#
# Type: string (filepath)
#
# data_deps
# The labels of targets that generate the files needed at runtime by the component.
# At minimum, this should include the label of the binary to include in the component.
#
# Type: list of labels
#
# manifest_output_name [optional]
# The name of the manifest file contained in the distribution that this
# component is included in. The output name should have no extension or
# prefixes. The resulting filename will have the extension correct for the
# manifest version. For example, if `manifest` is "foo.cmx"
# and `manifest_output_name` is "bar", the filename will be "bar.cmx". If
# `manifest` is "foo.cml" (a v2 manifest), the filename will be "bar.cm".
#
# Type: string
# Default: The base file name of `manifest` without an extension.
#
# resources [optional]
# Lists additional files to include for runtime access by the component.
# Defines the resources in a package containing this component. A resource
# is a data file that may be produced by the build system, checked in to a
# source repository, or produced by another system that runs before the
# build. Resources are placed in the `data/` directory of the assembled
# package.
#
# Type: list of scopes. Entries in a scope in the resources list:
# path (required)
# Location of resource in source or build directory. If the
# resource is checked in, this will typically be specified
# as a path relative to the BUILD.gn file containing the
# `package()` target. If the resource is generated, this will
# typically be specified relative to `$target_gen_dir`.
#
# dest (required) string (path) Location the resource will be placed within `data/`.
#
# Standard parameters:
# deps
# testonly
# visibility
#
# Metadata
# contents - list of scopes describing files for this component. This metadata is consumed by
# The fuchsia_package rule, which describes the entries used.
# Entries in scope:
# type: the usage type of the element, manifest or resource.
# Each type can have specific properties included in the scope.
# source [type == manifest || resource] The source file to include in
# the package for this component. In the case of v2 components,
# this is the compiled manifest.
# output_name [type == manifest] The basename of the manifest as it should appear in the package.
# manifest_version [type == manifest]
# dest: [type == resource] The package relative path of the resource.
template("fuchsia_component") {
forward_variables_from(invoker,
[
"manifest",
"manifest_output_name",
])
assert(defined(manifest), "manifest file required for this component")
if (!defined(manifest_output_name)) {
manifest_output_name = get_path_info(manifest, "name")
}
# Determine manifest_version from the `manifest` file extension.
_manifest_extension = get_path_info(manifest, "extension")
assert(_manifest_extension == "cmx" || _manifest_extension == "cml",
"Manifest file extension must be .cmx or .cml")
if (_manifest_extension == "cmx") {
_manifest_version = "v1"
} else if (_manifest_extension == "cml") {
_manifest_version = "v2"
}
if (fuchsia_code_coverage) {
if (_manifest_version == "v1") {
merged_manifest = "${target_name}-coverage.cmx"
cmc_merge(merged_manifest) {
forward_variables_from(invoker,
[
"deps",
"testonly",
])
sources = [
"${fuchsia_sdk}/build/enable_coverage_data.cmx",
manifest,
]
output_name = merged_manifest
}
manifest = "${target_out_dir}/${merged_manifest}"
}
}
# The component manifest validated using cmx_validation for v1,
# or cmc_compile for v2.
_cm_validation_target =
"${target_name}_validate_" + get_path_info(manifest, "file")
if (_manifest_version == "v1") {
cmc_validate(_cm_validation_target) {
forward_variables_from(invoker, [ "testonly" ])
manifest = manifest
deps = []
if (defined(invoker.deps)) {
deps += invoker.deps
}
if (fuchsia_code_coverage) {
deps += [ ":${merged_manifest}" ]
}
}
_manifest_source = manifest
} else if (_manifest_version == "v2") {
cmc_compile(_cm_validation_target) {
forward_variables_from(invoker,
[
"deps",
"testonly",
])
manifest = rebase_path(manifest)
}
_compiled_manifest_outputs = get_target_outputs(":$_cm_validation_target")
_manifest_source = _compiled_manifest_outputs[0]
}
group(target_name) {
forward_variables_from(invoker,
[
"data",
"deps",
"data_deps",
"resources",
"resources_in_json_files",
"testonly",
"visibility",
])
# Data is used for adding files as runtime dependencies. Files used as
# sources in the resources parameter are added as data to make sure
# non-generated files listed are captured as dependencies.
if (!defined(data)) {
data = []
}
if (!defined(resources)) {
resources = []
}
# TODO(richkadel): Changed from the Fuchsia GN SDK to add
# `resources_in_json_files, so additional resources could be computed at
# compile time (in this case, compiled Dart libraries).
if (!defined(resources_in_json_files)) {
resources_in_json_files = []
}
if (!defined(deps)) {
deps = []
}
deps += [ ":$_cm_validation_target" ]
# Create the component metadata entries. These capture the manifest information and
# the resources parameter contents. The metadata is intended for the fuchsia_package rule.
component_contents = [
{
type = "manifest"
source = rebase_path(get_path_info(_manifest_source, "abspath"))
output_name = manifest_output_name
manifest_version = _manifest_version
},
]
foreach(resource, resources) {
data += [ resource.path ]
component_contents += [
{
type = "resource"
source = rebase_path(resource.path)
dest = resource.dest
},
]
}
foreach(file, resources_in_json_files) {
data += [ file ]
component_contents += [
{
type = "json_of_resources"
source = file
},
]
}
# The contents of the component are enumerated in the
# metadata.
metadata = {
contents = [ component_contents ]
}
}
}