| # 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("//build/compiled_action.gni") | |
| import("//flutter/build/dart/rules.gni") | |
| import("//flutter/common/config.gni") | |
| is_aot_test = | |
| flutter_runtime_mode == "profile" || flutter_runtime_mode == "release" | |
| # Build unit tests when any of the following are true: | |
| # * host_toolchain: non-cross-compile, so we can run tests on the host. | |
| # * is_mac: arm64 builds can run x64 binaries. | |
| # * is_fuchsia: build unittests for testing on device. | |
| declare_args() { | |
| enable_unittests = current_toolchain == host_toolchain || is_fuchsia || is_mac | |
| } | |
| # Creates a translation unit that defines the flutter::testing::GetFixturesPath | |
| # method that tests can use to locate their fixtures. | |
| # | |
| # Arguments | |
| # assets_dir (required): The assets directory | |
| template("fixtures_location") { | |
| testonly = true | |
| assert(defined(invoker.assets_dir), "The assets directory.") | |
| location_path = rebase_path(invoker.assets_dir) | |
| testing_assets_path = rebase_path("$root_out_dir/gen/flutter/testing/assets") | |
| source_path = rebase_path("//") | |
| # Array of source lines. We use a list to ensure a trailing newline is | |
| # emitted by write_file() to comply with -Wnewline-eof. | |
| location_source = [ | |
| "namespace flutter { namespace testing { ", | |
| "const char* GetSourcePath() {return \"$source_path\";} ", | |
| "const char* GetFixturesPath() {return \"$location_path\";} ", | |
| "const char* GetTestingAssetsPath() {return \"$testing_assets_path\";} ", | |
| "}}", | |
| ] | |
| location_source_path = "$target_gen_dir/_fl_$target_name.cc" | |
| write_file(location_source_path, location_source) | |
| source_set(target_name) { | |
| public = [] | |
| sources = [ location_source_path ] | |
| } | |
| } | |
| # Generates the Dart kernel snapshot. | |
| # | |
| # Arguments | |
| # dart_main (required): The Main Dart file. | |
| # | |
| # dart_kernel (required): The path to the output kernel snapshot in the out | |
| # directory. | |
| template("dart_snapshot_kernel") { | |
| testonly = true | |
| assert(defined(invoker.dart_main), "The Dart Main file must be specified") | |
| assert(defined(invoker.dart_kernel), | |
| "The Dart Kernel file location must be specified") | |
| args = [] | |
| if (flutter_runtime_mode == "release" || | |
| flutter_runtime_mode == "jit_release") { | |
| args += [ "-Ddart.vm.product=true" ] | |
| } | |
| if (is_aot_test) { | |
| args += [ | |
| "--aot", | |
| # type flow analysis | |
| "--tfa", | |
| ] | |
| } | |
| flutter_frontend_server(target_name) { | |
| testonly = true | |
| main_dart = invoker.dart_main | |
| kernel_output = invoker.dart_kernel | |
| extra_args = args | |
| } | |
| } | |
| # Generates an AOT snapshot from a kernel snapshot. | |
| # | |
| # Arguments: | |
| # | |
| # dart_kernel (required): The path to the kernel snapshot. | |
| # | |
| # dart_elf_filename (required): The filename of the AOT ELF snapshot. | |
| template("dart_snapshot_aot") { | |
| testonly = true | |
| assert(defined(invoker.dart_kernel), | |
| "The Dart Kernel file location must be specified") | |
| assert(defined(invoker.dart_elf_filename), | |
| "The main Dart ELF filename must be specified.") | |
| compiled_action(target_name) { | |
| testonly = true | |
| tool = "$dart_src/runtime/bin:gen_snapshot" | |
| pool = "//build/toolchain:toolchain_pool" | |
| inputs = [ invoker.dart_kernel ] | |
| # Custom ELF loader is used for Mac and Windows. | |
| elf_object = "$target_gen_dir/assets/${invoker.dart_elf_filename}" | |
| loading_unit_manifest = "$target_gen_dir/assets/loading_unit_manifest.json" | |
| outputs = [ elf_object ] | |
| args = [ | |
| "--deterministic", | |
| "--snapshot_kind=app-aot-elf", | |
| "--loading_unit_manifest=" + rebase_path(loading_unit_manifest), | |
| "--elf=" + rebase_path(elf_object), | |
| rebase_path(invoker.dart_kernel), | |
| ] | |
| forward_variables_from(invoker, [ "deps" ]) | |
| } | |
| } | |
| # Generates a kernel or AOT snapshot as necessary from the main Dart file. | |
| # Other Dart dependencies referenced by that main Dart file will be tracked. | |
| # | |
| # Arguments: | |
| # | |
| # dart_main (required): The path to the main Dart file. | |
| # | |
| # dart_kernel_filename (required): The filename of the kernel blob. | |
| # | |
| # dart_elf_filename (required): The filename of the AOT ELF snapshot only if is_aot_test is true. | |
| template("dart_snapshot") { | |
| assert(defined(invoker.dart_main), "The main Dart file must be specified.") | |
| assert(defined(invoker.dart_kernel_filename), | |
| "The main Dart kernel filename must be specified.") | |
| testonly = true | |
| dart_snapshot_kernel_target_name = "_dsk_$target_name" | |
| dart_snapshot_kernel_path = | |
| "$target_gen_dir/assets/${invoker.dart_kernel_filename}" | |
| dart_snapshot_kernel(dart_snapshot_kernel_target_name) { | |
| dart_main = invoker.dart_main | |
| dart_kernel = dart_snapshot_kernel_path | |
| } | |
| snapshot_deps = [] | |
| snapshot_public_deps = [ ":$dart_snapshot_kernel_target_name" ] | |
| if (is_aot_test) { | |
| assert(defined(invoker.dart_elf_filename), | |
| "The main Dart ELF filename must be specified.") | |
| dart_snapshot_aot_target_name = "_dsa_$target_name" | |
| dart_snapshot_aot(dart_snapshot_aot_target_name) { | |
| dart_kernel = dart_snapshot_kernel_path | |
| dart_elf_filename = invoker.dart_elf_filename | |
| deps = [ ":$dart_snapshot_kernel_target_name" ] | |
| } | |
| snapshot_deps += [ ":$dart_snapshot_aot_target_name" ] | |
| } | |
| group(target_name) { | |
| testonly = true | |
| deps = snapshot_deps | |
| public_deps = snapshot_public_deps | |
| } | |
| } | |
| # Copies a (potentially empty) list of fixtures to the fixtures directory for | |
| # the unit test. | |
| # | |
| # Arguments: | |
| # | |
| # fixtures (required): The list of fixtures to copy. | |
| # | |
| # dest (optional): When specified, the fixtures are placed under an | |
| # 'assets' subdirectory of this path rather than an | |
| # 'assets' subdirectory of target_gen_dir. | |
| template("copy_fixtures") { | |
| testonly = true | |
| assert(defined(invoker.fixtures), "The test fixtures must be specified.") | |
| dest = target_gen_dir | |
| if (defined(invoker.dest)) { | |
| dest = invoker.dest | |
| } | |
| has_fixtures = false | |
| foreach(fixture, invoker.fixtures) { | |
| has_fixtures = true | |
| } | |
| if (has_fixtures) { | |
| copy(target_name) { | |
| sources = invoker.fixtures | |
| outputs = [ "$dest/assets/{{source_file_part}}" ] | |
| forward_variables_from(invoker, [ "deps" ]) | |
| } | |
| } else { | |
| group(target_name) { | |
| # The copy target cannot accept an empty list. | |
| } | |
| } | |
| } | |
| # Specifies the fixtures to copy to a location known by the specific unit test. | |
| # Test executable can only depend on one such target. You can use either one of | |
| # both arguments to expand this template. If you have none, then you'll see the | |
| # unused invoker scope error. In such cases specify the fixtures using an empty | |
| # array. | |
| # | |
| # The targets which generate the outputs from these test fixtures (e.g. the | |
| # Dart kernel snapshot) are exposed as public dependencies of the test fixture | |
| # target. This is so that users can depend on the test fixture target directly | |
| # and be able to access the generated outputs without needing to know about the | |
| # internal dependency structure generated by this template. | |
| # | |
| # Arguments: | |
| # | |
| # fixtures (optional): The list of test fixtures. An empty list may be | |
| # specified. | |
| # | |
| # dart_main (optional): The path to the main Dart file. If specified, it is | |
| # snapshotted. | |
| # | |
| # use_target_as_artifact_prefix(optional): If true, adds the target name as | |
| # prefix of the kernel and AOT ELF snapshot filename. | |
| # | |
| # dest (optional): When specified, the fixtures are placed under an | |
| # 'assets' subdirectory of this path rather than an | |
| # 'assets' subdirectory of target_gen_dir. | |
| template("test_fixtures") { | |
| dest = target_gen_dir | |
| if (defined(invoker.dest)) { | |
| dest = invoker.dest | |
| } | |
| # Not all paths use 'dest' | |
| not_needed([ "dest" ]) | |
| # Even if no fixtures are present, the location of the fixtures directory | |
| # must always be known to tests. | |
| fixtures_location_target_name = "_fl_$target_name" | |
| fixtures_location(fixtures_location_target_name) { | |
| if (is_fuchsia) { | |
| assets_dir = "/pkg/data/assets" | |
| } else { | |
| assets_dir = "$dest/assets" | |
| } | |
| } | |
| test_deps = [ ":$fixtures_location_target_name" ] | |
| test_public_deps = [] | |
| # If the fixtures are specified, copy them to the assets directory. | |
| if (defined(invoker.fixtures)) { | |
| copy_fixtures_target_name = "_cf_$target_name" | |
| copy_fixtures(copy_fixtures_target_name) { | |
| fixtures = invoker.fixtures | |
| dest = dest | |
| forward_variables_from(invoker, [ "deps" ]) | |
| } | |
| test_public_deps += [ ":$copy_fixtures_target_name" ] | |
| } | |
| # If a Dart file is specified, snapshot it and place it in the generated | |
| # assets directory. | |
| if (defined(invoker.dart_main)) { | |
| if (defined(invoker.use_target_as_artifact_prefix) && | |
| invoker.use_target_as_artifact_prefix) { | |
| artifact_prefix = "${target_name}_" | |
| } else { | |
| artifact_prefix = "" | |
| } | |
| dart_snapshot_target_name = "_ds_$target_name" | |
| dart_snapshot(dart_snapshot_target_name) { | |
| dart_main = invoker.dart_main | |
| dart_kernel_filename = "${artifact_prefix}kernel_blob.bin" | |
| if (is_aot_test) { | |
| dart_elf_filename = "${artifact_prefix}app_elf_snapshot.so" | |
| } | |
| } | |
| test_public_deps += [ ":$dart_snapshot_target_name" ] | |
| } | |
| group(target_name) { | |
| testonly = true | |
| deps = test_deps | |
| public_deps = test_public_deps | |
| } | |
| } |