| # 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 ] |
| } |
| } |
| } |