| # 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("//flutter/tools/executable_action.gni") |
| import("//flutter/tools/fuchsia/dart/config.gni") |
| import("//flutter/tools/fuchsia/dart/dart.gni") |
| import("//flutter/tools/fuchsia/dart/dart_package_config.gni") |
| import("//flutter/tools/fuchsia/dart/kernel/dart_kernel.gni") |
| import("//flutter/tools/fuchsia/gn-sdk/cmc.gni") |
| import("//flutter/tools/fuchsia/gn-sdk/component.gni") |
| |
| # Defines a component which will run in a flutter_runner or dart_runner |
| # |
| # This template is not intended to be used directly. Users should use the |
| # flutter_component and dart_component actions instead. |
| # |
| # Parameters |
| # |
| # manifest (required) |
| # The component manifest |
| # Type: path |
| # |
| # main_package (required) |
| # The name of the package containing the main_dart |
| # Type: string |
| # |
| # component_name (optional) |
| # The name of the component. |
| # Type: string |
| # Default: target_name |
| # |
| # build_cfg (required) |
| # A description of how to build this component. This object needs |
| # to contain the following variables: |
| # runtime_meta: a path to the partial cmx file containing the runner |
| # platform_name: either 'dart_runner' or 'flutter_runner' |
| # is_aot: a boolean indicating if this is an AOT build |
| # is_product: a boolean indicating if this is a product build |
| # enable_asserts: whether we should enable asserts when compiling |
| # |
| # main_dart (required) |
| # File containing the main function of the component. |
| # Type: string |
| # |
| # generate_asset_manifest (optional) |
| # If true, will generate an asset manifest for this component |
| # Type: boolean |
| # Default: false |
| # |
| # deps |
| # testonly |
| # visibility |
| template("flutter_dart_component") { |
| assert(defined(invoker.manifest), "must specify a manifest file") |
| assert(defined(invoker.build_cfg), "must specify build_cfg") |
| assert(defined(invoker.main_dart), "Must specify main_dart") |
| assert(defined(invoker.main_package), "Must specify main_package") |
| |
| build_cfg = invoker.build_cfg |
| |
| _component_deps = [] |
| if (defined(invoker.deps)) { |
| _component_deps += invoker.deps |
| } |
| |
| if (defined(invoker.component_name)) { |
| _component_name = invoker.component_name |
| } else { |
| _component_name = target_name |
| } |
| |
| _resources = [] |
| if (defined(invoker.resources)) { |
| _resources = invoker.resources |
| } |
| |
| # Flutter and Dart components need to run inside the runner which matches how |
| # they were compiled, for example, a JIT component must run in the JIT runner. |
| # We need to be able to dynamically convert the manifest files to include the |
| # runner requirements so that we can switch based on build modes. |
| _manifest_extension = get_path_info(invoker.manifest, "extension") |
| if (_manifest_extension == "cmx") { |
| # This is a v1 component, merge with the runtime_meta |
| _merged_target_name = "${target_name}_merged.cmx" |
| |
| cmc_merge(_merged_target_name) { |
| forward_variables_from(invoker, |
| [ |
| "testonly", |
| "visibility", |
| ]) |
| output_name = _merged_target_name |
| sources = [ |
| invoker.manifest, |
| rebase_path(build_cfg.runtime_meta, "."), |
| ] |
| } |
| |
| _merged_outputs = [] |
| _merged_outputs += get_target_outputs(":$_merged_target_name") |
| _manifest = _merged_outputs[0] |
| _manifest_output_name = "meta/" + _component_name + ".cmx" |
| |
| _component_deps += [ ":$_merged_target_name" ] |
| } else { |
| # This is a v2 component. |
| # The v2 runners have not been implemented yet so we just leave the manifest |
| # as is to avoid breaking the build. |
| _manifest = invoker.manifest |
| _manifest_output_name = "meta/" + _component_name + ".cm" |
| } |
| |
| _dart_package_config_target_name = "${target_name}_dart_package" |
| dart_package_config(_dart_package_config_target_name) { |
| forward_variables_from(invoker, |
| [ |
| "testonly", |
| "visibility", |
| ]) |
| |
| deps = _component_deps |
| } |
| |
| _package_config_output = [] |
| _package_config_output = |
| get_target_outputs(":$_dart_package_config_target_name") |
| _packages_path = _package_config_output[0] |
| |
| _kernel_target_name = _component_name + "_kernel" |
| _kernel_target_dep_name = _kernel_target_name + "_gen_file" |
| _kernel_path = "$target_gen_dir/__untraced_dart_kernel__/${target_name}.dil" |
| |
| dart_kernel(_kernel_target_name) { |
| kernel_path = _kernel_path |
| |
| # establishes a dependency chain for the snapshot since |
| # the kernel is wrapped in a group |
| kernel_target_name = _kernel_target_dep_name |
| |
| forward_variables_from(invoker, |
| [ |
| "testonly", |
| "visibility", |
| "main_dart", |
| "main_package", |
| ]) |
| |
| deps = [ ":$_dart_package_config_target_name" ] |
| |
| packages_path = _packages_path |
| args = [ |
| "--component-name", |
| _component_name, |
| ] |
| |
| # always generate a manifest for fuchsia builds. If this is an aot build |
| # the kernel will ignore this variable. |
| generate_manifest = true |
| |
| platform_name = build_cfg.platform_name |
| product = build_cfg.is_product |
| is_aot = build_cfg.is_aot |
| } |
| |
| _component_deps += [ ":$_kernel_target_name" ] |
| |
| if (build_cfg.is_aot) { |
| _snapshot_path = "$target_gen_dir/${_component_name}_snapshot.so" |
| _snapshot_target_name = target_name + "_snapshot" |
| |
| _stats_json_path = |
| "$target_gen_dir/${_component_name}/stats/symbol_sizes.json" |
| |
| if (build_cfg.is_product) { |
| _gen_snapshot_script_target = gen_snapshot_product |
| } else { |
| _gen_snapshot_script_target = gen_snapshot |
| } |
| |
| executable_action(_snapshot_target_name) { |
| forward_variables_from(invoker, |
| [ |
| "testonly", |
| "visibility", |
| ]) |
| |
| deps = [ ":$_kernel_target_dep_name" ] |
| inputs = [ _kernel_path ] |
| outputs = [ |
| _snapshot_path, |
| _stats_json_path, |
| ] |
| |
| if (defined(invoker.toolchain)) { |
| toolchain = invoker.toolchain |
| } else { |
| toolchain = host_toolchain |
| } |
| |
| # Construct the host toolchain version of the tool. |
| # host_tool = invoker.tool + "($toolchain)" |
| host_tool = _gen_snapshot_script_target + "($toolchain)" |
| |
| # Get the path to the executable. Currently, this assumes that the tool |
| # does not specify output_name so that the target name is the name to use. |
| # If that's not the case, we'll need another argument to the script to |
| # specify this, since we can't know what the output name is (it might be in |
| # another file not processed yet). |
| host_executable = |
| get_label_info(host_tool, "root_out_dir") + "/" + |
| get_label_info(host_tool, "name") + host_executable_suffix |
| |
| # Add the executable itself as an input. |
| inputs += [ host_executable ] |
| |
| deps += [ host_tool ] |
| |
| tool = host_executable |
| |
| args = [ |
| "--deterministic", |
| "--snapshot_kind=app-aot-elf", |
| "--elf=" + rebase_path(_snapshot_path, root_build_dir), |
| "--print-instructions-sizes-to=" + |
| rebase_path(_stats_json_path, root_build_dir), |
| ] |
| |
| # No asserts in debug or release product. |
| # No asserts in non-product release |
| # Yes asserts in non-product debug. |
| if (build_cfg.enable_asserts) { |
| args += [ "--enable_asserts" ] |
| } |
| args += [ rebase_path(_kernel_path, root_build_dir) ] |
| } |
| |
| _component_deps += [ ":$_snapshot_target_name" ] |
| } |
| |
| fuchsia_component(_component_name) { |
| forward_variables_from(invoker, |
| [ |
| "testonly", |
| "visibility", |
| ]) |
| deps = _component_deps |
| manifest = _manifest |
| manifest_output_name = _manifest_output_name |
| |
| if (build_cfg.is_aot) { |
| _resources += [ |
| { |
| path = _snapshot_path |
| dest = "data/${_component_name}/app_aot_snapshot.so" |
| }, |
| ] |
| } else { |
| _convert_kernel_target_name = |
| "${_kernel_target_name}_convert_kernel_manifest" |
| _convert_kernel_manifest_file = |
| # TODO(richkadel): This is prefixed by "dartlang/", which is not found. |
| # Is the current toolchain set incorrectly somewhere? |
| string_replace( |
| "${target_gen_dir}/${_convert_kernel_target_name}_kernel_manifest.json", |
| "dartlang/", |
| "") |
| |
| # TODO(richkadel): Adds the json resource names in the manifest to the |
| # collection of `json_of_resources` files, read by |
| # `prepare_package_inputs.py`. These resources are computed (only known) |
| # at some point during the build/compile phase. |
| resources_in_json_files = [ rebase_path(_convert_kernel_manifest_file) ] |
| } |
| |
| resources = _resources |
| } |
| |
| group(target_name) { |
| forward_variables_from(invoker, |
| [ |
| "testonly", |
| "visibility", |
| ]) |
| deps = [ ":" + _component_name ] |
| } |
| } |