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