| # Copyright 2016 The Chromium Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| assert(is_fuchsia || is_fuchsia_host) |
| |
| import("//build/package.gni") |
| import("//build/tools/json_merge/json_merge.gni") |
| import("//peridot/build/module_manifest.gni") |
| import("//third_party/dart/build/dart/dart_action.gni") |
| import("//topaz/runtime/dart/config.gni") |
| import("//topaz/runtime/dart/dart_component.gni") |
| import("//topaz/runtime/dart/dart_kernel.gni") |
| |
| # Defines JIT runtime components to be further distributed in one package. |
| # |
| # Takes a set of flutter components and puts them into one fuchsia package with |
| # the flutter_jit_runner as its runtime. Also supports legacy calls where the |
| # components parameter isn't specified, in which we will create one default |
| # component for the package. |
| # |
| # Parameters |
| # |
| # components (required) |
| # [list of scopes] Defines the components in the package. Either main_dart |
| # or components must be defined, but not both. |
| # |
| # Entries in a scope in the resources list: |
| # |
| # component_name (required) |
| # Name of the component. |
| # |
| # main_dart (required) |
| # File containing the main function of the component. |
| # |
| # main_dart (required) |
| # File containing the main function of the application. Either main_dart or |
| # components must be defined, but not both. |
| template("_flutter_jit_component") { |
| pkg_name = target_name |
| legacy_component = false |
| if (!defined(invoker.components)) { |
| # If components is not specified, we are fitting main_dart into a component |
| # scope, and using that for the package. |
| # |
| # TODO(CP-140): Remove support for legacy_component once all existing calls |
| # to flutter_app() have a components parameter. |
| legacy_component = true |
| if (defined(invoker.fuchsia_package_name)) { |
| legacy_component_name = invoker.fuchsia_package_name |
| } else { |
| legacy_component_name = target_name |
| } |
| pkg_name = legacy_component_name |
| pkg_sources = [] |
| if (defined(invoker.sources)) { |
| pkg_sources = invoker.sources |
| } |
| components = [ |
| { |
| main_dart = invoker.main_dart |
| component_name = legacy_component_name |
| component_type = "flutter" |
| deps = invoker.deps |
| sources = pkg_sources |
| } |
| ] |
| } |
| flutter_dart_jit_component(target_name) { |
| forward_variables_from(invoker, "*") |
| } |
| } |
| |
| template("_flutter_aot_package") { |
| package(target_name) { |
| package_name = invoker.pkg_name |
| deps = invoker.cmx_deps |
| extra = [] |
| resources = [] |
| |
| if (defined(invoker.invoker_resources)) { |
| resources += invoker.invoker_resources |
| } |
| |
| foreach(component, invoker.components_with_kernel) { |
| extra += [ |
| component.asset_manifest, |
| ] |
| |
| deps += [ |
| ":${component.snapshot_target_name}", |
| ":${component.component_resources}", |
| ":${component.stats_target_name}", |
| ] + component.component_shared_snapshot_deps + component.deps |
| if (defined(invoker.module_manifest)) { |
| deps += [ |
| ":${component.component_copy_manifest}", |
| ":${component.component_verify_manifest}", |
| ] |
| } |
| |
| resources_path = "${component.component_name}/" |
| resources += [ |
| { |
| path = rebase_path(component.vm_snapshot_data_path) |
| dest = "${resources_path}vm_snapshot_data.bin" |
| }, |
| { |
| path = rebase_path(component.vm_snapshot_instructions_path) |
| dest = "${resources_path}vm_snapshot_instructions.bin" |
| }, |
| { |
| path = rebase_path(component.snapshot_data_path) |
| dest = "${resources_path}isolate_snapshot_data.bin" |
| }, |
| { |
| path = rebase_path(component.snapshot_instructions_path) |
| dest = "${resources_path}isolate_snapshot_instructions.bin" |
| }, |
| { |
| path = rebase_path(component.shared_snapshot_data_path) |
| dest = "${resources_path}shared_snapshot_data.bin" |
| }, |
| { |
| path = rebase_path(component.shared_snapshot_instructions_path) |
| dest = "${resources_path}shared_snapshot_instructions.bin" |
| }, |
| ] |
| } |
| |
| if (defined(invoker.non_dart_deps)) { |
| deps += invoker.non_dart_deps |
| } |
| |
| meta = invoker.cmx_filtered_meta |
| |
| # TODO(CP-140): Support module_manifest per component. |
| if (defined(invoker.module_manifest)) { |
| meta += [ |
| { |
| path = rebase_path(invoker.module_manifest) |
| dest = "module.json" |
| }, |
| ] |
| } |
| } |
| } |
| |
| # Defines AOT runtime components to be further distributed in one package. |
| # |
| # Takes a set of flutter components and puts them into one fuchsia package with |
| # the flutter_aot_runner as its runtime. Also supports legacy calls where the |
| # components parameter isn't specified, in which we will create one default |
| # component for the package. |
| # |
| # Parameters |
| # |
| # components (required) |
| # [list of scopes] Defines the components in the package. Either main_dart |
| # or components must be defined, but not both. |
| # |
| # Entries in a scope in the resources list: |
| # |
| # component_name (required) |
| # Name of the component. |
| # |
| # main_dart (required) |
| # File containing the main function of the component. |
| # |
| # main_dart (required) |
| # File containing the main function of the application. Either main_dart or |
| # components must be defined, but not both. |
| template("_flutter_aot_component") { |
| # This variable isn't needed in AOT builds. |
| if (defined(invoker.flutter_driver_extendable)) { |
| not_needed(invoker, ["flutter_driver_extendable",]) |
| } |
| legacy_component = false |
| pkg_name = target_name |
| components = [] |
| if (defined(invoker.components)) { |
| components += invoker.components |
| } else { |
| # If components is not specified, we are fitting main_dart into a component |
| # scope, and using that for the package. |
| # |
| # TODO(CP-140): Remove support for legacy_component once all existing calls |
| # to flutter_app() have a components parameter. |
| legacy_component = true |
| if (defined(invoker.fuchsia_package_name)) { |
| legacy_component_name = invoker.fuchsia_package_name |
| } else { |
| legacy_component_name = target_name |
| } |
| pkg_name = legacy_component_name |
| pkg_sources = [] |
| if (defined(invoker.sources)) { |
| pkg_sources = invoker.sources |
| } |
| components += [ |
| { |
| main_dart = invoker.main_dart |
| component_name = legacy_component_name |
| deps = invoker.deps |
| sources = pkg_sources |
| } |
| ] |
| } |
| |
| product = !flutter_profile |
| if (defined(invoker.product)) { |
| product = invoker.product |
| } |
| |
| if (dart_force_product) { |
| product = true |
| } |
| |
| product_suffix = "" |
| if (product) { |
| product_suffix = "_product" |
| } |
| |
| # Build the kernel for each of the components, and bundle them in the same |
| # scope for later packaging. |
| components_with_kernel = [] |
| foreach(component, components) { |
| assert(defined(component.main_dart), "Must specify main_dart file") |
| |
| component_name = component.component_name |
| if (legacy_component) { |
| kernel_name = target_name |
| } else { |
| kernel_name = component_name |
| } |
| dart_library_target_name = kernel_name + "_dart_library" |
| kernel_target_name = kernel_name + "_kernel" |
| kernel_path = "$target_gen_dir/${kernel_target_name}.dil" |
| |
| dart_kernel(kernel_name) { |
| platform_name = "flutter_runner" |
| platform_deps = |
| [ "//topaz/runtime/flutter_runner/kernel:kernel_platform_files" ] |
| platform_path = "$root_out_dir/flutter_runner_patched_sdk" |
| |
| forward_variables_from(invoker, |
| [ |
| "disable_analysis", |
| "non_dart_deps", |
| "source_dir", |
| "package_name", |
| ]) |
| deps = component.deps |
| sources = component.sources |
| |
| main_dart = component.main_dart |
| args = [ "--aot", "--tfa" ] |
| } |
| |
| # TODO(rmacnak): Don't bake the VM service into each app. |
| vm_snapshot_data_path = "$target_gen_dir/${kernel_name}_vm_data.aotsnapshot" |
| vm_snapshot_instructions_path = |
| "$target_gen_dir/${kernel_name}_vm_instructions.aotsnapshot" |
| snapshot_data_path = "$target_gen_dir/${kernel_name}_data.aotsnapshot" |
| snapshot_instructions_path = |
| "$target_gen_dir/${kernel_name}_instructions.aotsnapshot" |
| snapshot_target_name = kernel_name + "_snapshot" |
| |
| if (flutter_aot_sharing_basis != "" && |
| get_label_info(":$kernel_name", "label_no_toolchain") != |
| get_label_info(flutter_aot_sharing_basis, "label_no_toolchain")) { |
| # Note: The use of "label_no_toolchain" is to ensure we are comparing fully |
| # qualified target names. We don't actually care about the toolchain. |
| shared_snapshot_deps = [] |
| shared_snapshot_deps = |
| [ get_label_info(flutter_aot_sharing_basis, "label_no_toolchain") + |
| "_snapshot" ] |
| prefix = get_label_info(flutter_aot_sharing_basis, "target_gen_dir") + "/" + |
| get_label_info(flutter_aot_sharing_basis, "name") |
| shared_snapshot_data_path = "${prefix}_data.aotsnapshot" |
| shared_snapshot_instructions_path = "${prefix}_instructions.aotsnapshot" |
| } else { |
| shared_snapshot_deps = [] |
| shared_snapshot_data_path = "//topaz/runtime/dart_runner/empty" |
| shared_snapshot_instructions_path = "//topaz/runtime/dart_runner/empty" |
| } |
| |
| stats_target_name = "${kernel_name}_stats" |
| stats_json_path = "$target_gen_dir/${kernel_name}/stats/symbol_sizes.json" |
| stats_html_dir = "$target_gen_dir/${kernel_name}/stats" |
| |
| action(snapshot_target_name) { |
| if (defined(invoker.testonly)) { |
| testonly = invoker.testonly |
| } |
| |
| deps = gen_snapshot_deps + shared_snapshot_deps + [ ":$kernel_target_name" ] |
| inputs = [ |
| shared_snapshot_data_path, |
| shared_snapshot_instructions_path, |
| kernel_path, |
| ] |
| outputs = [ |
| vm_snapshot_data_path, |
| vm_snapshot_instructions_path, |
| snapshot_data_path, |
| snapshot_instructions_path, |
| stats_json_path, |
| ] |
| |
| if (product) { |
| script = gen_snapshot_product |
| } else { |
| script = gen_snapshot |
| } |
| |
| args = [ |
| "--deterministic", |
| "--snapshot_kind=app-aot-blobs", |
| "--vm_snapshot_data=" + rebase_path(vm_snapshot_data_path), |
| "--vm_snapshot_instructions=" + |
| rebase_path(vm_snapshot_instructions_path), |
| "--isolate_snapshot_data=" + rebase_path(snapshot_data_path), |
| "--isolate_snapshot_instructions=" + |
| rebase_path(snapshot_instructions_path), |
| "--shared_data=" + rebase_path(shared_snapshot_data_path), |
| "--shared_instructions=" + rebase_path(shared_snapshot_instructions_path), |
| "--print-instructions-sizes-to=" + rebase_path(stats_json_path), |
| ] |
| if (is_debug && !product) { |
| args += [ "--enable_asserts" ] |
| } |
| args += [ rebase_path(kernel_path) ] |
| |
| pool = "//build/dart:dart_pool($dart_toolchain)" |
| } |
| |
| dart_action(stats_target_name) { |
| if (defined(invoker.testonly)) { |
| testonly = invoker.testonly |
| } |
| |
| deps = [ |
| ":$snapshot_target_name", |
| ] |
| script = "//third_party/dart/pkg/vm/bin/run_binary_size_analysis.dart" |
| inputs = [ |
| stats_json_path, |
| ] |
| outputs = [ |
| "$stats_html_dir/index.html", |
| ] |
| args = [ |
| rebase_path(stats_json_path), |
| rebase_path(stats_html_dir), |
| ] |
| } |
| |
| if (defined(invoker.resources)) { |
| invoker_resources = invoker.resources |
| } else { |
| invoker_resources = [] |
| } |
| |
| asset_manifest = "$target_gen_dir/build/${kernel_name}_pkgassets" |
| dart_target_gen_dir = |
| get_label_info(":bogus($dart_toolchain)", "target_gen_dir") |
| dot_packages = "$dart_target_gen_dir/$dart_library_target_name.packages" |
| |
| action("${kernel_name}_resources") { |
| script = "//topaz/runtime/flutter_runner/build/asset_package.py" |
| |
| args = [ |
| "--flutter-root", |
| rebase_path(flutter_base), |
| "--flutter-tools", |
| rebase_path(flutter_asset_tools_bin), |
| "--app-dir", |
| rebase_path("."), |
| "--asset-dir", |
| rebase_path("$target_gen_dir/build"), |
| "--packages", |
| rebase_path(dot_packages), |
| "--asset-manifest-out", |
| rebase_path(asset_manifest), |
| "--component-name", |
| component_name, |
| ] |
| |
| if (defined(invoker.manifest)) { |
| args += [ |
| "--manifest", |
| rebase_path(invoker.manifest), |
| ] |
| } |
| |
| deps = [ |
| ":$dart_library_target_name", |
| flutter_asset_tools_label, |
| ] |
| |
| outputs = [ |
| asset_manifest, |
| ] |
| } |
| |
| # The module manifest verify & copy targets. |
| if (defined(invoker.module_manifest)) { |
| verify_module_manifest("${kernel_name}_verify_manifest") { |
| original_target_name = kernel_name |
| module_manifest = invoker.module_manifest |
| } |
| copy_module_manifest("${kernel_name}_copy_manifest") { |
| package_name = kernel_name |
| module_manifest = rebase_path(invoker.module_manifest) |
| } |
| } |
| |
| components_with_kernel += [ |
| { |
| kernel_target_name = kernel_target_name |
| component_name = component_name |
| asset_manifest = asset_manifest |
| |
| snapshot_target_name = snapshot_target_name |
| stats_target_name = stats_target_name |
| vm_snapshot_data_path = vm_snapshot_data_path |
| vm_snapshot_instructions_path = vm_snapshot_instructions_path |
| snapshot_data_path = snapshot_data_path |
| snapshot_instructions_path = snapshot_instructions_path |
| shared_snapshot_data_path = shared_snapshot_data_path |
| shared_snapshot_instructions_path = shared_snapshot_instructions_path |
| |
| component_shared_snapshot_deps = shared_snapshot_deps |
| deps = component.deps |
| sources = component.sources |
| component_resources = "${kernel_name}_resources" |
| component_copy_manifest = "${kernel_name}_copy_manifest" |
| component_verify_manifest = "${kernel_name}_verify_manifest" |
| } |
| ] |
| } |
| |
| invoker_resources = [] |
| if (defined(invoker.resources)) { |
| invoker_resources += invoker.resources |
| } |
| |
| package_meta = [] |
| if (defined(invoker.meta)) { |
| package_meta = invoker.meta |
| } |
| |
| # Inject appropriate "runner" into Component manifests |
| cmx_filtered_meta = [] |
| cmx_deps = [] |
| found_cmx = false |
| foreach(item, package_meta) { |
| dest = item.path |
| if (defined(item.dest)) { |
| dest = item.dest |
| } |
| if (get_path_info(dest, "extension") == "cmx") { |
| found_cmx = true |
| merged = "merged_" + get_path_info(dest, "file") |
| json_merge(merged) { |
| sources = [ |
| item.path, |
| rebase_path( |
| "//topaz/runtime/flutter_runner/meta/aot${product_suffix}_runtime"), |
| ] |
| } |
| merged_outputs = [] |
| merged_outputs = get_target_outputs(":$merged") |
| item.path = merged_outputs[0] |
| cmx_deps += [ ":$merged" ] |
| } |
| cmx_filtered_meta += [ item ] |
| } |
| |
| if (!found_cmx) { |
| # No cmx to inject to. Inject the runner aspect as a dangling deprecated_runtime. |
| # CP-129: deprecate cmx-less components, then delete this. |
| cmx_filtered_meta += [ |
| { |
| path = rebase_path( |
| "//topaz/runtime/flutter_runner/meta/aot${product_suffix}_runtime") |
| dest = "deprecated_runtime" |
| }, |
| ] |
| } |
| |
| _flutter_aot_package(target_name) { |
| forward_variables_from(invoker, "*") |
| } |
| } |
| |
| template("flutter_jit_app") { |
| template_name = "_flutter_jit_component" |
| if (dart_force_product) { |
| template_name = flutter_product_app |
| } |
| |
| target(template_name, target_name) { |
| forward_variables_from(invoker, "*") |
| } |
| } |
| |
| template("flutter_aot_app") { |
| template_name = "_flutter_aot_component" |
| if (dart_force_product) { |
| template_name = flutter_product_app |
| } |
| |
| target(template_name, target_name) { |
| forward_variables_from(invoker, "*", ["space_dart"]) |
| } |
| } |
| |
| # Defines a Flutter application |
| # |
| # Parameters |
| # |
| # main_dart (required) |
| # Name of the Dart file containing the main function. Either main_dart or |
| # components must be defined, but not both. |
| # |
| # package_name (optional) |
| # Name of the Dart package. |
| # |
| # fuchsia_package_name (optional) |
| # Name of the Fuchsia package. |
| # |
| # deps (optional) |
| # List of Dart packages the application depends on. |
| # |
| # manifest (optional) |
| # Path to the manifest file |
| # |
| # disable_analysis (optional) |
| # Prevents analysis from being run on this target. |
| # |
| # product (optional) |
| # A boolean. Whether to build/run the app in a stripped-down Dart VM. |
| # Defaults to !is_debug. |
| # |
| # flutter_driver_extendable (optional) |
| # A boolean. Determines if, in a debug build, this package will be built |
| # with a wrapper that auto-enables flutter driver extensions when running |
| # the application in a an environment that includes TestRunner. Does not |
| # affect AOT or release builds. |
| # |
| # components (required) |
| # [list of scopes] Defines the components in the package. Either main_dart |
| # or components must be defined, but not both. |
| # |
| # Entries in a scope in the resources list: |
| # |
| # component_name (required) |
| # Name of the component. |
| # |
| # main_dart (required) |
| # File containing the main function of the component. |
| template("flutter_app") { |
| assert((defined(invoker.components) && !defined(invoker.main_dart)) || |
| (!defined(invoker.components) && defined(invoker.main_dart)), |
| "Only one of components or main_dart should be defined") |
| target(flutter_default_app, target_name) { |
| forward_variables_from(invoker, "*", [ "aot" ]) |
| } |
| } |