| # Copyright 2020 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/dist/resource.gni") |
| import("//tools/cmc/build/cml.gni") |
| import("//tools/cmc/build/cmx.gni") |
| |
| # Defines a Fuchsia component. |
| # See: https://fuchsia.dev/fuchsia-src/development/components/build |
| # |
| # A component is defined by a component manifest. |
| # Component manifests typically reference files in the package that they are |
| # distributed in. Therefore a component can also have dependencies on |
| # `resource()`, such that any package that depends on the component # will |
| # also include that resource. |
| # |
| # A component is launched by a URL. |
| # See: https://fuchsia.dev/fuchsia-src/glossary#component_url |
| # |
| # A component's URL is a function of the name of a package that includes it, |
| # and the path within that package to the component's manifest. For instance if |
| # you defined the following: |
| # ``` |
| # executable("my_program") { |
| # ... |
| # } |
| # |
| # fuchsia_component("my-component") { |
| # manifest = "manifest.cml" |
| # deps = [ ":my_program" ] |
| # } |
| # |
| # fuchsia_package("my-package") { |
| # deps = [ ":my-component" ] |
| # } |
| # ``` |
| # The component above will have the following launch URL: |
| # `fuchsia-pkg://fuchsia.com/my-package#meta/my-component.cm` |
| # |
| # Since the component depends on the executable target, the binary produced by |
| # the executable will be packaged with the manifest. Therefore the manifest |
| # author can reference the path `bin/my_program`. |
| # |
| # Components may depend on any number of `resource()` targets to ensure that |
| # any `fuchsia_package()` that includes them will include the same resources. |
| # |
| # ``` |
| # resource("my_file") { |
| # sources = [ "my_file.txt" ] |
| # outputs = [ "data/{{source_file_part}}" ] |
| # } |
| # |
| # fuchsia_component("my-component") { |
| # deps = [ ":my_file" ] |
| # ... |
| # } |
| # ``` |
| # |
| # The component defined above will be able to read my_file.txt under the path |
| # "/pkg/data/my_file.txt" in its sandbox. |
| # |
| # Parameters |
| # |
| # manifest (required) |
| # The component manifest. |
| # Type: path |
| # |
| # component_name (optional) |
| # The name of the component. |
| # Type: string |
| # Default: target_name |
| # |
| # deps |
| # testonly |
| # visibility |
| template("fuchsia_component") { |
| assert( |
| defined(invoker.manifest), |
| "A `manifest` argument was missing when calling fuchsia_component($target_name)") |
| |
| component_name = target_name |
| if (defined(invoker.component_name)) { |
| component_name = invoker.component_name |
| } |
| |
| # Handle different manifest versions |
| if (get_path_info(invoker.manifest, "extension") == "cml") { |
| manifest_processor = "cm" |
| manifest_name = "$component_name.cm" |
| } else if (get_path_info(invoker.manifest, "extension") == "cmx") { |
| manifest_processor = "cmx" |
| manifest_name = "$component_name.cmx" |
| } else { |
| assert( |
| false, |
| "Unknown manifest format for \"${invoker.manifest}\" passed to fuchsia_component($target_name)") |
| } |
| |
| manifest_resource_target = "${target_name}_manifest_resource" |
| |
| # Process the manifest |
| target(manifest_processor, target_name) { |
| output_name = manifest_name |
| forward_variables_from(invoker, |
| [ |
| "deps", |
| "manifest", |
| "testonly", |
| "visibility", |
| ]) |
| if (!defined(deps)) { |
| deps = [] |
| } |
| deps += [ ":$manifest_resource_target" ] |
| } |
| |
| # Add the manifest |
| resource(manifest_resource_target) { |
| sources = get_target_outputs(":${invoker.target_name}") |
| outputs = [ "meta/$manifest_name" ] |
| visibility = [ ":*" ] |
| metadata = { |
| component_manifests = [ rebase_path(sources[0], root_build_dir) ] |
| } |
| } |
| } |