| # Copyright 2019 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/build/zip_bundle.gni") |
| import("//flutter/common/config.gni") |
| import("//third_party/dart/build/dart/dart_action.gni") |
| |
| declare_args() { |
| build_canvaskit = false |
| archive_flutter_web_sdk = true |
| } |
| |
| dart_sdk_package_config = "//third_party/dart/.dart_tool/package_config.json" |
| |
| web_ui_sources = exec_script("//third_party/dart/tools/list_dart_files.py", |
| [ |
| "absolute", |
| rebase_path("//flutter/lib/web_ui/lib"), |
| ], |
| "list lines") |
| |
| web_engine_libraries = [ |
| ":skwasm_impl_library", |
| ":skwasm_stub_library", |
| ":web_engine_library", |
| ":web_ui_library", |
| ":web_ui_library_sources", |
| ":web_unicode_library", |
| ] |
| |
| group("web_sdk") { |
| deps = [ |
| ":flutter_ddc_modules", |
| ":flutter_legacy_platform_dills", |
| ":flutter_web_platforms", |
| ] |
| |
| if (archive_flutter_web_sdk && !is_fuchsia) { |
| deps += [ ":flutter_web_sdk_archive" ] |
| } |
| } |
| |
| template("sdk_rewriter") { |
| ui = defined(invoker.ui) && invoker.ui |
| if (!ui) { |
| assert(defined(invoker.library_name), "Must pass 'library_name'") |
| assert(defined(invoker.api_file), "Must pass 'api_file'") |
| } |
| assert(defined(invoker.input_dir), "Must pass 'input_dir'") |
| assert(defined(invoker.output_dir), "Must pass 'output_dir'") |
| |
| source_dart_files = exec_script("//third_party/dart/tools/list_dart_files.py", |
| [ |
| "absolute", |
| rebase_path(invoker.input_dir), |
| ], |
| "list lines") |
| |
| if (defined(invoker.exclude_patterns)) { |
| filtered_files = filter_exclude(source_dart_files, invoker.exclude_patterns) |
| source_dart_files = [] |
| source_dart_files = filtered_files |
| } |
| |
| prebuilt_dart_action(target_name) { |
| packages = dart_sdk_package_config |
| pool = "//flutter/build/dart:dart_pool" |
| |
| script = "sdk_rewriter.dart" |
| inputs = source_dart_files + [ "sdk_rewriter.dart" ] |
| |
| stamp_location = "$target_gen_dir/$target_name.stamp" |
| outputs = [ |
| stamp_location, |
| invoker.output_dir, |
| ] |
| |
| input_dir = rebase_path(invoker.input_dir) |
| output_dir = rebase_path(invoker.output_dir) |
| |
| args = [ |
| "--output-dir=$output_dir", |
| "--input-dir=$input_dir", |
| "--stamp", |
| rebase_path(stamp_location, root_build_dir), |
| ] |
| if (ui) { |
| args += [ "--ui" ] |
| } else { |
| library_name = invoker.library_name |
| api_file = rebase_path(invoker.api_file) |
| args += [ |
| "--library-name=$library_name", |
| "--api-file=$api_file", |
| ] |
| } |
| |
| foreach(source_file, source_dart_files) { |
| path = rebase_path(source_file) |
| args += [ "--source-file=$path" ] |
| } |
| } |
| } |
| |
| sdk_rewriter("web_ui_library_sources") { |
| ui = true |
| input_dir = "//flutter/lib/web_ui/lib/" |
| output_dir = "$root_out_dir/flutter_web_sdk/lib/ui/" |
| |
| # exclude everything in the engine directory, it will be a separate internal library |
| exclude_patterns = [ rebase_path("//flutter/lib/web_ui/lib/src/*") ] |
| } |
| |
| sdk_rewriter("web_engine_library") { |
| library_name = "engine" |
| api_file = "//flutter/lib/web_ui/lib/src/engine.dart" |
| input_dir = "//flutter/lib/web_ui/lib/src/engine/" |
| output_dir = "$root_out_dir/flutter_web_sdk/lib/_engine/" |
| |
| # exclude skwasm, it will be a separate internal library |
| exclude_patterns = |
| [ rebase_path("//flutter/lib/web_ui/lib/src/engine/skwasm/*") ] |
| } |
| |
| sdk_rewriter("skwasm_stub_library") { |
| library_name = "skwasm_stub" |
| api_file = "//flutter/lib/web_ui/lib/src/engine/skwasm/skwasm_stub.dart" |
| input_dir = "//flutter/lib/web_ui/lib/src/engine/skwasm/skwasm_stub/" |
| output_dir = "$root_out_dir/flutter_web_sdk/lib/_skwasm_stub/" |
| } |
| |
| sdk_rewriter("skwasm_impl_library") { |
| library_name = "skwasm_impl" |
| api_file = "//flutter/lib/web_ui/lib/src/engine/skwasm/skwasm_impl.dart" |
| input_dir = "//flutter/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/" |
| output_dir = "$root_out_dir/flutter_web_sdk/lib/_skwasm_impl/" |
| } |
| |
| sdk_rewriter("web_unicode_library") { |
| library_name = "web_unicode" |
| api_file = "//flutter/third_party/web_unicode/lib/web_unicode.dart" |
| input_dir = "//flutter/third_party/web_unicode/lib/web_unicode/" |
| output_dir = "$root_out_dir/flutter_web_sdk/lib/_web_unicode/" |
| } |
| |
| copy("web_ui_library") { |
| sources = [ "//flutter/web_sdk/libraries.json" ] |
| |
| outputs = [ "$root_out_dir/flutter_web_sdk/{{source_file_part}}" ] |
| } |
| |
| # Compiles a Dart program with dartdevc |
| # |
| # Parameters: |
| # |
| # inputs (required): The inputs to dartdevc |
| # |
| # outputs (required): The files generated by dartdevc |
| # |
| # args (required): The arguments to pass to dartdevc |
| template("_dartdevc") { |
| if (flutter_prebuilt_dart_sdk) { |
| action(target_name) { |
| not_needed(invoker, [ "packages" ]) |
| deps = web_engine_libraries |
| script = "//build/gn_run_binary.py" |
| |
| inputs = invoker.inputs |
| outputs = invoker.outputs |
| |
| pool = "//flutter/build/dart:dart_pool" |
| |
| ext = "" |
| if (is_win) { |
| ext = ".exe" |
| } |
| dart = rebase_path("$host_prebuilt_dart_sdk/bin/dart$ext", root_out_dir) |
| dartdevc = rebase_path( |
| "$host_prebuilt_dart_sdk/bin/snapshots/dartdevc.dart.snapshot") |
| args = [ |
| dart, |
| dartdevc, |
| ] + invoker.args |
| } |
| } else { |
| prebuilt_dart_action(target_name) { |
| forward_variables_from(invoker, "*") |
| |
| deps = web_engine_libraries + [ |
| "//third_party/dart:create_sdk", |
| "//third_party/dart/pkg:pkg_files_stamp", |
| "//third_party/dart/utils/dartdevc:dartdevc_files_stamp", |
| "//third_party/dart/utils/dartdevc:dartdevc_sdk_patch_stamp", |
| ] |
| |
| script = "//third_party/dart/pkg/dev_compiler/bin/dartdevc.dart" |
| |
| pool = "//flutter/build/dart:dart_pool" |
| } |
| } |
| } |
| |
| # Compiles a Dart SDK with the kernel_worker |
| # |
| # Parameters: |
| # |
| # inputs (required): The inputs to the kernel_worker |
| # |
| # outputs (required): The files generated by the kernel_worker |
| # |
| # args (required): The arguments to pass to the kernel_worker |
| template("_kernel_worker") { |
| if (flutter_prebuilt_dart_sdk) { |
| action(target_name) { |
| deps = web_engine_libraries |
| script = "//build/gn_run_binary.py" |
| |
| inputs = invoker.inputs |
| outputs = invoker.outputs |
| |
| pool = "//flutter/build/dart:dart_pool" |
| |
| ext = "" |
| if (is_win) { |
| ext = ".exe" |
| } |
| dart = rebase_path("$host_prebuilt_dart_sdk/bin/dart$ext", root_out_dir) |
| kernel_worker = rebase_path( |
| "$host_prebuilt_dart_sdk/bin/snapshots/kernel_worker.dart.snapshot") |
| |
| args = [ |
| dart, |
| kernel_worker, |
| ] + invoker.args |
| } |
| } else { |
| prebuilt_dart_action(target_name) { |
| forward_variables_from(invoker, "*") |
| |
| deps = web_engine_libraries + [ |
| "//third_party/dart:create_sdk", |
| "//third_party/dart/pkg:pkg_files_stamp", |
| "//third_party/dart/utils/dartdevc:dartdevc_files_stamp", |
| "//third_party/dart/utils/dartdevc:dartdevc_sdk_patch_stamp", |
| ] |
| |
| script = "//third_party/dart/utils/bazel/kernel_worker.dart" |
| |
| pool = "//flutter/build/dart:dart_pool" |
| } |
| } |
| } |
| |
| template("_compile_platform") { |
| assert(defined(invoker.sound_null_safety), |
| "sound_null_safety must be defined for $target_name") |
| assert(defined(invoker.kernel_target), |
| "kernel_target must be defined for $target_name") |
| assert(defined(invoker.summary_only), |
| "summary_only must be defined for $target_name") |
| assert(defined(invoker.output_dill), |
| "output_dill must be defined for $target_name") |
| _kernel_worker(target_name) { |
| inputs = [ "sdk_rewriter.dart" ] + web_ui_sources |
| |
| outputs = [ invoker.output_dill ] |
| |
| if (invoker.sound_null_safety) { |
| args = [ "--sound-null-safety" ] |
| } else { |
| args = [ "--no-sound-null-safety" ] |
| } |
| |
| if (invoker.summary_only) { |
| args += [ "--summary-only" ] |
| } else { |
| args += [ "--no-summary-only" ] |
| } |
| args += [ |
| "--target", |
| "${invoker.kernel_target}", |
| "--packages-file", |
| "file:///" + rebase_path(dart_sdk_package_config), |
| "--multi-root-scheme", |
| "org-dartlang-sdk", |
| "--multi-root", |
| "file:///" + rebase_path("$root_out_dir/flutter_web_sdk"), |
| "--libraries-file", |
| "org-dartlang-sdk:///libraries.json", |
| "--output", |
| rebase_path(invoker.output_dill), |
| "--source", |
| "dart:core", |
| |
| # Additional Flutter web dart libraries |
| "--source", |
| "dart:ui", |
| "--source", |
| "dart:_engine", |
| "--source", |
| "dart:_skwasm_stub", |
| "--source", |
| "dart:_web_unicode", |
| ] |
| if (flutter_prebuilt_dart_sdk) { |
| args += [ |
| "--multi-root", |
| "file:///" + rebase_path("$host_prebuilt_dart_sdk/.."), |
| ] |
| } else { |
| args += [ |
| "--multi-root", |
| "file:///" + rebase_path("$root_out_dir"), |
| ] |
| } |
| |
| if (defined(invoker.extra_args)) { |
| args += invoker.extra_args |
| } |
| } |
| } |
| |
| # Compile the unsound DDC SDK's summary. |
| _compile_platform("flutter_dartdevc_kernel_sdk_outline") { |
| sound_null_safety = false |
| kernel_target = "ddc" |
| summary_only = true |
| output_dill = "$root_out_dir/flutter_web_sdk/kernel/flutter_ddc_sdk.dill" |
| } |
| |
| # Compile the sound DDC SDK's summary. |
| _compile_platform("flutter_dartdevc_kernel_sdk_outline_sound") { |
| sound_null_safety = true |
| kernel_target = "ddc" |
| summary_only = true |
| output_dill = |
| "$root_out_dir/flutter_web_sdk/kernel/flutter_ddc_sdk_sound.dill" |
| } |
| |
| group("flutter_legacy_platform_dills") { |
| public_deps = [ |
| ":flutter_dartdevc_kernel_sdk_outline", |
| ":flutter_dartdevc_kernel_sdk_outline_sound", |
| ] |
| } |
| |
| template("_flutter_web_platform") { |
| assert(defined(invoker.output_dir), |
| "output_dir must be defined for $target_name") |
| assert(defined(invoker.use_skia), |
| "use_skia must be defined for $target_name") |
| assert(defined(invoker.auto_detect), |
| "auto_detect must be defined for $target_name") |
| |
| define_flags = [ |
| "-DFLUTTER_WEB_USE_SKIA=${invoker.use_skia}", |
| "-DFLUTTER_WEB_AUTO_DETECT=${invoker.auto_detect}", |
| ] |
| |
| _compile_platform("${target_name}_ddc_sound") { |
| sound_null_safety = true |
| kernel_target = "ddc" |
| summary_only = true |
| output_dill = "${invoker.output_dir}/ddc_outline_sound.dill" |
| extra_args = define_flags |
| } |
| _compile_platform("${target_name}_ddc_unsound") { |
| sound_null_safety = false |
| kernel_target = "ddc" |
| summary_only = true |
| output_dill = "${invoker.output_dir}/ddc_outline.dill" |
| extra_args = define_flags |
| } |
| _compile_platform("${target_name}_dart2js_sound") { |
| sound_null_safety = true |
| kernel_target = "dart2js" |
| summary_only = false |
| output_dill = "${invoker.output_dir}/dart2js_platform.dill" |
| extra_args = define_flags |
| } |
| _compile_platform("${target_name}_dart2js_unsound") { |
| sound_null_safety = false |
| kernel_target = "dart2js" |
| summary_only = false |
| output_dill = "${invoker.output_dir}/dart2js_platform_unsound.dill" |
| extra_args = define_flags |
| } |
| |
| group(target_name) { |
| public_deps = [ |
| ":${target_name}_dart2js_sound", |
| ":${target_name}_dart2js_unsound", |
| ":${target_name}_ddc_sound", |
| ":${target_name}_ddc_unsound", |
| ] |
| } |
| } |
| |
| _flutter_web_platform("flutter_auto_platform") { |
| output_dir = "$root_out_dir/flutter_web_sdk/kernel/platforms/auto" |
| use_skia = true |
| auto_detect = true |
| } |
| |
| _flutter_web_platform("flutter_html_platform") { |
| output_dir = "$root_out_dir/flutter_web_sdk/kernel/platforms/html" |
| use_skia = false |
| auto_detect = false |
| } |
| |
| _flutter_web_platform("flutter_canvaskit_platform") { |
| output_dir = "$root_out_dir/flutter_web_sdk/kernel/platforms/canvaskit" |
| use_skia = true |
| auto_detect = false |
| } |
| |
| group("flutter_web_platforms") { |
| public_deps = [ |
| ":flutter_auto_platform", |
| ":flutter_canvaskit_platform", |
| ":flutter_html_platform", |
| ] |
| } |
| |
| template("_compile_ddc_modules") { |
| assert(defined(invoker.sound_null_safety), |
| "sound_null_safety must be defined for $target_name") |
| assert(defined(invoker.use_skia), |
| "use_skia must be defined for $target_name") |
| assert(defined(invoker.auto_detect), |
| "auto_detect must be defined for $target_name") |
| |
| _dartdevc(target_name) { |
| inputs = [ "sdk_rewriter.dart" ] + web_ui_sources |
| |
| packages = dart_sdk_package_config |
| |
| name_suffix = "" |
| if (invoker.use_skia) { |
| name_suffix += "-canvaskit" |
| } |
| if (invoker.auto_detect) { |
| name_suffix += "-html" |
| } |
| if (invoker.sound_null_safety) { |
| name_suffix += "-sound" |
| } |
| |
| amd_js_path = |
| "$root_out_dir/flutter_web_sdk/kernel/amd${name_suffix}/dart_sdk.js" |
| legacy_js_path = |
| "$root_out_dir/flutter_web_sdk/kernel/legacy${name_suffix}/dart_sdk.js" |
| |
| outputs = [ |
| amd_js_path, |
| amd_js_path + ".map", |
| legacy_js_path, |
| legacy_js_path + ".map", |
| ] |
| |
| if (invoker.sound_null_safety) { |
| args = [ "--sound-null-safety" ] |
| } else { |
| args = [ "--no-sound-null-safety" ] |
| } |
| |
| args += [ |
| "--compile-sdk", |
| "dart:core", |
| |
| # Additional Flutter web dart libraries |
| "dart:ui", |
| "dart:_engine", |
| "dart:_skwasm_stub", |
| "dart:_web_unicode", |
| "--no-summarize", |
| "--packages", |
| "file:///" + rebase_path(dart_sdk_package_config), |
| "--multi-root-scheme", |
| "org-dartlang-sdk", |
| "--multi-root", |
| "file:///" + rebase_path("$root_out_dir/flutter_web_sdk"), |
| "--multi-root-output-path", |
| rebase_path("$root_out_dir/"), |
| "--libraries-file", |
| "org-dartlang-sdk:///libraries.json", |
| "--inline-source-map", |
| "-DFLUTTER_WEB_USE_SKIA=${invoker.use_skia}", |
| "-DFLUTTER_WEB_AUTO_DETECT=${invoker.auto_detect}", |
| "--modules", |
| "amd", |
| "-o", |
| rebase_path(amd_js_path), |
| "--modules", |
| "legacy", |
| "-o", |
| rebase_path(legacy_js_path), |
| ] |
| if (flutter_prebuilt_dart_sdk) { |
| args += [ |
| "--multi-root", |
| "file:///" + rebase_path("$host_prebuilt_dart_sdk/.."), |
| ] |
| } else { |
| args += [ |
| "--multi-root", |
| "file:///" + rebase_path("$root_out_dir"), |
| ] |
| } |
| } |
| } |
| |
| # Compiles the unsound html only renderer. |
| _compile_ddc_modules("flutter_dartdevc_kernel_sdk") { |
| sound_null_safety = false |
| use_skia = false |
| auto_detect = false |
| } |
| |
| # Compiles the unsound canvaskit only renderer. |
| _compile_ddc_modules("flutter_dartdevc_canvaskit_kernel_sdk") { |
| sound_null_safety = false |
| use_skia = true |
| auto_detect = false |
| } |
| |
| # Compiles the unsound autodetect renderer. |
| _compile_ddc_modules("flutter_dartdevc_canvaskit_html_kernel_sdk") { |
| sound_null_safety = false |
| use_skia = true |
| auto_detect = true |
| } |
| |
| # Compiles the sound html only renderer. |
| _compile_ddc_modules("flutter_dartdevc_kernel_sdk_sound") { |
| sound_null_safety = true |
| use_skia = false |
| auto_detect = false |
| } |
| |
| # Compiles the sound canvaskit only renderer. |
| _compile_ddc_modules("flutter_dartdevc_canvaskit_kernel_sdk_sound") { |
| sound_null_safety = true |
| use_skia = true |
| auto_detect = false |
| } |
| |
| # Compiles the sound autodetect renderer. |
| _compile_ddc_modules("flutter_dartdevc_canvaskit_html_kernel_sdk_sound") { |
| sound_null_safety = true |
| use_skia = true |
| auto_detect = true |
| } |
| |
| group("flutter_ddc_modules") { |
| public_deps = [ |
| ":flutter_dartdevc_canvaskit_html_kernel_sdk", |
| ":flutter_dartdevc_canvaskit_html_kernel_sdk_sound", |
| ":flutter_dartdevc_canvaskit_kernel_sdk", |
| ":flutter_dartdevc_canvaskit_kernel_sdk_sound", |
| ":flutter_dartdevc_kernel_sdk", |
| ":flutter_dartdevc_kernel_sdk_sound", |
| ] |
| } |
| |
| # Archives Flutter Web SDK |
| if (!is_fuchsia) { |
| zip_bundle_from_file("flutter_web_sdk_archive") { |
| if (target_os == "wasm") { |
| output = "flutter-web-sdk.zip" |
| } else { |
| # TODO(jacksongardner): remove this once we stop making platform-specific |
| # flutter_web_sdk archives. |
| # https://github.com/flutter/flutter/issues/113303 |
| output = "flutter-web-sdk-${full_platform_name}.zip" |
| } |
| deps = [ |
| ":flutter_ddc_modules", |
| ":flutter_legacy_platform_dills", |
| ":flutter_web_platforms", |
| ] + web_engine_libraries |
| |
| if (build_canvaskit) { |
| deps += [ "//third_party/skia/modules/canvaskit" ] |
| } |
| |
| # flutter_ddc_modules |
| sources = get_target_outputs(":flutter_dartdevc_kernel_sdk") |
| sources += get_target_outputs(":flutter_dartdevc_canvaskit_kernel_sdk") |
| sources += get_target_outputs(":flutter_dartdevc_canvaskit_html_kernel_sdk") |
| sources += get_target_outputs(":flutter_dartdevc_kernel_sdk_sound") |
| sources += |
| get_target_outputs(":flutter_dartdevc_canvaskit_kernel_sdk_sound") |
| sources += |
| get_target_outputs(":flutter_dartdevc_canvaskit_html_kernel_sdk_sound") |
| |
| # flutter_legacy_platform_dills |
| sources += get_target_outputs(":flutter_dartdevc_kernel_sdk_outline") |
| sources += get_target_outputs(":flutter_dartdevc_kernel_sdk_outline_sound") |
| |
| # flutter_web_platforms |
| sources += get_target_outputs(":flutter_auto_platform_ddc_sound") |
| sources += get_target_outputs(":flutter_auto_platform_ddc_unsound") |
| sources += get_target_outputs(":flutter_auto_platform_dart2js_sound") |
| sources += get_target_outputs(":flutter_auto_platform_dart2js_unsound") |
| |
| sources += get_target_outputs(":flutter_html_platform_ddc_sound") |
| sources += get_target_outputs(":flutter_html_platform_ddc_unsound") |
| sources += get_target_outputs(":flutter_html_platform_dart2js_sound") |
| sources += get_target_outputs(":flutter_html_platform_dart2js_unsound") |
| |
| sources += get_target_outputs(":flutter_canvaskit_platform_ddc_sound") |
| sources += get_target_outputs(":flutter_canvaskit_platform_ddc_unsound") |
| sources += get_target_outputs(":flutter_canvaskit_platform_dart2js_sound") |
| sources += get_target_outputs(":flutter_canvaskit_platform_dart2js_unsound") |
| |
| foreach(web_engine_library, web_engine_libraries) { |
| sources += get_target_outputs(web_engine_library) |
| } |
| |
| tmp_files = [] |
| foreach(source, sources) { |
| tmp_files += [ |
| { |
| source = rebase_path(source) |
| destination = rebase_path(source, "$root_build_dir") |
| }, |
| ] |
| } |
| if (build_canvaskit) { |
| tmp_files += [ |
| { |
| source = rebase_path("$root_out_dir/canvaskit.js") |
| destination = "canvaskit/canvaskit.js" |
| }, |
| { |
| source = rebase_path("$root_out_dir/canvaskit.wasm") |
| destination = "canvaskit/canvaskit.wasm" |
| }, |
| ] |
| } |
| files = tmp_files |
| } |
| } |