[flutter_runner] Optionally create the framework snapshot from a prebuilt Flutter program.
Add required analysis_options.yaml and silence the resulting bad advice.
Change-Id: Ia793a0dab06aa99c6f0a5f8a5b2263877e5f8c61
diff --git a/runtime/flutter_runner/BUILD.gn b/runtime/flutter_runner/BUILD.gn
index 83e837d..34ff1bb 100644
--- a/runtime/flutter_runner/BUILD.gn
+++ b/runtime/flutter_runner/BUILD.gn
@@ -4,10 +4,12 @@
assert(is_fuchsia)
+import("//build/package.gni")
import("//build/test/test_package.gni")
import("//build/testing/environments.gni")
import("//build/vulkan/config.gni")
import("//garnet/bin/ui/scenic/config.gni")
+import("//topaz/runtime/flutter_runner/prebuilt_framework.gni")
import("$flutter_root/shell/gpu/gpu.gni")
shell_gpu_configuration("fuchsia_gpu_configuration") {
@@ -166,9 +168,11 @@
"-fno-omit-frame-pointer",
]
- # This flag is needed so that the call to dladdr() in Dart's native symbol
- # resolver can report good symbol information for the CPU profiler.
- ldflags = [ "-rdynamic" ]
+ if (!invoker.product) {
+ # This flag is needed so that the call to dladdr() in Dart's native symbol
+ # resolver can report good symbol information for the CPU profiler.
+ ldflags = [ "-rdynamic" ]
+ }
}
}
@@ -210,8 +214,6 @@
]
}
-import("//build/package.gni")
-
observatory_target =
"//third_party/dart/runtime/observatory:observatory_archive"
observatory_archive_dir = get_label_info(observatory_target, "target_gen_dir")
@@ -276,7 +278,6 @@
deps = [
":jit${product_suffix}",
- "//topaz/runtime/flutter_runner/kernel:framework_shim_kernel",
snapshot_framework_label,
snapshot_label,
]
@@ -329,16 +330,32 @@
dest = "framework_isolate_core_snapshot_instructions.bin"
},
{
- path = rebase_path(
- "$snapshot_gen_dir/framework_shim.dilpmanifest.frameworkversion")
- dest = "runner.frameworkversion"
- },
- {
path = rebase_path("//third_party/icu/common/icudtl.dat")
dest = "icudtl.dat"
},
]
+ if (prebuilt_framework_path == "") {
+ deps += [ "//topaz/runtime/flutter_runner/kernel:framework_shim_kernel" ]
+ resources += [
+ {
+ path = rebase_path(
+ "$snapshot_gen_dir/framework_shim.dilpmanifest.frameworkversion")
+ dest = "runner.frameworkversion"
+ },
+ ]
+ } else {
+ deps +=
+ [ "//topaz/runtime/flutter_runner/kernel:extract_prebuilt_framework" ]
+ resources += [
+ {
+ path = rebase_path(
+ "$snapshot_gen_dir/data/$prebuilt_framework_name/app.frameworkversion")
+ dest = "runner.frameworkversion"
+ },
+ ]
+ }
+
if (!product) {
resources += [
{
diff --git a/runtime/flutter_runner/kernel/BUILD.gn b/runtime/flutter_runner/kernel/BUILD.gn
index b040b32..671a8e3 100644
--- a/runtime/flutter_runner/kernel/BUILD.gn
+++ b/runtime/flutter_runner/kernel/BUILD.gn
@@ -3,8 +3,10 @@
# found in the LICENSE file.
import("//build/dart/dart_tool.gni")
+import("//build/host.gni")
import("//third_party/dart/utils/compile_platform.gni")
import("//topaz/runtime/dart/dart_kernel.gni")
+import("//topaz/runtime/flutter_runner/prebuilt_framework.gni")
compile_platform("kernel_platform_files") {
single_root_scheme = "org-dartlang-sdk"
@@ -29,7 +31,8 @@
dart_kernel("framework_shim") {
platform_name = "flutter_runner"
- platform_deps = [ "//topaz/runtime/flutter_runner/kernel:kernel_platform_files" ]
+ platform_deps =
+ [ "//topaz/runtime/flutter_runner/kernel:kernel_platform_files" ]
platform_path = "$root_out_dir/flutter_runner_patched_sdk"
disable_analysis = true
gen_bytecode = true
@@ -59,23 +62,21 @@
action(target_name) {
deps = gen_snapshot_deps + [ ":kernel_platform_files" ]
- platform_dill = "$root_out_dir/flutter_runner_patched_sdk/platform_strong.dill"
+ platform_dill =
+ "$root_out_dir/flutter_runner_patched_sdk/platform_strong.dill"
compilation_trace = "//topaz/runtime/flutter_runner/compilation_trace.txt"
inputs = [
platform_dill,
compilation_trace,
]
- vm_snapshot_data =
- "$target_gen_dir/vm_isolate_snapshot${suffix}.bin"
+ vm_snapshot_data = "$target_gen_dir/vm_isolate_snapshot${suffix}.bin"
vm_snapshot_instructions =
"$target_gen_dir/vm_snapshot_instructions${suffix}.bin"
- isolate_snapshot_data =
- "$target_gen_dir/isolate_snapshot${suffix}.bin"
+ isolate_snapshot_data = "$target_gen_dir/isolate_snapshot${suffix}.bin"
isolate_snapshot_instructions =
"$target_gen_dir/isolate_snapshot_instructions${suffix}.bin"
- snapshot_profile =
- "$target_gen_dir/snapshot_profile${suffix}.json"
+ snapshot_profile = "$target_gen_dir/snapshot_profile${suffix}.json"
outputs = [
vm_snapshot_data,
vm_snapshot_instructions,
@@ -115,9 +116,19 @@
args += [ rebase_path(platform_dill) ]
if (invoker.framework) {
- deps += [ ":framework_shim_kernel" ]
- inputs += [ "$target_gen_dir/framework_shim_kernel.dil" ]
- args += [ rebase_path("$target_gen_dir/framework_shim_kernel.dil") ]
+ if (prebuilt_framework_path == "") {
+ deps += [ ":framework_shim_kernel" ]
+ inputs += [ "$target_gen_dir/framework_shim_kernel.dil" ]
+ args += [ rebase_path("$target_gen_dir/framework_shim_kernel.dil") ]
+ } else {
+ deps += [ ":extract_prebuilt_framework" ]
+ foreach(package, framework_packages) {
+ args += [ rebase_path(
+ "$target_gen_dir/data/$prebuilt_framework_name/$package.dilp") ]
+ inputs +=
+ [ "$target_gen_dir/data/$prebuilt_framework_name/$package.dilp" ]
+ }
+ }
}
}
}
@@ -141,3 +152,52 @@
product = true
framework = true
}
+
+dart_tool("extract_far") {
+ main_dart = "extract_far.dart"
+
+ force_prebuilt_dart = true
+
+ source_dir = "."
+ sources = [
+ "extract_far.dart",
+ ]
+
+ deps = [
+ "//third_party/dart-pkg/pub/args",
+ ]
+}
+
+if (prebuilt_framework_path != "") {
+ action("extract_prebuilt_framework") {
+ deps = [
+ ":extract_far",
+ "//garnet/bin/far:host",
+ ]
+
+ inputs = [
+ prebuilt_framework_path,
+ ]
+
+ script = get_label_info(":extract_far", "root_out_dir") +
+ "/dart-tools/extract_far"
+ args = [
+ "--far-tool",
+ rebase_path("$host_tools_dir/far"),
+ "--archive",
+ rebase_path(prebuilt_framework_path),
+ "--out-dir",
+ rebase_path(target_gen_dir),
+ ]
+
+ outputs = []
+ foreach(package, framework_packages) {
+ args += [ "data/$prebuilt_framework_name/$package.dilp" ]
+ outputs +=
+ [ "$target_gen_dir/data/$prebuilt_framework_name/$package.dilp" ]
+ }
+ args += [ "data/$prebuilt_framework_name/app.frameworkversion" ]
+ outputs +=
+ [ "$target_gen_dir/data/$prebuilt_framework_name/app.frameworkversion" ]
+ }
+}
diff --git a/runtime/flutter_runner/kernel/analysis_options.yaml b/runtime/flutter_runner/kernel/analysis_options.yaml
new file mode 100644
index 0000000..ef6b539
--- /dev/null
+++ b/runtime/flutter_runner/kernel/analysis_options.yaml
@@ -0,0 +1,12 @@
+# Copyright 2019 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.
+
+include: ../../../tools/analysis_options.yaml
+analyzer:
+ errors:
+ avoid_catches_without_on_clauses: ignore
+ cascade_invocations: ignore
+ only_throw_errors: ignore # adds noise to error messages
+ prefer_foreach: ignore # for-in is preferable to closurization
+ prefer_single_quotes: ignore
diff --git a/runtime/flutter_runner/kernel/extract_far.dart b/runtime/flutter_runner/kernel/extract_far.dart
new file mode 100644
index 0000000..e9aa2b2
--- /dev/null
+++ b/runtime/flutter_runner/kernel/extract_far.dart
@@ -0,0 +1,83 @@
+// Copyright 2019 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 "dart:io";
+
+import "package:args/args.dart";
+
+Future<void> main(List<String> args) async {
+ final parser = new ArgParser();
+ parser.addOption("far-tool", help: "Path to `far` tool");
+ parser.addOption("archive", help: "Path to the far archive to extract from");
+ parser.addOption("out-dir", help: "Path to output directory");
+ final usage = """
+Usage: extract_far.dart [options] {paths}
+
+Options:
+${parser.usage};
+""";
+
+ ArgResults options;
+ try {
+ options = parser.parse(args);
+ if (options["far-tool"] == null) {
+ throw "Must specify --far-tool";
+ }
+ if (options["archive"] == null) {
+ throw "Must specify --archive";
+ }
+ if (options["out-dir"] == null) {
+ throw "Must specify --out-dir";
+ }
+ } catch (e) {
+ print("ERROR: $e\n");
+ print(usage);
+ exitCode = 1;
+ return;
+ }
+
+ await run(options);
+}
+
+Future<void> run(ArgResults options) async {
+ final far = options["far-tool"];
+
+ Future<void> extract(String archive, String file, String output) async {
+ await new File(output).parent.create(recursive: true);
+ final args = ["extract-file", "--archive=$archive", "--file=$file", "--output=$output"];
+ final result = await Process.run(far, args);
+ if (result.exitCode != 0) {
+ print(result.stdout);
+ print(result.stderr);
+ throw "Command failed: $far $args";
+ }
+ }
+
+ final outerArchive = options["archive"];
+ final outDir = options["out-dir"];
+
+ final innerArchive = "$outDir/meta.far";
+ await extract(outerArchive, "meta.far", innerArchive);
+
+ final manifest = "$outDir/meta/contents";
+ await extract(innerArchive, "meta/contents", manifest);
+
+ final blobNames = <String, String>{};
+ for (final line in await new File(manifest).readAsLines()) {
+ final pivot = line.lastIndexOf("=");
+ blobNames[line.substring(0, pivot)] = line.substring(pivot + 1, line.length);
+ }
+
+ for (final path in options.rest) {
+ final blobName = blobNames[path];
+ if (blobName == null) {
+ print("Archive contents: ");
+ for (final key in blobNames.keys) {
+ print(key);
+ }
+ throw "$outerArchive does not contain $path";
+ }
+ await extract(outerArchive, blobName, "$outDir/$path");
+ }
+}
diff --git a/runtime/flutter_runner/prebuilt_framework.gni b/runtime/flutter_runner/prebuilt_framework.gni
new file mode 100644
index 0000000..edc389c
--- /dev/null
+++ b/runtime/flutter_runner/prebuilt_framework.gni
@@ -0,0 +1,15 @@
+# Copyright 2019 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.
+
+declare_args() {
+ prebuilt_framework_path = ""
+ prebuilt_framework_name = ""
+ framework_packages = [
+ "collection",
+ "flutter",
+ "meta",
+ "typed_data",
+ "vector_math",
+ ]
+}