GN build rules for tests using Fuchsia SDK Dart libraries and bindings (flutter/engine#27996)
This commit is contained in:
@@ -1,251 +0,0 @@
|
||||
# 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/package.gni")
|
||||
import("//build/tools/json_merge/json_merge.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 dart components and puts them into one fuchsia package with
|
||||
# the dart_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.
|
||||
#
|
||||
# dart_package_name (optional)
|
||||
# Name of the dart package for the component. If not provided, it will
|
||||
# be inferred from the component name.
|
||||
#
|
||||
# package_root (optional)
|
||||
# Path to the dart package for the component. If not provided, it will
|
||||
# be assumed as ".".
|
||||
#
|
||||
# sources (optional)
|
||||
# Relative path of source files to be included in the dart package for
|
||||
# the component at $package_root/lib.
|
||||
#
|
||||
# main_dart (required)
|
||||
# File containing the main function of the application. Either main_dart or
|
||||
# components must be defined, but not both.
|
||||
#
|
||||
# package_name (optional)
|
||||
# Name of the Dart package. This is used as an identifier in code that
|
||||
# depends on the dart library that the *one and only* component generates.
|
||||
# Only compatible when components is not specified (use
|
||||
# components.dart_package_name).
|
||||
#
|
||||
template("_dart_jit_component") {
|
||||
legacy_component = false
|
||||
pkg_name = target_name
|
||||
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-141): Remove support for legacy_component once all existing calls
|
||||
# to dart_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 = "dart"
|
||||
package_root = "."
|
||||
deps = invoker.deps
|
||||
sources = pkg_sources
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
flutter_dart_jit_component(target_name) {
|
||||
forward_variables_from(invoker, "*")
|
||||
}
|
||||
}
|
||||
|
||||
# Defines AOT runtime components to be further distributed in one package.
|
||||
#
|
||||
# Takes a set of dart components and puts them into one fuchsia package with
|
||||
# the dart_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.
|
||||
#
|
||||
# dart_package_name (optional)
|
||||
# Name of the dart package for the component. If not provided, it will
|
||||
# be inferred from the component name.
|
||||
#
|
||||
# package_root (optional)
|
||||
# Path to the dart package for the component. If not provided, it will
|
||||
# be assumed as ".".
|
||||
#
|
||||
# sources (optional)
|
||||
# Relative path of source files to be included in the dart package for
|
||||
# the component at $package_root/lib.
|
||||
#
|
||||
# main_dart (required)
|
||||
# File containing the main function of the application. Either main_dart or
|
||||
# components must be defined, but not both.
|
||||
#
|
||||
# package_name (optional)
|
||||
# Name of the Dart package. This is used as an identifier in code that
|
||||
# depends on the dart library that the *one and only* component generates.
|
||||
# Only compatible when components is not specified (use
|
||||
# components.dart_package_name).
|
||||
#
|
||||
template("_dart_aot_component") {
|
||||
legacy_component = false
|
||||
pkg_name = target_name
|
||||
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-141): Remove support for legacy_component once all existing calls
|
||||
# to dart_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 = "dart"
|
||||
package_root = "."
|
||||
deps = invoker.deps
|
||||
sources = pkg_sources
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
flutter_dart_aot_component(target_name) {
|
||||
forward_variables_from(invoker, "*")
|
||||
}
|
||||
}
|
||||
|
||||
template("dart_jit_app") {
|
||||
template_name = "_dart_jit_component"
|
||||
if (dart_force_product) {
|
||||
template_name = dart_product_app
|
||||
}
|
||||
|
||||
target(template_name, target_name) {
|
||||
forward_variables_from(invoker, "*")
|
||||
}
|
||||
}
|
||||
|
||||
template("dart_aot_app") {
|
||||
template_name = "_dart_aot_component"
|
||||
if (dart_force_product) {
|
||||
template_name = dart_product_app
|
||||
}
|
||||
|
||||
target(template_name, target_name) {
|
||||
forward_variables_from(invoker, "*")
|
||||
}
|
||||
}
|
||||
|
||||
# Defines a Dart application that can be run in the Dart content handler
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# resources (optional)
|
||||
# Resources for the package (see //build/package.gni)
|
||||
#
|
||||
# tests (optional)
|
||||
# List of tests forwarded for the package. See the definition in //build/package.gni.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# package_root (optional)
|
||||
# Path to the dart package for the component. If not provided, it will
|
||||
# be assumed as ".".
|
||||
#
|
||||
# sources (optional)
|
||||
# Relative path of source files to be included in the dart package for
|
||||
# the component at $package_root/lib.
|
||||
#
|
||||
template("dart_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(dart_default_app, target_name) {
|
||||
forward_variables_from(invoker, "*")
|
||||
}
|
||||
}
|
||||
@@ -1,316 +0,0 @@
|
||||
# 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.
|
||||
|
||||
assert(is_fuchsia)
|
||||
|
||||
import("//build/package.gni")
|
||||
import("//build/tools/json_merge/json_merge.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.
|
||||
#
|
||||
# dart_package_name (optional)
|
||||
# Name of the dart package for the component. If not provided, it will
|
||||
# be inferred from the component name.
|
||||
#
|
||||
# package_root (optional)
|
||||
# Path to the dart package for the component. If not provided, it will
|
||||
# be assumed as ".".
|
||||
#
|
||||
# sources (optional)
|
||||
# Relative path of source files to be included in the dart package for
|
||||
# the component at $package_root/lib.
|
||||
#
|
||||
# main_dart (required)
|
||||
# File containing the main function of the application. Either main_dart or
|
||||
# components must be defined, but not both.
|
||||
#
|
||||
# package_name (optional)
|
||||
# Name of the Dart package. This is used as an identifier in code that
|
||||
# depends on the dart library that the *one and only* component generates.
|
||||
# Only compatible when components is not specified (use
|
||||
# components.dart_package_name).
|
||||
#
|
||||
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"
|
||||
package_root = "."
|
||||
deps = invoker.deps
|
||||
sources = pkg_sources
|
||||
},
|
||||
]
|
||||
}
|
||||
flutter_dart_jit_component(target_name) {
|
||||
forward_variables_from(invoker, "*")
|
||||
}
|
||||
}
|
||||
|
||||
# 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.
|
||||
#
|
||||
# dart_package_name (optional)
|
||||
# Name of the dart package for the component. If not provided, it will
|
||||
# be inferred from the component name.
|
||||
#
|
||||
# package_root (optional)
|
||||
# Path to the dart package for the component. If not provided, it will
|
||||
# be assumed as ".".
|
||||
#
|
||||
# sources (optional)
|
||||
# Relative path of source files to be included in the dart package for
|
||||
# the component at $package_root/lib.
|
||||
#
|
||||
# main_dart (required)
|
||||
# File containing the main function of the application. Either main_dart or
|
||||
# components must be defined, but not both.
|
||||
#
|
||||
# package_name (optional)
|
||||
# Name of the Dart package. This is used as an identifier in code that
|
||||
# depends on the dart library that the *one and only* component generates.
|
||||
# Only compatible when components is not specified (use
|
||||
# components.dart_package_name).
|
||||
#
|
||||
template("_flutter_aot_component") {
|
||||
# This variable isn't needed in AOT builds.
|
||||
if (defined(invoker.flutter_driver_extendable)) {
|
||||
not_needed(invoker, [ "flutter_driver_extendable" ])
|
||||
}
|
||||
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"
|
||||
package_root = "."
|
||||
deps = invoker.deps
|
||||
sources = pkg_sources
|
||||
},
|
||||
]
|
||||
}
|
||||
flutter_dart_aot_component(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.
|
||||
#
|
||||
# package_root (optional)
|
||||
# Path to the dart package for the component. If not provided, it will
|
||||
# be assumed as ".".
|
||||
#
|
||||
# sources (optional)
|
||||
# Relative path of source files to be included in the dart package for
|
||||
# the component at $package_root/lib.
|
||||
#
|
||||
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" ])
|
||||
}
|
||||
}
|
||||
|
||||
# Defines multiple Flutter/Dart applications in one fuchsia 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.
|
||||
#
|
||||
# dart_package_name (optional)
|
||||
# Name of the dart package for the component. If not provided, it will
|
||||
# be inferred from the component name.
|
||||
#
|
||||
# package_root (optional)
|
||||
# Path to the dart package for the component. If not provided, it will
|
||||
# be assumed as ".".
|
||||
#
|
||||
# sources (optional)
|
||||
# Relative path of source files to be included in the dart package for
|
||||
# the component at $package_root/lib.
|
||||
#
|
||||
template("flutter_dart_apps") {
|
||||
assert(defined(invoker.components) && !defined(invoker.main_dart),
|
||||
"components must be defined. Use main_dart under components instead.")
|
||||
|
||||
pkg_name = target_name
|
||||
legacy_component = false
|
||||
if (flutter_default_app == "flutter_jit_app") {
|
||||
template_name = "flutter_dart_jit_component"
|
||||
if (dart_force_product) {
|
||||
template_name = flutter_product_app
|
||||
}
|
||||
target(template_name, target_name) {
|
||||
forward_variables_from(invoker, "*", [ "aot" ])
|
||||
}
|
||||
} else {
|
||||
template_name = "flutter_dart_aot_component"
|
||||
if (dart_force_product) {
|
||||
template_name = flutter_product_app
|
||||
}
|
||||
target(template_name, target_name) {
|
||||
forward_variables_from(invoker,
|
||||
"*",
|
||||
[
|
||||
"aot",
|
||||
"space_dart",
|
||||
])
|
||||
}
|
||||
}
|
||||
}
|
||||
43
engine/src/flutter/tools/executable_action.gni
Normal file
43
engine/src/flutter/tools/executable_action.gni
Normal file
@@ -0,0 +1,43 @@
|
||||
# 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.
|
||||
|
||||
if (host_os == "win") {
|
||||
host_executable_suffix = ".exe"
|
||||
} else {
|
||||
host_executable_suffix = ""
|
||||
}
|
||||
|
||||
template("executable_action") {
|
||||
action(target_name) {
|
||||
assert(defined(invoker.tool), "The executable tool must be specified.")
|
||||
assert(defined(invoker.args), "The command line args must be specified.")
|
||||
if (defined(invoker.visibility)) {
|
||||
visibility = invoker.visibility
|
||||
}
|
||||
if (defined(invoker.testonly)) {
|
||||
testonly = invoker.testonly
|
||||
}
|
||||
|
||||
script = "//build/gn_run_binary.py"
|
||||
|
||||
host_executable =
|
||||
rebase_path("${invoker.tool}${host_executable_suffix}", root_build_dir)
|
||||
|
||||
if (defined(invoker.deps)) {
|
||||
deps = invoker.deps
|
||||
} else {
|
||||
deps = []
|
||||
}
|
||||
|
||||
if (defined(invoker.inputs)) {
|
||||
inputs = invoker.inputs
|
||||
} else {
|
||||
inputs = []
|
||||
}
|
||||
|
||||
outputs = invoker.outputs
|
||||
|
||||
args = [ host_executable ] + invoker.args
|
||||
}
|
||||
}
|
||||
@@ -99,9 +99,12 @@ def main():
|
||||
help='Path to read-elf executable.')
|
||||
|
||||
args = parser.parse_args()
|
||||
assert os.path.exists(args.exec_path)
|
||||
assert os.path.exists(args.dest)
|
||||
assert os.path.exists(args.read_elf)
|
||||
assert os.path.exists(args.exec_path), (
|
||||
'exec_path "%s" does not exist' % args.exec_path)
|
||||
assert os.path.exists(args.dest), (
|
||||
'dest "%s" does not exist' % args.dest)
|
||||
assert os.path.exists(args.read_elf), (
|
||||
'read_elf "%s" does not exist' % args.read_elf)
|
||||
|
||||
parts = GetBuildIdParts(args.exec_path, args.read_elf)
|
||||
dbg_prefix_base = os.path.join(args.dest, parts['prefix_dir'])
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
# Copyright 2018 The Fuchsia Authors. All rights reserved.
|
||||
# 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.
|
||||
|
||||
gen_snapshot = "//third_party/dart/runtime/bin:gen_snapshot"
|
||||
gen_snapshot_product = "//third_party/dart/runtime/bin:gen_snapshot_product"
|
||||
|
||||
prebuilt_dart = "//third_party/dart/tools/sdks/dart-sdk/bin/dart"
|
||||
|
||||
observatory_target =
|
||||
"//third_party/dart/runtime/observatory:observatory_archive"
|
||||
observatory_archive_dir = get_label_info(observatory_target, "target_gen_dir")
|
||||
|
||||
27
engine/src/flutter/tools/fuchsia/dart/BUILD.gn
Normal file
27
engine/src/flutter/tools/fuchsia/dart/BUILD.gn
Normal file
@@ -0,0 +1,27 @@
|
||||
# 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/fuchsia/dart/toolchain.gni")
|
||||
import("//flutter/tools/fuchsia/python/python_binary.gni")
|
||||
import("//flutter/tools/fuchsia/sdk/sdk_targets.gni")
|
||||
import("//flutter/tools/fuchsia/toolchain/basic_toolchain.gni")
|
||||
|
||||
python_binary("gen_dart_package_config") {
|
||||
main_source = "gen_dart_package_config.py"
|
||||
}
|
||||
|
||||
if (current_toolchain == default_toolchain) {
|
||||
# A toolchain dedicated to processing and analyzing Dart packages.
|
||||
# The only targets in this toolchain are action() targets, so it
|
||||
# has no real tools. But every toolchain needs stamp and copy.
|
||||
basic_toolchain("dartlang") {
|
||||
expected_label = dart_toolchain
|
||||
}
|
||||
}
|
||||
|
||||
if (current_toolchain != default_toolchain) {
|
||||
sdk_targets("dart_library") {
|
||||
meta = "$fuchsia_sdk_path/meta/manifest.json"
|
||||
}
|
||||
}
|
||||
24
engine/src/flutter/tools/fuchsia/dart/config.gni
Normal file
24
engine/src/flutter/tools/fuchsia/dart/config.gni
Normal file
@@ -0,0 +1,24 @@
|
||||
# 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/fuchsia/dart/dart_build_config.gni")
|
||||
|
||||
declare_args() {
|
||||
# Forces all Dart apps to build in product mode which is a
|
||||
# stripped down version of the VM running in AOT mode.
|
||||
dart_force_product = false
|
||||
|
||||
# TODO(fxbug.dev/64153) renable aot builds
|
||||
# if (dart_force_product) {
|
||||
# Product AOT
|
||||
# dart_default_build_cfg = dart_release_build_cfg
|
||||
# } else if (is_debug) {
|
||||
# Non-product JIT
|
||||
dart_default_build_cfg = dart_debug_build_cfg
|
||||
|
||||
# } else {
|
||||
# Non-product AOT
|
||||
# dart_default_build_cfg = dart_profile_build_cfg
|
||||
# }
|
||||
}
|
||||
22
engine/src/flutter/tools/fuchsia/dart/dart.gni
Normal file
22
engine/src/flutter/tools/fuchsia/dart/dart.gni
Normal file
@@ -0,0 +1,22 @@
|
||||
# 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.
|
||||
|
||||
# NOTE: Generally, the build rules in //flutter/tools/fuchsia/dart/,
|
||||
# //flutter/tools/fuchsia/dart/kernel/, and similar SUBDIRECTORIES of
|
||||
# //flutter/tools/fuchsia/ (such as //flutter/tools/fuchsia/flutter/)
|
||||
# mirror the directory paths and much of the build rule content of fuchsia.git
|
||||
# //build/...
|
||||
#
|
||||
# Most of the fuchsia-derived build rules were implemented after some similar
|
||||
# build rules already existed in the directory //flutter/tools/fuchsia/
|
||||
# and several existing build targets use these (legacy) build rules.
|
||||
# Though some rules and targets in //flutter/tools/fuchsia/ have similar names
|
||||
# to the fuchsia.git-derived rules, the rule structures and behavior can be
|
||||
# different. Therefore both are maintained for now.
|
||||
#
|
||||
# In the case of this file--dart.gni--some existing definitions from the
|
||||
# original dart.gni are relevant and useful to the new fuchsia.git-derived
|
||||
# rules, so these definitions can simply be imported.
|
||||
|
||||
import("//flutter/tools/fuchsia/dart.gni")
|
||||
51
engine/src/flutter/tools/fuchsia/dart/dart_build_config.gni
Normal file
51
engine/src/flutter/tools/fuchsia/dart/dart_build_config.gni
Normal file
@@ -0,0 +1,51 @@
|
||||
# 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.
|
||||
|
||||
# Builds the component in a non-product JIT build. This will
|
||||
# launch the vm service in the runner.
|
||||
dart_debug_build_cfg = {
|
||||
runtime_meta = "//flutter/shell/platform/fuchsia/dart_runner/meta/jit_runtime"
|
||||
runner_dep = "//flutter/shell/platform/fuchsia/dart_runner:dart_jit_runner"
|
||||
platform_name = "dart_runner"
|
||||
is_aot = false
|
||||
is_product = false
|
||||
enable_asserts = true
|
||||
}
|
||||
|
||||
# Builds the component in a non-product AOT build. This will
|
||||
# launch the vm service in the runner.
|
||||
# This configuration is not compatible with a --release build since the
|
||||
# profile aot runner is built without asserts.
|
||||
dart_aot_debug_build_cfg = {
|
||||
runtime_meta = "//flutter/shell/platform/fuchsia/dart_runner/meta/aot_runtime"
|
||||
runner_dep = "//flutter/shell/platform/fuchsia/dart_runner:dart_aot_runner"
|
||||
platform_name = "dart_runner"
|
||||
is_aot = true
|
||||
is_product = false
|
||||
enable_asserts = true
|
||||
}
|
||||
|
||||
# Builds the component in a non-product AOT build. This will
|
||||
# launch the vm service in the runner.
|
||||
dart_profile_build_cfg = {
|
||||
runtime_meta = "//flutter/shell/platform/fuchsia/dart_runner/meta/aot_runtime"
|
||||
runner_dep = "//flutter/shell/platform/fuchsia/dart_runner:dart_aot_runner"
|
||||
platform_name = "dart_runner"
|
||||
is_aot = true
|
||||
is_product = false
|
||||
enable_asserts = false
|
||||
}
|
||||
|
||||
# Builds the component in a product AOT build. This will
|
||||
# not launch the vm service in the runner.
|
||||
dart_release_build_cfg = {
|
||||
runtime_meta =
|
||||
"//flutter/shell/platform/fuchsia/dart_runner/meta/aot_product_runtime"
|
||||
runner_dep =
|
||||
"//flutter/shell/platform/fuchsia/dart_runner:dart_aot_product_runner"
|
||||
platform_name = "dart_runner"
|
||||
is_aot = true
|
||||
is_product = true
|
||||
enable_asserts = false
|
||||
}
|
||||
345
engine/src/flutter/tools/fuchsia/dart/dart_library.gni
Normal file
345
engine/src/flutter/tools/fuchsia/dart/dart_library.gni
Normal file
@@ -0,0 +1,345 @@
|
||||
# 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/fuchsia/dart/dart.gni")
|
||||
import("//flutter/tools/fuchsia/dart/dart_package_config.gni")
|
||||
import("//flutter/tools/fuchsia/dart/toolchain.gni")
|
||||
import("//flutter/tools/python/python3_action.gni")
|
||||
|
||||
# Defines a Dart library
|
||||
#
|
||||
# Parameters
|
||||
#
|
||||
# sources
|
||||
# The list of all sources in this library.
|
||||
# These sources must be within source_dir.
|
||||
#
|
||||
# package_root (optional)
|
||||
# Path to the directory hosting the library.
|
||||
# This is useful for generated content, and can be ignored otherwise.
|
||||
# Defaults to ".".
|
||||
#
|
||||
# package_name (optional)
|
||||
# Name of the Dart package. This is used as an identifier in code that
|
||||
# depends on this library.
|
||||
#
|
||||
# language_version (optional)
|
||||
# Specify the Dart language version to use for this package.
|
||||
# If language_version is not specified but pubspec is then the language
|
||||
# version will be read from the pubspec. If no language version can be
|
||||
# determined then we will default to version "2.8".
|
||||
# It is recommended to specify a language_version if it is well known
|
||||
# instead of relying on the pubspec file since this will improve compilation
|
||||
# times.
|
||||
#
|
||||
# infer_package_name (optional)
|
||||
# Infer the package name based on the path to the package.
|
||||
#
|
||||
# NOTE: Exactly one of package_name or infer_package_name must be set.
|
||||
#
|
||||
# source_dir (optional)
|
||||
# Path to the directory containing the package sources, relative to
|
||||
# package_root. All non third-party dart files under source_dir must be
|
||||
# included in sources.
|
||||
# Defaults to "lib".
|
||||
#
|
||||
# deps (optional)
|
||||
# List of labels this library depends on.
|
||||
#
|
||||
# TODO(fxb/63133): non_dart_deps is deprecated. Use deps instead.
|
||||
# non_dart_deps (optional, deprecated)
|
||||
# List of labels this library depends on that are not Dart libraries. This
|
||||
# includes things like actions that generate Dart code. It typically doesn't
|
||||
# need to be set.
|
||||
# Note that these labels *must* have an explicit toolchain attached.
|
||||
#
|
||||
# TODO(fxbug.dev/71902): set up allowlist for disable_source_verification when
|
||||
# dart_test no longer depends on dart_library.
|
||||
# NOTE: Do NOT disable source verification unless you are 100% sure it is
|
||||
# absolutely necessary.
|
||||
# disable_source_verification (optional)
|
||||
# Prevents source verification from being run on this target.
|
||||
#
|
||||
# extra_sources (optional)
|
||||
# Additional sources to consider for analysis.
|
||||
#
|
||||
# pubspec (optional)
|
||||
# Path to the pubspec.yaml. If not provided, will default to looking for
|
||||
# the pubspec.yaml in the package root. It is not common that this value will
|
||||
# need to be set but can be useful for generated code.
|
||||
#
|
||||
# options_file (optional)
|
||||
# Path to the analysis_options.yaml file. If not provided, will default to
|
||||
# looking for the analysis_options.yaml in the package root. It is not common
|
||||
# that this value needs to be set but can be useful for generated code.
|
||||
#
|
||||
# disable_metadata_entry (optional)
|
||||
# Prevents metedata entry from being written to the dart_packag_config json file.
|
||||
#
|
||||
# null_safe (optional)
|
||||
# A flag that enables null safety check in dart libraries.
|
||||
#
|
||||
# Example of usage:
|
||||
#
|
||||
# dart_library("baz") {
|
||||
# package_name = "foo.bar.baz"
|
||||
#
|
||||
# sources = [
|
||||
# "blah.dart",
|
||||
# ]
|
||||
#
|
||||
# deps = [
|
||||
# "//foo/bar/owl",
|
||||
# ]
|
||||
# }
|
||||
if (current_toolchain == dart_toolchain) {
|
||||
template("dart_library") {
|
||||
forward_variables_from(invoker,
|
||||
[
|
||||
"visibility",
|
||||
"hermetic_deps",
|
||||
])
|
||||
|
||||
if (defined(invoker.package_name)) {
|
||||
package_name = invoker.package_name
|
||||
} else if (defined(invoker.infer_package_name) &&
|
||||
invoker.infer_package_name) {
|
||||
# Compute a package name from the label:
|
||||
# //foo/bar --> foo.bar
|
||||
# //foo/bar:blah --> foo.bar._blah
|
||||
# //garnet/public/foo/bar --> foo.bar
|
||||
# Strip public directories.
|
||||
full_dir = get_label_info(":$target_name", "dir")
|
||||
package_name = full_dir
|
||||
package_name = string_replace(package_name, "//", "")
|
||||
package_name = string_replace(package_name, "/", ".")
|
||||
|
||||
# If the last directory name does not match the target name, add the
|
||||
# target name to the resulting package name.
|
||||
name = get_label_info(":$target_name", "name")
|
||||
last_dir = get_path_info(full_dir, "name")
|
||||
if (last_dir != name) {
|
||||
package_name = "$package_name._$name"
|
||||
}
|
||||
} else {
|
||||
assert(false, "Must specify either a package_name or infer_package_name")
|
||||
}
|
||||
|
||||
_dart_deps = []
|
||||
if (defined(invoker.deps)) {
|
||||
foreach(dep, invoker.deps) {
|
||||
_dart_deps += [ get_label_info(dep, "label_no_toolchain") ]
|
||||
}
|
||||
}
|
||||
|
||||
_non_dart_deps = []
|
||||
if (defined(invoker.non_dart_deps)) {
|
||||
_non_dart_deps += invoker.non_dart_deps
|
||||
}
|
||||
|
||||
package_root = "."
|
||||
if (defined(invoker.package_root)) {
|
||||
package_root = invoker.package_root
|
||||
}
|
||||
|
||||
source_dir = "$package_root/lib"
|
||||
if (defined(invoker.source_dir)) {
|
||||
source_dir = "$package_root/${invoker.source_dir}"
|
||||
}
|
||||
|
||||
assert(defined(invoker.sources), "Sources must be defined")
|
||||
|
||||
disable_source_verification =
|
||||
defined(invoker.disable_source_verification) &&
|
||||
invoker.disable_source_verification
|
||||
if (disable_source_verification && invoker.sources == []) {
|
||||
not_needed([ source_dir ])
|
||||
}
|
||||
|
||||
rebased_sources = []
|
||||
foreach(source, invoker.sources) {
|
||||
rebased_source_dir = rebase_path(source_dir)
|
||||
rebased_sources += [ "$rebased_source_dir/$source" ]
|
||||
}
|
||||
if (defined(invoker.extra_sources)) {
|
||||
foreach(source, invoker.extra_sources) {
|
||||
rebased_sources += [ rebase_path(source) ]
|
||||
}
|
||||
}
|
||||
source_file = "$target_gen_dir/$target_name.sources"
|
||||
write_file(source_file, rebased_sources, "list lines")
|
||||
|
||||
# Dependencies of the umbrella group for the targets in this file.
|
||||
group_deps = []
|
||||
|
||||
_public_deps = []
|
||||
if (defined(invoker.public_deps)) {
|
||||
_public_deps = invoker.public_deps
|
||||
}
|
||||
|
||||
_metadata = {
|
||||
package_config_entries = [
|
||||
{
|
||||
name = package_name
|
||||
if (defined(invoker.language_version)) {
|
||||
language_version = invoker.language_version
|
||||
} else if (defined(invoker.null_safe) && invoker.null_safe) {
|
||||
language_version = "2.12"
|
||||
} else if (defined(invoker.pubspec)) {
|
||||
pubspec_path = rebase_path(invoker.pubspec, root_build_dir)
|
||||
}
|
||||
root_uri = rebase_path(package_root, root_build_dir)
|
||||
if (defined(invoker.source_dir)) {
|
||||
package_uri = invoker.source_dir
|
||||
} else {
|
||||
package_uri = "lib"
|
||||
}
|
||||
},
|
||||
]
|
||||
dart_build_info = [
|
||||
{
|
||||
__is_current_target = false
|
||||
__package_name = package_name
|
||||
__deps = _dart_deps + _non_dart_deps
|
||||
__public_deps = _public_deps
|
||||
__rebased_sources = rebased_sources
|
||||
},
|
||||
]
|
||||
|
||||
dart_build_info_barrier = []
|
||||
}
|
||||
|
||||
# When we generate a package_config for the analyzer we need to make sure
|
||||
# that we are including this library in that file. The dart_package_config
|
||||
# collects metadata from its dependencies so we create this group to expose
|
||||
# that data. We also expose this in the group target below so that users of
|
||||
# the dart_package_config target can just add the targets to the deps list.
|
||||
_publish_metadata_target_name = "${target_name}_package_metadata"
|
||||
group(_publish_metadata_target_name) {
|
||||
metadata = _metadata
|
||||
}
|
||||
|
||||
_dart_package_config_target_name = "${target_name}_dart_package"
|
||||
_packages_path = "$target_gen_dir/${target_name}_package_config.json"
|
||||
dart_package_config(_dart_package_config_target_name) {
|
||||
# Do not publish the metadata to the dart_package_config json file if the
|
||||
# disable_metadata_entry flag is enabled in the dart_tool. The reason this is here
|
||||
# is to avoid entries that may have identical rootUris as fxb/58781 has highlighted.
|
||||
deps = _dart_deps
|
||||
if (!defined(invoker.disable_metadata_entry) ||
|
||||
!invoker.disable_metadata_entry) {
|
||||
deps += [ ":$_publish_metadata_target_name" ]
|
||||
}
|
||||
public_deps = _non_dart_deps
|
||||
outputs = [ _packages_path ]
|
||||
forward_variables_from(invoker, [ "testonly" ])
|
||||
}
|
||||
group_deps += [ ":$_dart_package_config_target_name" ]
|
||||
|
||||
################################
|
||||
# Dart source "verification"
|
||||
#
|
||||
# Warn if there are dart sources from the source directory that are
|
||||
# not explicitly part of sources. This may cause a failure when syncing to
|
||||
# another repository, as they will be excluded from the resulting BUILD
|
||||
# file.
|
||||
#
|
||||
# Also warn if nonexistent files are included in sources.
|
||||
if (!disable_source_verification) {
|
||||
source_verification_target_name = "${target_name}_source_verification"
|
||||
python3_action(source_verification_target_name) {
|
||||
script = "//flutter/tools/fuchsia/dart/verify_sources.py"
|
||||
output_file = "$target_gen_dir/$target_name.missing"
|
||||
|
||||
sources = rebased_sources
|
||||
outputs = [ output_file ]
|
||||
|
||||
args = [
|
||||
"--source_dir",
|
||||
rebase_path(source_dir),
|
||||
"--stamp",
|
||||
rebase_path(output_file),
|
||||
] + invoker.sources
|
||||
|
||||
forward_variables_from(invoker, [ "testonly" ])
|
||||
|
||||
# Deps may include codegen dependencies that generate dart sources.
|
||||
deps = _dart_deps + _non_dart_deps
|
||||
}
|
||||
group_deps += [ ":$source_verification_target_name" ]
|
||||
}
|
||||
|
||||
# Generate a file that lists files containing full (including all direct and
|
||||
# transitive dependencies) sources for this target's dependencies.
|
||||
_all_deps_sources_list_target = "${target_name}.all_deps_sources.list"
|
||||
_all_deps_sources_list_file =
|
||||
"${target_gen_dir}/${target_name}.all_deps_sources.list"
|
||||
generated_file(_all_deps_sources_list_target) {
|
||||
forward_variables_from(invoker, [ "testonly" ])
|
||||
outputs = [ _all_deps_sources_list_file ]
|
||||
data_keys = [ "all_deps_sources" ]
|
||||
walk_keys = [ "all_deps_sources_barrier" ]
|
||||
deps = _dart_deps
|
||||
}
|
||||
|
||||
# Generate full sources for this target by combining sources of this target
|
||||
# with full sources of all dependencies.
|
||||
#
|
||||
# The generated file contains sources of this target and all of its direct
|
||||
# and transitive dependencies.
|
||||
#
|
||||
# The output file is useful when writing depfiles for actions like dart
|
||||
# analyzer, which recursively reads all sources.
|
||||
_all_deps_sources_target = "${target_name}.all_deps_sources"
|
||||
_all_deps_sources_file = "${target_gen_dir}/${target_name}.all_deps_sources"
|
||||
python3_action(_all_deps_sources_target) {
|
||||
forward_variables_from(invoker, [ "testonly" ])
|
||||
|
||||
script = "//flutter/tools/fuchsia/dart/merge_deps_sources.py"
|
||||
|
||||
outputs = [ _all_deps_sources_file ]
|
||||
depfile = "${_all_deps_sources_file}.d"
|
||||
args = [
|
||||
"--output",
|
||||
rebase_path(outputs[0], root_build_dir),
|
||||
"--depfile",
|
||||
rebase_path(depfile, root_build_dir),
|
||||
"--source_lists",
|
||||
"@" + rebase_path(_all_deps_sources_list_file, root_build_dir),
|
||||
"--sources",
|
||||
] + rebase_path(rebased_sources, root_build_dir)
|
||||
|
||||
inputs = [ _all_deps_sources_list_file ]
|
||||
deps = [ ":${_all_deps_sources_list_target}" ]
|
||||
metadata = {
|
||||
all_deps_sources = [ rebase_path(outputs[0], root_build_dir) ]
|
||||
all_deps_sources_barrier = []
|
||||
}
|
||||
}
|
||||
group_deps += [ ":${_all_deps_sources_target}" ]
|
||||
|
||||
not_needed(invoker, [ "options_file" ])
|
||||
|
||||
group(target_name) {
|
||||
# _dart_deps are added here to ensure they are fully built.
|
||||
# Up to this point, only the targets generating .packages had been
|
||||
# depended on.
|
||||
deps = _dart_deps + _non_dart_deps
|
||||
|
||||
public_deps = group_deps
|
||||
|
||||
metadata = _metadata
|
||||
forward_variables_from(invoker, [ "testonly" ])
|
||||
}
|
||||
}
|
||||
} else { # Not the Dart toolchain.
|
||||
template("dart_library") {
|
||||
group(target_name) {
|
||||
forward_variables_from(invoker, [ "testonly" ])
|
||||
not_needed(invoker, "*")
|
||||
|
||||
public_deps = [ ":$target_name($dart_toolchain)" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
117
engine/src/flutter/tools/fuchsia/dart/dart_package_config.gni
Normal file
117
engine/src/flutter/tools/fuchsia/dart/dart_package_config.gni
Normal file
@@ -0,0 +1,117 @@
|
||||
# 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.
|
||||
|
||||
# Generates a package_config.json file containing all of the packages used
|
||||
# to generate a kernel file.
|
||||
#
|
||||
# Package configs are files which describe metadata about a dart package.
|
||||
# This includes information like the name, dart language version, where to
|
||||
# find the files, etc. The file is required by the dart kernel compiler.
|
||||
#
|
||||
# Parameters
|
||||
#
|
||||
# deps, public_deps (optional)
|
||||
# [list of labels] The targets to generate a manifest for.
|
||||
# See `gn help` for more details.
|
||||
#
|
||||
# testonly, visibility, metadata (optional)
|
||||
# See `gn help`.
|
||||
#
|
||||
# outputs (optional)
|
||||
# Singleton list containing the path to the package_config file.
|
||||
# Defaults to `[ "$target_gen_dir/${target_name}_package_config.json" ]`.
|
||||
template("dart_package_config") {
|
||||
main_target = target_name
|
||||
generate_target = "${target_name}_generate"
|
||||
|
||||
# Build the name of the output file.
|
||||
if (defined(invoker.outputs)) {
|
||||
_outputs = invoker.outputs
|
||||
assert(_outputs != [] && _outputs == [ _outputs[0] ],
|
||||
"Outputs list must have exactly one element.")
|
||||
package_config_file = _outputs[0]
|
||||
} else {
|
||||
package_config_file = "$target_gen_dir/${target_name}_package_config.json"
|
||||
}
|
||||
intermediate_file = "$package_config_file.partial"
|
||||
|
||||
# Gather metadata about runtime objects.
|
||||
generated_file(generate_target) {
|
||||
forward_variables_from(invoker,
|
||||
[
|
||||
"deps",
|
||||
"public_deps",
|
||||
"testonly",
|
||||
])
|
||||
|
||||
visibility = [ ":$main_target" ]
|
||||
|
||||
data_keys = [
|
||||
# A list of package configuration entries
|
||||
#
|
||||
# Each entry must contain these values:
|
||||
# - `name`: The name of the package;
|
||||
# - `root_uri`: Path to the package root relative to root_build_dir;
|
||||
# - `package_uri`: The path in which the source lives
|
||||
#
|
||||
# The following entries may optionally be specified
|
||||
# - `language_version`: The dart language version.
|
||||
# - `pubspec_path`: The path to the pubspec file to find the language version
|
||||
"package_config_entries",
|
||||
]
|
||||
walk_keys = [ "package_config_entry_barrier" ]
|
||||
|
||||
outputs = [ intermediate_file ]
|
||||
|
||||
output_conversion = "json"
|
||||
}
|
||||
|
||||
# Converts the intermediate to a real pacakge_config.json file.
|
||||
action(main_target) {
|
||||
forward_variables_from(invoker,
|
||||
[
|
||||
"deps",
|
||||
"public_deps",
|
||||
"testonly",
|
||||
"visibility",
|
||||
])
|
||||
|
||||
script =
|
||||
get_label_info("//flutter/tools/fuchsia/dart:gen_dart_package_config",
|
||||
"target_out_dir") + "/gen_dart_package_config.pyz"
|
||||
|
||||
inputs = [ intermediate_file ]
|
||||
outputs = [ package_config_file ]
|
||||
depfile = "${target_gen_dir}/${target_name}.d"
|
||||
|
||||
args = [
|
||||
"--input",
|
||||
rebase_path(intermediate_file, root_build_dir),
|
||||
"--output",
|
||||
rebase_path(package_config_file, root_build_dir),
|
||||
"--root",
|
||||
rebase_path("//", root_build_dir),
|
||||
"--depfile",
|
||||
rebase_path(depfile, root_build_dir),
|
||||
]
|
||||
|
||||
if (!defined(deps)) {
|
||||
deps = []
|
||||
}
|
||||
deps += [
|
||||
":$generate_target",
|
||||
"//flutter/tools/fuchsia/dart:gen_dart_package_config",
|
||||
]
|
||||
|
||||
metadata = {
|
||||
# Add a barrier here to avoid double of inclusion of elements listed in
|
||||
# the generated package config.
|
||||
package_config_entry_barrier = []
|
||||
|
||||
if (defined(invoker.metadata)) {
|
||||
forward_variables_from(invoker.metadata, "*")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
105
engine/src/flutter/tools/fuchsia/dart/dart_tool.gni
Normal file
105
engine/src/flutter/tools/fuchsia/dart/dart_tool.gni
Normal file
@@ -0,0 +1,105 @@
|
||||
# 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/fuchsia/dart/dart_library.gni")
|
||||
import("//flutter/tools/fuchsia/dart/dart_package_config.gni")
|
||||
import("//flutter/tools/fuchsia/dart/toolchain.gni")
|
||||
|
||||
import("//flutter/tools/python/python3_action.gni")
|
||||
|
||||
# Wraps a dart snapshot in a script to be invoked by dart
|
||||
#
|
||||
# Parameters
|
||||
#
|
||||
# dart (required)
|
||||
# The path to the dart binary
|
||||
#
|
||||
# snapshot (required)
|
||||
# The path to the dart snapshot
|
||||
#
|
||||
# deps (optional)
|
||||
# Dependencies of this application
|
||||
#
|
||||
# output_name (optional)
|
||||
# Name of the output file to generate. Defaults to $target_name.
|
||||
template("_dart_snapshot_invocation") {
|
||||
assert(defined(invoker.dart), "Must specify the path to the dart binary")
|
||||
assert(defined(invoker.snapshot),
|
||||
"Must specify the path to the dart snapshot")
|
||||
|
||||
if (defined(invoker.output_name)) {
|
||||
app_name = invoker.output_name
|
||||
} else {
|
||||
app_name = target_name
|
||||
}
|
||||
|
||||
# Builds a convenience script to invoke the app.
|
||||
python3_action(target_name) {
|
||||
forward_variables_from(invoker,
|
||||
[
|
||||
"testonly",
|
||||
"deps",
|
||||
])
|
||||
|
||||
script = "//flutter/tools/fuchsia/dart/gen_app_invocation.py"
|
||||
|
||||
app_path = "$root_out_dir/dart-tools/$app_name"
|
||||
dart_binary = invoker.dart
|
||||
snapshot = invoker.snapshot
|
||||
|
||||
inputs = [
|
||||
dart_binary,
|
||||
snapshot,
|
||||
]
|
||||
outputs = [ app_path ]
|
||||
|
||||
args = [
|
||||
"--out",
|
||||
rebase_path(app_path, root_build_dir),
|
||||
|
||||
# `--dart` and `--snapshot` are used in the output app script, use
|
||||
# absolute path so the script would work regardless where it's invoked.
|
||||
"--dart",
|
||||
rebase_path(dart_binary),
|
||||
"--snapshot",
|
||||
rebase_path(snapshot),
|
||||
]
|
||||
|
||||
metadata = {
|
||||
# Record metadata for the //:tool_paths build API.
|
||||
tool_paths = [
|
||||
{
|
||||
cpu = current_cpu
|
||||
label = get_label_info(":$target_name", "label_with_toolchain")
|
||||
name = app_name
|
||||
os = current_os
|
||||
path = rebase_path(app_path, root_build_dir)
|
||||
},
|
||||
]
|
||||
snapshot_path = [ rebase_path(snapshot, root_build_dir) ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Defines a Dart application that can be run on the host which is
|
||||
# compiled from an existing snapshot
|
||||
#
|
||||
# Parameters
|
||||
#
|
||||
# snapshot (required)
|
||||
# The path to the dart snapshot
|
||||
#
|
||||
# deps (optional)
|
||||
# Dependencies of this application
|
||||
#
|
||||
# output_name (optional)
|
||||
# Name of the output file to generate. Defaults to $target_name.
|
||||
template("dart_prebuilt_tool") {
|
||||
assert(defined(invoker.snapshot),
|
||||
"Must specify the path to the dart snapshot")
|
||||
_dart_snapshot_invocation(target_name) {
|
||||
dart = prebuilt_dart
|
||||
forward_variables_from(invoker, "*")
|
||||
}
|
||||
}
|
||||
95
engine/src/flutter/tools/fuchsia/dart/fidl_dart.gni
Normal file
95
engine/src/flutter/tools/fuchsia/dart/fidl_dart.gni
Normal file
@@ -0,0 +1,95 @@
|
||||
# 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/fuchsia/sdk.gni")
|
||||
import("//flutter/tools/executable_action.gni")
|
||||
import("//flutter/tools/fuchsia/dart/dart_library.gni")
|
||||
import("//flutter/tools/fuchsia/dart/toolchain.gni")
|
||||
import("//flutter/tools/fuchsia/fidl/fidl.gni")
|
||||
import("//flutter/tools/fuchsia/fidl/toolchain.gni")
|
||||
|
||||
# Generates some Dart bindings for a FIDL library.
|
||||
#
|
||||
# The parameters for this template are defined in //flutter/tools/fuchsia/fidl/fidl.gni. The
|
||||
# relevant parameters in this template are:
|
||||
# - name;
|
||||
|
||||
template("fidl_dart") {
|
||||
assert(current_toolchain == dart_toolchain,
|
||||
"This template can only be used in the $dart_toolchain toolchain.")
|
||||
|
||||
not_needed(invoker, [ "sources" ])
|
||||
|
||||
main_target_name = target_name
|
||||
generation_target_name = "${target_name}_dart_generate"
|
||||
|
||||
library_name = target_name
|
||||
root_dir = "$target_gen_dir/${library_name}_package"
|
||||
if (defined(invoker.name)) {
|
||||
library_name = invoker.name
|
||||
root_dir = "$target_gen_dir/${target_name}_${library_name}_package"
|
||||
}
|
||||
bindings_dir = "$root_dir/lib"
|
||||
async_bindings_file = "$bindings_dir/fidl_async.dart"
|
||||
test_bindings_file = "$bindings_dir/fidl_test.dart"
|
||||
|
||||
fidl_target_gen_dir =
|
||||
get_label_info(":bogus($fidl_toolchain)", "target_gen_dir")
|
||||
json_representation = "$fidl_target_gen_dir/$target_name.fidl.json"
|
||||
|
||||
executable_action(generation_target_name) {
|
||||
visibility = [ ":*" ]
|
||||
|
||||
tool = "${fuchsia_sdk_path}/tools/fidlgen_dart"
|
||||
|
||||
inputs = [ json_representation ]
|
||||
|
||||
outputs = [
|
||||
async_bindings_file,
|
||||
test_bindings_file,
|
||||
]
|
||||
|
||||
args = [
|
||||
"--json",
|
||||
rebase_path(json_representation, root_build_dir),
|
||||
"--output-async",
|
||||
rebase_path(async_bindings_file, root_build_dir),
|
||||
"--output-test",
|
||||
rebase_path(test_bindings_file, root_build_dir),
|
||||
]
|
||||
|
||||
deps = [ ":$main_target_name($fidl_toolchain)" ]
|
||||
forward_variables_from(invoker, [ "testonly" ])
|
||||
}
|
||||
|
||||
dart_library(main_target_name) {
|
||||
forward_variables_from(invoker,
|
||||
[
|
||||
"testonly",
|
||||
"visibility",
|
||||
])
|
||||
|
||||
package_root = root_dir
|
||||
|
||||
package_name = "fidl_" + string_replace(library_name, ".", "_")
|
||||
|
||||
null_safe = true
|
||||
|
||||
sources = [
|
||||
rebase_path(async_bindings_file, bindings_dir),
|
||||
rebase_path(test_bindings_file, bindings_dir),
|
||||
]
|
||||
|
||||
deps = [ ":$generation_target_name" ]
|
||||
|
||||
if (defined(invoker.public_deps)) {
|
||||
deps += invoker.public_deps
|
||||
}
|
||||
|
||||
# invoker.deps are the non_fidl_deps passed in to the fidl() rule
|
||||
if (defined(invoker.deps)) {
|
||||
deps += invoker.deps
|
||||
}
|
||||
}
|
||||
}
|
||||
44
engine/src/flutter/tools/fuchsia/dart/gen_app_invocation.py
Executable file
44
engine/src/flutter/tools/fuchsia/dart/gen_app_invocation.py
Executable file
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env python3.8
|
||||
# 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 argparse
|
||||
import os
|
||||
import stat
|
||||
import string
|
||||
import sys
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Generate a script that invokes a Dart application')
|
||||
parser.add_argument(
|
||||
'--out', help='Path to the invocation file to generate', required=True)
|
||||
parser.add_argument('--dart', help='Path to the Dart binary', required=True)
|
||||
parser.add_argument(
|
||||
'--snapshot', help='Path to the app snapshot', required=True)
|
||||
args = parser.parse_args()
|
||||
|
||||
app_file = args.out
|
||||
app_path = os.path.dirname(app_file)
|
||||
if not os.path.exists(app_path):
|
||||
os.makedirs(app_path)
|
||||
|
||||
script_template = string.Template(
|
||||
'''#!/bin/sh
|
||||
|
||||
$dart \\
|
||||
$snapshot \\
|
||||
"$$@"
|
||||
''')
|
||||
with open(app_file, 'w') as file:
|
||||
file.write(script_template.substitute(args.__dict__))
|
||||
permissions = (
|
||||
stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR | stat.S_IRGRP |
|
||||
stat.S_IWGRP | stat.S_IXGRP | stat.S_IROTH)
|
||||
os.chmod(app_file, permissions)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
135
engine/src/flutter/tools/fuchsia/dart/gen_dart_package_config.py
Executable file
135
engine/src/flutter/tools/fuchsia/dart/gen_dart_package_config.py
Executable file
@@ -0,0 +1,135 @@
|
||||
#!/usr/bin/env python3.8
|
||||
# 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.
|
||||
"""Reads the contents of a package config file generated by the build and
|
||||
converts it to a real package_config.json file
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import collections
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import yaml
|
||||
|
||||
DEFAULT_LANGUAGE_VERSION = '2.8'
|
||||
|
||||
Package = collections.namedtuple(
|
||||
'Package', ['name', 'rootUri', 'languageVersion', 'packageUri'])
|
||||
|
||||
|
||||
class PackageConfig:
|
||||
# The version of the package config.
|
||||
VERSION = 2
|
||||
|
||||
# The name of the generator which gets written to the json output
|
||||
GENERATOR_NAME = os.path.basename(__file__)
|
||||
|
||||
def __init__(self, packages):
|
||||
self.packages = packages
|
||||
|
||||
def asdict(self):
|
||||
"""Converts the package config to a dictionary"""
|
||||
return {
|
||||
'configVersion': self.VERSION,
|
||||
'packages': [p._asdict() for p in sorted(self.packages)],
|
||||
'generator': self.GENERATOR_NAME,
|
||||
}
|
||||
|
||||
|
||||
def language_version_from_pubspec(pubspec):
|
||||
"""Parse the content of a pubspec.yaml"""
|
||||
with open(pubspec) as pubspec:
|
||||
parsed = yaml.safe_load(pubspec)
|
||||
if not parsed:
|
||||
return DEFAULT_LANGUAGE_VERSION
|
||||
|
||||
# If a format like sdk: '>=a.b' or sdk: 'a.b' is found, we'll use a.b.
|
||||
# In all other cases we default to "2.8"
|
||||
env_sdk = parsed.get('environment', {}).get('sdk', 'any')
|
||||
match = re.search(r'^(>=)?((0|[1-9]\d*)\.(0|[1-9]\d*))', env_sdk)
|
||||
if match:
|
||||
min_sdk_version = match.group(2)
|
||||
else:
|
||||
min_sdk_version = DEFAULT_LANGUAGE_VERSION
|
||||
|
||||
return min_sdk_version
|
||||
|
||||
|
||||
def collect_packages(items, relative_to):
|
||||
"""Reads metadata produced by GN to create lists of packages and pubspecs.
|
||||
- items: a list of objects collected from gn
|
||||
- relative_to: The directory which the packages are relative to. This is
|
||||
the location that contains the package_config.json file
|
||||
|
||||
Returns None if there was a problem parsing packages
|
||||
"""
|
||||
packages = []
|
||||
pubspec_paths = []
|
||||
for item in items:
|
||||
if 'language_version' in item:
|
||||
language_version = item['language_version']
|
||||
elif 'pubspec_path' in item:
|
||||
pubspec_paths.append(item['pubspec_path'])
|
||||
language_version = language_version_from_pubspec(
|
||||
item['pubspec_path'])
|
||||
else:
|
||||
language_version = DEFAULT_LANGUAGE_VERSION
|
||||
|
||||
package = Package(
|
||||
name=item['name'],
|
||||
rootUri=os.path.relpath(item['root_uri'], relative_to),
|
||||
languageVersion=language_version,
|
||||
packageUri=item['package_uri'])
|
||||
|
||||
# TODO(fxbug.dev/56428): enable once we sort out our duplicate packages
|
||||
# for p in packages:
|
||||
# if p.rootUri == package.rootUri:
|
||||
# print('Failed to create package_config.json file')
|
||||
# print('The following packages contain the same package root ' + p.rootUri)
|
||||
# print(' - ' + p.rootUri)
|
||||
# print(' - ' + package.rootUri)
|
||||
# return None
|
||||
|
||||
packages.append(package)
|
||||
|
||||
return packages, pubspec_paths
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument(
|
||||
'--input', help='Path to original package_config', required=True)
|
||||
parser.add_argument(
|
||||
'--output', help='Path to the updated package_config', required=True)
|
||||
parser.add_argument('--root', help='Path to fuchsia root', required=True)
|
||||
parser.add_argument('--depfile', help='Path to the depfile', required=True)
|
||||
args = parser.parse_args()
|
||||
|
||||
with open(args.input, 'r') as input_file:
|
||||
contents = json.load(input_file)
|
||||
|
||||
output_dir = os.path.dirname(os.path.abspath(args.output))
|
||||
packages, pubspec_paths = collect_packages(contents, output_dir)
|
||||
if packages is None:
|
||||
return 1
|
||||
|
||||
with open(args.depfile, 'w') as depfile:
|
||||
depfile.write('%s: %s' % (args.output, ' '.join(pubspec_paths)))
|
||||
|
||||
with open(args.output, 'w') as output_file:
|
||||
package_config = PackageConfig(packages)
|
||||
json.dump(
|
||||
package_config.asdict(),
|
||||
output_file,
|
||||
indent=2,
|
||||
sort_keys=True,
|
||||
separators=(',', ': '))
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
9
engine/src/flutter/tools/fuchsia/dart/kernel/BUILD.gn
Normal file
9
engine/src/flutter/tools/fuchsia/dart/kernel/BUILD.gn
Normal file
@@ -0,0 +1,9 @@
|
||||
# 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/fuchsia/dart/dart_tool.gni")
|
||||
|
||||
dart_prebuilt_tool("gen_kernel") {
|
||||
snapshot = "//third_party/dart/pkg/vm/bin/gen_kernel.dart"
|
||||
}
|
||||
58
engine/src/flutter/tools/fuchsia/dart/kernel/convert_manifest_to_json.py
Executable file
58
engine/src/flutter/tools/fuchsia/dart/kernel/convert_manifest_to_json.py
Executable file
@@ -0,0 +1,58 @@
|
||||
#!/usr/bin/env python3.8
|
||||
# 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.
|
||||
'''Reads the contents of a kernel manifest generated by the build and
|
||||
converts it to a format suitable for distribution_entries
|
||||
'''
|
||||
|
||||
import argparse
|
||||
import collections
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
|
||||
Entry = collections.namedtuple('Entry', ['source', 'destination'])
|
||||
|
||||
|
||||
def collect(lines):
|
||||
'''Reads the kernel manifest and creates an array of Entry objects.
|
||||
- lines: a list of lines from the manifest
|
||||
'''
|
||||
entries = []
|
||||
for line in lines:
|
||||
values = line.split("=", 1)
|
||||
entries.append(Entry(source=values[1], destination=values[0]))
|
||||
|
||||
return entries
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument(
|
||||
'--input', help='Path to original manifest', required=True)
|
||||
parser.add_argument(
|
||||
'--output', help='Path to the updated json file', required=True)
|
||||
args = parser.parse_args()
|
||||
|
||||
with open(args.input, 'r') as input_file:
|
||||
contents = input_file.read().splitlines()
|
||||
|
||||
entries = collect(contents)
|
||||
|
||||
if entries is None:
|
||||
return 1
|
||||
|
||||
with open(args.output, 'w') as output_file:
|
||||
json.dump(
|
||||
[e._asdict() for e in entries],
|
||||
output_file,
|
||||
indent=2,
|
||||
sort_keys=True,
|
||||
separators=(',', ': '))
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
329
engine/src/flutter/tools/fuchsia/dart/kernel/dart_kernel.gni
Normal file
329
engine/src/flutter/tools/fuchsia/dart/kernel/dart_kernel.gni
Normal file
@@ -0,0 +1,329 @@
|
||||
# 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.
|
||||
|
||||
# NOTE: Generally, the build rules in //flutter/tools/fuchsia/dart/,
|
||||
# //flutter/tools/fuchsia/dart/kernel/, and similar SUBDIRECTORIES of
|
||||
# //flutter/tools/fuchsia/ (such as //flutter/tools/fuchsia/flutter/)
|
||||
# mirror the directory paths and much of the build rule content of fuchsia.git
|
||||
# //build/...
|
||||
#
|
||||
# Most of the fuchsia-derived build rules were implemented after some similar
|
||||
# build rules already existed in the directory //flutter/tools/fuchsia/
|
||||
# and several existing build targets use these (legacy) build rules.
|
||||
# Though some rules and targets in //flutter/tools/fuchsia/ have similar names
|
||||
# to the fuchsia.git-derived rules, the rule structures and behavior can be
|
||||
# different. Therefore both are maintained for now.
|
||||
#
|
||||
# This file--dart_kernel.gni--and its primary template--dart_kernel()--match
|
||||
# pre-existing (legacy) template and filename in
|
||||
# //flutter/tools/fuchsia/dart_kernel.gni.
|
||||
#
|
||||
# The templates appear to have different behavior, so both will be maintained
|
||||
# until we can determine a better way to reconcile them.
|
||||
|
||||
import("//flutter/tools/fuchsia/dart/config.gni")
|
||||
import("//flutter/tools/fuchsia/dart/dart_library.gni")
|
||||
import("//flutter/tools/fuchsia/dart/toolchain.gni")
|
||||
|
||||
import("//flutter/tools/python/python3_action.gni")
|
||||
|
||||
_gen_kernel_label =
|
||||
"//flutter/tools/fuchsia/dart/kernel:gen_kernel($host_toolchain)"
|
||||
_gen_kernel_path =
|
||||
get_label_info(_gen_kernel_label, "root_out_dir") + "/dart-tools/gen_kernel"
|
||||
|
||||
flutter_platform_name = "flutter_runner"
|
||||
|
||||
# Converts the kernel manifest file from fini format to JSON format and
|
||||
# registers the metadata for the fuchsia_package to pick up.
|
||||
#
|
||||
# Parameters
|
||||
#
|
||||
# manifest (required)
|
||||
# Path to the kernel manifest
|
||||
# Type: Path
|
||||
template("_convert_kernel_manifest") {
|
||||
assert(defined(invoker.manifest), "dart_kernel() requires a manifest")
|
||||
|
||||
python3_action(target_name) {
|
||||
forward_variables_from(invoker,
|
||||
[
|
||||
"deps",
|
||||
"testonly",
|
||||
"visibility",
|
||||
])
|
||||
_converted_file_name =
|
||||
"${target_gen_dir}/${target_name}_kernel_manifest.json"
|
||||
|
||||
script = "//flutter/tools/fuchsia/dart/kernel/convert_manifest_to_json.py"
|
||||
args = [
|
||||
"--input",
|
||||
rebase_path(invoker.manifest, root_build_dir),
|
||||
"--output",
|
||||
rebase_path(_converted_file_name, root_build_dir),
|
||||
]
|
||||
|
||||
sources = [ invoker.manifest ]
|
||||
|
||||
outputs = [ _converted_file_name ]
|
||||
|
||||
metadata = {
|
||||
distribution_entries = [
|
||||
{
|
||||
file = rebase_path(_converted_file_name, root_build_dir)
|
||||
label = get_label_info(target_name, "label_with_toolchain")
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Generates dill files for a Dart application.
|
||||
#
|
||||
# It is not likely that this target will be used directly. Instead, developers
|
||||
# should use the dart_tool or dart/flutter_component targets which create a
|
||||
# kernel for you.
|
||||
#
|
||||
# Parameters
|
||||
#
|
||||
# platform_name (required)
|
||||
# The name of the platform, either "flutter_runner" or "dart_runner".
|
||||
#
|
||||
# packages_path (required)
|
||||
# Path to the package_config.json file.
|
||||
#
|
||||
# main_dart (required, mutually exclusive)
|
||||
# Path to Dart source file containing main(). Mutually exclusive with
|
||||
# main_dart_file. This is relative to source_dir, should exist in the
|
||||
# main_package, and uses a package: URI.
|
||||
#
|
||||
# main_package (required, mutually exclusive)
|
||||
# The name of the package which contains main. Mutually exclusive with
|
||||
# main_dart_file.
|
||||
#
|
||||
# main_dart_file (required, mutually exclusive)
|
||||
# Path to Dart source file containing main(). Mutually exclusive with
|
||||
# main_dart. This doesn't need to necessarily exist in main_package and uses
|
||||
# a fuchsia-source: URI.
|
||||
#
|
||||
# product (required)
|
||||
# Whether this should be built with the product runner.
|
||||
#
|
||||
# is_aot required)
|
||||
# Whether this kernel is an aot build.
|
||||
#
|
||||
# generate_manifest (optional)
|
||||
# Whether the compiler should generate a kernel manifest containing the list
|
||||
# of partial dill files in JIT builds. This flag is ignored in aot builds
|
||||
# Default: false
|
||||
#
|
||||
# kernel_path (optional)
|
||||
# The path to the kernel output. Defaults to target_gen_dir/${target_name}.dil
|
||||
#
|
||||
# kernel_target_name (optional)
|
||||
# The name of the kernel target. This parameter is required if you are
|
||||
# depending on the kernel_path for an input. This allows you to establish a
|
||||
# dependency chain on the generated file.
|
||||
#
|
||||
# args (optional)
|
||||
# A list of additional arguments to the compiler.dart program in this
|
||||
# directory that generates the kernel files.
|
||||
#
|
||||
# link_platform (optional)
|
||||
# Whether the kernel compiler should link the current platform.dill into
|
||||
# the build. If false, the --no-link-platform flag will be passed to the
|
||||
# compiler. Defaults to false
|
||||
template("dart_kernel") {
|
||||
assert(defined(invoker.platform_name), "dart_kernel() requires platform_name")
|
||||
assert(defined(invoker.packages_path),
|
||||
"dart_kernel() requires the path to the package config")
|
||||
assert(
|
||||
(defined(invoker.main_dart) && defined(invoker.main_package)) !=
|
||||
defined(invoker.main_dart_file),
|
||||
"dart_kernel() requires either (main_dart and main_package) or main_dart_file")
|
||||
assert(defined(invoker.product), "dart_kernel() requires product")
|
||||
assert(defined(invoker.is_aot), "dart_kernel() requires is_aot")
|
||||
|
||||
if (defined(invoker.kernel_target_name)) {
|
||||
_kernel_target_name = invoker.kernel_target_name
|
||||
} else {
|
||||
_kernel_target_name = "${target_name}_kernel"
|
||||
}
|
||||
_group_deps = [ ":$_kernel_target_name" ]
|
||||
|
||||
_kernel_deps = []
|
||||
if (defined(invoker.deps)) {
|
||||
_kernel_deps += invoker.deps
|
||||
}
|
||||
|
||||
_generate_manifest = false
|
||||
if (invoker.is_aot) {
|
||||
not_needed(invoker, [ "generate_manifest" ])
|
||||
} else {
|
||||
if (defined(invoker.generate_manifest) && invoker.generate_manifest) {
|
||||
_generate_manifest = true
|
||||
}
|
||||
}
|
||||
|
||||
if (_generate_manifest) {
|
||||
_kernel_manifest = "$target_gen_dir/${target_name}.dilpmanifest"
|
||||
|
||||
_convert_target_name = "${target_name}_convert_kernel_manifest"
|
||||
_convert_kernel_manifest(_convert_target_name) {
|
||||
forward_variables_from(invoker,
|
||||
[
|
||||
"testonly",
|
||||
"visibility",
|
||||
])
|
||||
manifest = _kernel_manifest
|
||||
|
||||
# must depend on the kernel target so we have the kernel manifest
|
||||
deps = [ ":$_kernel_target_name" ]
|
||||
}
|
||||
|
||||
_group_deps += [ ":$_convert_target_name" ]
|
||||
}
|
||||
|
||||
python3_action(_kernel_target_name) {
|
||||
forward_variables_from(invoker,
|
||||
[
|
||||
"testonly",
|
||||
"visibility",
|
||||
])
|
||||
|
||||
if (defined(invoker.kernel_path)) {
|
||||
_kernel_path = invoker.kernel_path
|
||||
} else {
|
||||
_kernel_path =
|
||||
"$target_gen_dir/__untraced_dart_kernel__/${target_name}.dil"
|
||||
}
|
||||
|
||||
depfile = "${_kernel_path}.d"
|
||||
|
||||
_kernel_deps += [ _gen_kernel_label ]
|
||||
|
||||
if (invoker.platform_name == flutter_platform_name) {
|
||||
_kernel_deps += [
|
||||
"//flutter/shell/platform/fuchsia/flutter/kernel:kernel_platform_files",
|
||||
]
|
||||
_platform_path = "$root_out_dir/flutter_runner_patched_sdk"
|
||||
} else {
|
||||
assert(false,
|
||||
"platform_name must be either dart_runner or flutter_runner")
|
||||
}
|
||||
|
||||
_platform_strong_dill = "${_platform_path}/platform_strong.dill"
|
||||
inputs = [
|
||||
_gen_kernel_path,
|
||||
_platform_strong_dill,
|
||||
invoker.packages_path,
|
||||
]
|
||||
outputs = [ _kernel_path ]
|
||||
|
||||
if (_generate_manifest) {
|
||||
outputs += [
|
||||
# Explicit output when using --manifest.
|
||||
_kernel_manifest,
|
||||
|
||||
# Implicit output when using --manifest; see createManifest in compiler.dart.
|
||||
_kernel_manifest + ".dilplist",
|
||||
_kernel_manifest + ".frameworkversion",
|
||||
]
|
||||
}
|
||||
|
||||
_multi_root_scheme = "fuchsia-source"
|
||||
|
||||
# Rebase against // instead of root_build_dir since the package_config is
|
||||
# relative to the sources.
|
||||
_rebased_packages_path = rebase_path(invoker.packages_path, "//")
|
||||
|
||||
# gen_kernel writes absolute paths to depfiles, convert them to relative.
|
||||
# See more information in https://fxbug.dev/75451.
|
||||
script = "//flutter/tools/fuchsia/depfile_path_to_relative.py"
|
||||
args = [
|
||||
"--depfile=" + rebase_path(depfile, root_build_dir),
|
||||
"--",
|
||||
rebase_path(_gen_kernel_path, root_out_dir),
|
||||
]
|
||||
if (defined(invoker.args)) {
|
||||
args += invoker.args
|
||||
}
|
||||
args += [
|
||||
"--verbosity=warning",
|
||||
"--no-sound-null-safety",
|
||||
"--target",
|
||||
invoker.platform_name,
|
||||
"--platform",
|
||||
rebase_path(_platform_strong_dill, root_build_dir),
|
||||
"--filesystem-scheme",
|
||||
_multi_root_scheme,
|
||||
"--filesystem-root",
|
||||
rebase_path("//"),
|
||||
"--packages",
|
||||
"$_multi_root_scheme:///$_rebased_packages_path",
|
||||
|
||||
# Repeating "--depfile" because the previous one is for
|
||||
# `depfile_path_to_relative.py`, and this one is for `_gen_kernel_path`.
|
||||
"--depfile",
|
||||
rebase_path(depfile, root_build_dir),
|
||||
"--output",
|
||||
rebase_path(_kernel_path, root_build_dir),
|
||||
]
|
||||
|
||||
if (_generate_manifest) {
|
||||
args += [
|
||||
"--split-output-by-packages",
|
||||
"--manifest",
|
||||
rebase_path(_kernel_manifest, root_build_dir),
|
||||
]
|
||||
}
|
||||
|
||||
if (is_debug) {
|
||||
args += [ "--embed-sources" ]
|
||||
} else {
|
||||
args += [ "--no-embed-sources" ]
|
||||
}
|
||||
|
||||
if (invoker.is_aot) {
|
||||
args += [
|
||||
"--aot",
|
||||
"--tfa",
|
||||
]
|
||||
} else if (!defined(invoker.link_platform) || !invoker.link_platform) {
|
||||
args += [ "--no-link-platform" ]
|
||||
}
|
||||
|
||||
if (invoker.product) {
|
||||
# Setting this flag in a non-product release build for AOT (a "profile"
|
||||
# build) causes the vm service isolate code to be tree-shaken from an app.
|
||||
# See the pragma on the entrypoint here:
|
||||
#
|
||||
# This define excludes debugging and profiling code from Flutter.
|
||||
args += [ "-Ddart.vm.product=true" ]
|
||||
} else {
|
||||
if (!is_debug) {
|
||||
# The following define excludes debugging code from Flutter.
|
||||
args += [ "-Ddart.vm.profile=true" ]
|
||||
}
|
||||
}
|
||||
|
||||
if (defined(invoker.main_dart)) {
|
||||
args += [ "package:${invoker.main_package}/${invoker.main_dart}" ]
|
||||
} else {
|
||||
rebased_main_dart = rebase_path(invoker.main_dart_file, "//")
|
||||
args += [ "$_multi_root_scheme:///$rebased_main_dart" ]
|
||||
}
|
||||
|
||||
deps = _kernel_deps
|
||||
}
|
||||
|
||||
group(target_name) {
|
||||
forward_variables_from(invoker,
|
||||
[
|
||||
"testonly",
|
||||
"visibility",
|
||||
])
|
||||
deps = _group_deps
|
||||
}
|
||||
}
|
||||
51
engine/src/flutter/tools/fuchsia/dart/merge_deps_sources.py
Executable file
51
engine/src/flutter/tools/fuchsia/dart/merge_deps_sources.py
Executable file
@@ -0,0 +1,51 @@
|
||||
#!/usr/bin/env python3.8
|
||||
"""Merges sources of a Dart target and its dependencies"""
|
||||
|
||||
# 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 argparse
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
'Merges sources of a Dart target and its dependencies',
|
||||
fromfile_prefix_chars='@')
|
||||
parser.add_argument(
|
||||
'--output',
|
||||
help='Path to output the final list',
|
||||
type=argparse.FileType('w'),
|
||||
required=True)
|
||||
parser.add_argument(
|
||||
'--depfile',
|
||||
help='Path to the depfile to generate',
|
||||
type=argparse.FileType('w'),
|
||||
required=True)
|
||||
parser.add_argument(
|
||||
'--sources',
|
||||
help='Sources of this target',
|
||||
nargs='*',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--source_lists',
|
||||
help='Files containing lists of Dart sources',
|
||||
nargs='*')
|
||||
args = parser.parse_args()
|
||||
|
||||
args.depfile.write(
|
||||
'{}: {}\n'.format(args.output.name, ' '.join(args.source_lists)))
|
||||
|
||||
# Merges sources of this target, and all of its dependencies.
|
||||
all_sources = set(args.sources)
|
||||
for f in args.source_lists:
|
||||
with open(f, 'r') as f:
|
||||
all_sources.update(json.load(f))
|
||||
json.dump(sorted(all_sources), args.output)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
10
engine/src/flutter/tools/fuchsia/dart/toolchain.gni
Normal file
10
engine/src/flutter/tools/fuchsia/dart/toolchain.gni
Normal file
@@ -0,0 +1,10 @@
|
||||
# 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.
|
||||
|
||||
dart_toolchain = "//flutter/tools/fuchsia/dart:dartlang"
|
||||
|
||||
dart_root_gen_dir = get_label_info("//bogus($dart_toolchain)", "root_gen_dir")
|
||||
# In order to access the target_gen_dir in the Dart toolchain from some location
|
||||
# in the source tree, use the following:
|
||||
# dart_target_gen_dir = get_label_info(":bogus($dart_toolchain)", "target_gen_dir")
|
||||
72
engine/src/flutter/tools/fuchsia/dart/verify_sources.py
Executable file
72
engine/src/flutter/tools/fuchsia/dart/verify_sources.py
Executable file
@@ -0,0 +1,72 @@
|
||||
#!/usr/bin/env python3.8
|
||||
|
||||
# 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 argparse
|
||||
import os
|
||||
import sys
|
||||
import pathlib
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
"Verifies that all .dart files are included in sources, and sources don't include nonexsitent files"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--source_dir",
|
||||
help="Path to the directory containing the package sources",
|
||||
required=True)
|
||||
parser.add_argument(
|
||||
"--stamp",
|
||||
help="File to touch when source checking succeeds",
|
||||
required=True)
|
||||
parser.add_argument(
|
||||
"sources", help="source files", nargs=argparse.REMAINDER)
|
||||
args = parser.parse_args()
|
||||
|
||||
actual_sources = set()
|
||||
# Get all dart sources from source directory.
|
||||
src_dir_path = pathlib.Path(args.source_dir)
|
||||
for (dirpath, dirnames, filenames) in os.walk(src_dir_path, topdown=True):
|
||||
relpath_to_src_root = pathlib.Path(dirpath).relative_to(src_dir_path)
|
||||
actual_sources.update(
|
||||
os.path.normpath(relpath_to_src_root.joinpath(filename))
|
||||
for filename in filenames
|
||||
if pathlib.Path(filename).suffix == ".dart")
|
||||
|
||||
expected_sources = set(args.sources)
|
||||
# It is possible for sources to include dart files outside of source_dir.
|
||||
actual_sources.update(
|
||||
[
|
||||
s for s in (expected_sources - actual_sources)
|
||||
if src_dir_path.joinpath(s).resolve().exists()
|
||||
],
|
||||
)
|
||||
|
||||
if actual_sources == expected_sources:
|
||||
with open(args.stamp, "w") as stamp:
|
||||
stamp.write("Success!")
|
||||
return 0
|
||||
|
||||
def sources_to_abs_path(sources):
|
||||
return sorted(str(src_dir_path.joinpath(s)) for s in sources)
|
||||
|
||||
missing_sources = actual_sources - expected_sources
|
||||
if missing_sources:
|
||||
print(
|
||||
'\nSource files found that were missing from the "sources" parameter:\n{}\n'
|
||||
.format("\n".join(sources_to_abs_path(missing_sources))),
|
||||
)
|
||||
nonexistent_sources = expected_sources - actual_sources
|
||||
if nonexistent_sources:
|
||||
print(
|
||||
'\nSource files listed in "sources" parameter but not found:\n{}\n'.
|
||||
format("\n".join(sources_to_abs_path(nonexistent_sources))),
|
||||
)
|
||||
return 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
36
engine/src/flutter/tools/fuchsia/depfile_path_to_relative.py
Executable file
36
engine/src/flutter/tools/fuchsia/depfile_path_to_relative.py
Executable file
@@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env python3.8
|
||||
# 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 argparse
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description=
|
||||
'Executes a command, then rewrites the depfile, converts all absolute paths to relative'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--depfile', help='Path to the depfile to rewrite', required=True)
|
||||
parser.add_argument(
|
||||
'command', nargs='+', help='Positional args for the command to run')
|
||||
args = parser.parse_args()
|
||||
|
||||
retval = subprocess.call(args.command)
|
||||
if retval != 0:
|
||||
return retval
|
||||
|
||||
lines = []
|
||||
with open(args.depfile, 'r') as f:
|
||||
for line in f:
|
||||
lines.append(' '.join(os.path.relpath(p) for p in line.split()))
|
||||
with open(args.depfile, 'w') as f:
|
||||
f.write('\n'.join(lines))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
330
engine/src/flutter/tools/fuchsia/dist/resource.gni
vendored
Normal file
330
engine/src/flutter/tools/fuchsia/dist/resource.gni
vendored
Normal file
@@ -0,0 +1,330 @@
|
||||
# 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.
|
||||
|
||||
# Declare data files to be accessible at runtime on the target device.
|
||||
#
|
||||
# A resource() target looks just like a copy() target but $outputs are
|
||||
# relative target paths. Using $data_deps to this resource() target in
|
||||
# each target whose code uses $outputs at runtime ensures that the files
|
||||
# will be present on the system.
|
||||
#
|
||||
# If the file is not in the source tree, it should be generated by another
|
||||
# target in the build listed in $deps. If that would be a generated_file()
|
||||
# target, then use generated_resource() instead of resource().
|
||||
#
|
||||
# Parameters
|
||||
#
|
||||
# data_deps
|
||||
# Optional: Additional dependencies for the runtime image. These are
|
||||
# included in the image if this target is, but are not related to the
|
||||
# $sources list.
|
||||
# Type: list(label)
|
||||
#
|
||||
# deps
|
||||
# Optional: Targets that produce $sources. Any files listed in
|
||||
# $sources that are produced by the build should be produced by a
|
||||
# target listed here. This is the only thing that guarantees those
|
||||
# files will have been built by the time the image is being packed.
|
||||
# Targets reached only via this $deps list will *not* contribute their
|
||||
# own contents to the image directly. For that, list them in $data_deps.
|
||||
# Targets listed here are used only to produce the $sources files.
|
||||
# Type: list(label)
|
||||
#
|
||||
# outputs
|
||||
# Required: List of one runtime path. This must be a relative path (no
|
||||
# leading `/`). It can use placeholders based on $sources; see copy()
|
||||
# and `gn help source_expansion`. When this resource() target is in
|
||||
# the dependency graph of a zbi() target, then this is the path within
|
||||
# the BOOTFS, which appears at /boot in the namespace of early-boot and
|
||||
# standalone Zircon processes.
|
||||
# Type: list(path)
|
||||
#
|
||||
# sources
|
||||
# Required: List of files in the source tree or build that become $outputs.
|
||||
# See copy() for details.
|
||||
# Type: list(file)
|
||||
#
|
||||
# See copy() for other parameters.
|
||||
template("resource") {
|
||||
if (invoker.sources != []) {
|
||||
_label = get_label_info(":$target_name", "label_with_toolchain")
|
||||
}
|
||||
|
||||
group(target_name) {
|
||||
forward_variables_from(invoker,
|
||||
"*",
|
||||
[
|
||||
"metadata",
|
||||
"outputs",
|
||||
"sources",
|
||||
])
|
||||
metadata = {
|
||||
# Used by the distribution_manifest() template.
|
||||
distribution_entries_barrier = []
|
||||
distribution_entries = []
|
||||
|
||||
# Used by the zbi() template.
|
||||
zbi_input_barrier = []
|
||||
|
||||
if (defined(invoker.metadata)) {
|
||||
forward_variables_from(invoker.metadata, "*")
|
||||
}
|
||||
|
||||
# Stop *_manifest() and zbi_test() from picking up files or
|
||||
# zbi_input() items from the deps, but let them reach the data_deps.
|
||||
if (defined(data_deps)) {
|
||||
distribution_entries_barrier += data_deps
|
||||
zbi_input_barrier += data_deps
|
||||
}
|
||||
|
||||
foreach(source, invoker.sources) {
|
||||
foreach(target, process_file_template([ source ], invoker.outputs)) {
|
||||
assert(rebase_path(target, "foo") != target,
|
||||
"`outputs` in resource() cannot start with /")
|
||||
distribution_entries += [
|
||||
{
|
||||
source = rebase_path(source, root_build_dir)
|
||||
destination = target
|
||||
label = _label
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Declare data files to be accessible at runtime on the target device.
|
||||
#
|
||||
# Similar to resource() but with a different interface that allows grouping
|
||||
# multiple files into a single target when their packaged paths don't follow
|
||||
# a common pattern.
|
||||
#
|
||||
# Parameters
|
||||
#
|
||||
# data_deps
|
||||
# Optional: Additional dependencies for the runtime image. These are
|
||||
# included in the image if this target is, but are not related to the
|
||||
# $sources list.
|
||||
# Type: list(label)
|
||||
#
|
||||
# deps
|
||||
# Optional: Targets that produce $sources. Any files listed in
|
||||
# $sources that are produced by the build should be produced by a
|
||||
# target listed here. This is the only thing that guarantees those
|
||||
# files will have been built by the time the image is being packed.
|
||||
# Targets reached only via this $deps list will *not* contribute their
|
||||
# own contents to the image directly. For that, list them in $data_deps.
|
||||
# Targets listed here are used only to produce the $sources files.
|
||||
# Type: list(label)
|
||||
#
|
||||
# files
|
||||
# Required: List of scopes containing `source` and `dest` paths.
|
||||
# `source` paths are local file paths.
|
||||
# `dest` paths are packaged paths.
|
||||
# For instance:
|
||||
# files = [
|
||||
# {
|
||||
# source = "//path/to/file.txt"
|
||||
# dest = "data/first.txt"
|
||||
# },
|
||||
# {
|
||||
# source = "//path/to/other_file.txt",
|
||||
# dest = "data/second.txt"
|
||||
# },
|
||||
# ]
|
||||
# Type: list(scope)
|
||||
#
|
||||
# testonly, visibility
|
||||
template("resource_group") {
|
||||
if (invoker.files != []) {
|
||||
_label = get_label_info(":$target_name", "label_with_toolchain")
|
||||
}
|
||||
|
||||
group(target_name) {
|
||||
forward_variables_from(invoker,
|
||||
[
|
||||
"deps",
|
||||
"testonly",
|
||||
"visibility",
|
||||
])
|
||||
metadata = {
|
||||
# Used by the distribution_manifest() template.
|
||||
distribution_entries_barrier = []
|
||||
distribution_entries = []
|
||||
|
||||
# Used by the zbi() template.
|
||||
zbi_input_barrier = []
|
||||
|
||||
if (defined(invoker.metadata)) {
|
||||
forward_variables_from(invoker.metadata, "*")
|
||||
}
|
||||
|
||||
# Stop *_manifest() and zbi_test() from picking up files or
|
||||
# zbi_input() items from the deps, but let them reach the data_deps.
|
||||
if (defined(data_deps)) {
|
||||
distribution_entries_barrier += data_deps
|
||||
zbi_input_barrier += data_deps
|
||||
}
|
||||
|
||||
foreach(file, invoker.files) {
|
||||
distribution_entries += [
|
||||
{
|
||||
source = rebase_path(file.source, root_build_dir)
|
||||
destination = file.dest
|
||||
label = _label
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# resource_tree() is similar to resource() but makes it easy to replicate
|
||||
# a tree of sources files, relative to a given sources path prefix, to a
|
||||
# given destination directory.
|
||||
#
|
||||
# For example:
|
||||
#
|
||||
# //some/dir/BUILD.gn:
|
||||
# resource_trees("my-resources") {
|
||||
# sources_root = "res"
|
||||
# sources = [
|
||||
# foo.resource",
|
||||
# bar/bar-1.resource",
|
||||
# ]
|
||||
# dest_dir = "data/resources"
|
||||
# }
|
||||
#
|
||||
# Will declare the following installation requirements:
|
||||
#
|
||||
# //some/dir/res/foo.resource --> data/resources/foo.resource
|
||||
# //some/dir/res/bar/bar.resource --> data/resources/bar/bar.resource
|
||||
#
|
||||
# This is difficult to do with resource() because GN source expansion
|
||||
# cannot preserve the original sources input paths.
|
||||
#
|
||||
# This template is useful to avoid calling resource() multiple times
|
||||
# in a loop when dealing with resource files laid out into different
|
||||
# sub-directories. Note that the files cannot be renamed though!
|
||||
#
|
||||
# Parameters
|
||||
#
|
||||
# source_root
|
||||
# Optional: A path prefix that is prepended to all items in the 'sources'
|
||||
# list. If not specified, the current target's directory is used.
|
||||
# Type: string(path)
|
||||
#
|
||||
# sources
|
||||
# Required: List of files in the source tree or build that will be
|
||||
# installed. Each 'file' item in this list is installed to
|
||||
# '$dest_dir/$file', and its content taken from '$sources_root/$file'.
|
||||
# Note that unlike resource(), there is no way to transform or expand
|
||||
# source paths.
|
||||
# Type: list(file)
|
||||
#
|
||||
# dest_dir
|
||||
# Required: Destination path where all sources are installed.
|
||||
# Cannot start with a "/". Use an empty string to install files directory
|
||||
# to the package's top-level directory.
|
||||
# Type: string(path)
|
||||
#
|
||||
# data_deps
|
||||
# Optional: Additional dependencies for the runtime image. These are
|
||||
# included in the image if this target is, but are not related to the
|
||||
# $sources list.
|
||||
# Type: list(label)
|
||||
#
|
||||
# deps
|
||||
# Optional: Targets that produce $sources. Any files listed in
|
||||
# $sources that are produced by the build should be produced by a
|
||||
# target listed here. This is the only thing that guarantees those
|
||||
# files will have been built by the time the image is being packed.
|
||||
# Targets reached only via this $deps list will *not* contribute their
|
||||
# own contents to the image directly. For that, list them in $data_deps.
|
||||
# Targets listed here are used only to produce the $sources files.
|
||||
# Type: list(label)
|
||||
#
|
||||
template("resource_tree") {
|
||||
assert(defined(invoker.sources), "sources is required!")
|
||||
assert(defined(invoker.dest_dir), "dest_dir is required!")
|
||||
dest_dir = invoker.dest_dir
|
||||
if (dest_dir != "") {
|
||||
# Sanitize dest_dir and append a directory separator.
|
||||
assert(rebase_path(dest_dir, "foo") != dest_dir,
|
||||
"dest_dir cannot start with /: $dest_dir")
|
||||
assert(dest_dir != "." && dest_dir != ".." &&
|
||||
string_replace(dest_dir, "./", "") == dest_dir,
|
||||
"dest_dir cannot contain . or .. path elements!: $dest_dir")
|
||||
dest_dir = string_replace(dest_dir + "/", "//", "/")
|
||||
}
|
||||
|
||||
if (defined(invoker.sources_root)) {
|
||||
assert(invoker.sources_root != "", "sources_root cannot be empty!")
|
||||
sources_prefix = invoker.sources_root
|
||||
|
||||
# Append trailing separator if needed
|
||||
if (string_replace(sources_prefix + "###", "/###", "") ==
|
||||
sources_prefix + "###") {
|
||||
sources_prefix += "/"
|
||||
}
|
||||
} else {
|
||||
sources_prefix = ""
|
||||
}
|
||||
|
||||
target_label = get_label_info(":$target_name", "label_with_toolchain")
|
||||
if (invoker.sources == []) {
|
||||
# Support resource_tree() targets with empty sources list.
|
||||
not_needed(invoker,
|
||||
[
|
||||
"dest_dir",
|
||||
"sources_root",
|
||||
])
|
||||
not_needed([
|
||||
"sources_prefix",
|
||||
"dest_dir",
|
||||
"target_label",
|
||||
])
|
||||
}
|
||||
|
||||
group(target_name) {
|
||||
forward_variables_from(invoker,
|
||||
"*",
|
||||
[
|
||||
"dest_dir",
|
||||
"metadata",
|
||||
"sources",
|
||||
"sources_root",
|
||||
])
|
||||
metadata = {
|
||||
# Used by the distribution_manifest() template.
|
||||
distribution_entries_barrier = []
|
||||
distribution_entries = []
|
||||
|
||||
# Used by the zbi() template.
|
||||
zbi_input_barrier = []
|
||||
|
||||
if (defined(invoker.metadata)) {
|
||||
forward_variables_from(invoker.metadata, "*")
|
||||
}
|
||||
|
||||
# Stop *_manifest() and zbi_test() from picking up files or
|
||||
# zbi_input() items from the deps, but let them reach the data_deps.
|
||||
if (defined(data_deps)) {
|
||||
distribution_entries_barrier += data_deps
|
||||
zbi_input_barrier += data_deps
|
||||
}
|
||||
|
||||
foreach(_source, invoker.sources) {
|
||||
distribution_entries += [
|
||||
{
|
||||
source = rebase_path(sources_prefix + _source, root_build_dir)
|
||||
destination = dest_dir + _source
|
||||
label = target_label
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
24
engine/src/flutter/tools/fuchsia/fidl/BUILD.gn
Normal file
24
engine/src/flutter/tools/fuchsia/fidl/BUILD.gn
Normal file
@@ -0,0 +1,24 @@
|
||||
# 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/fuchsia/sdk.gni")
|
||||
import("//flutter/tools/fuchsia/fidl/fidl.gni")
|
||||
import("//flutter/tools/fuchsia/fidl/toolchain.gni")
|
||||
import("//flutter/tools/fuchsia/sdk/sdk_targets.gni")
|
||||
import("//flutter/tools/fuchsia/toolchain/basic_toolchain.gni")
|
||||
|
||||
# A toolchain dedicated to processing FIDL libraries.
|
||||
# The only targets in this toolchain are action() targets, so it
|
||||
# has no real tools. But every toolchain needs stamp and copy.
|
||||
if (current_toolchain == default_toolchain) {
|
||||
basic_toolchain("fidling") {
|
||||
expected_label = fidl_toolchain
|
||||
}
|
||||
}
|
||||
|
||||
if (current_toolchain != default_toolchain) {
|
||||
sdk_targets("fidl_library") {
|
||||
meta = "$fuchsia_sdk_path/meta/manifest.json"
|
||||
}
|
||||
}
|
||||
46
engine/src/flutter/tools/fuchsia/fidl/fidl.gni
Normal file
46
engine/src/flutter/tools/fuchsia/fidl/fidl.gni
Normal file
@@ -0,0 +1,46 @@
|
||||
# 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/fuchsia/sdk.gni")
|
||||
import("//flutter/tools/fuchsia/dart/toolchain.gni")
|
||||
import("//flutter/tools/fuchsia/fidl/toolchain.gni")
|
||||
|
||||
# Declares a FIDL library.
|
||||
#
|
||||
# Depending on the toolchain in which this targets is expanded, it will yield
|
||||
# different results:
|
||||
# - in the FIDL toolchain, it will compile its source files into an
|
||||
# intermediate representation consumable by language bindings generators;
|
||||
# - in the target or shared toolchain, this will produce a source_set
|
||||
# containing language-specific bindings.
|
||||
template("fidl") {
|
||||
# Allow generated targets visibility to their dependant generated targets
|
||||
if (defined(invoker.visibility)) {
|
||||
invoker.visibility += [ ":*" ]
|
||||
}
|
||||
|
||||
assert(!defined(invoker.deps),
|
||||
"All FIDL dependencies are inherently " +
|
||||
"public, use 'public_deps' instead of 'deps'.")
|
||||
|
||||
deps = []
|
||||
|
||||
if (current_toolchain == dart_toolchain) {
|
||||
import("//flutter/tools/fuchsia/dart/fidl_dart.gni")
|
||||
|
||||
fidl_dart(target_name) {
|
||||
forward_variables_from(invoker, "*")
|
||||
}
|
||||
} else {
|
||||
if (current_toolchain == fidl_toolchain) {
|
||||
import("//flutter/tools/fuchsia/fidl/fidl_library.gni")
|
||||
|
||||
fidl_library(target_name) {
|
||||
forward_variables_from(invoker, "*")
|
||||
}
|
||||
} else {
|
||||
not_needed("*")
|
||||
}
|
||||
}
|
||||
}
|
||||
143
engine/src/flutter/tools/fuchsia/fidl/fidl_library.gni
Normal file
143
engine/src/flutter/tools/fuchsia/fidl/fidl_library.gni
Normal file
@@ -0,0 +1,143 @@
|
||||
# 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/fidl/fidl.gni")
|
||||
import("//flutter/tools/fuchsia/fidl/toolchain.gni")
|
||||
|
||||
# Generates some representation of a FIDL library that's consumable by Language
|
||||
# bindings generators.
|
||||
#
|
||||
# The parameters for this template are defined in //flutter/tools/fuchsia/fidl/fidl.gni. The
|
||||
# relevant parameters in this template are:
|
||||
# - name;
|
||||
# - sources.
|
||||
|
||||
template("fidl_library") {
|
||||
assert(
|
||||
current_toolchain == fidl_toolchain,
|
||||
"This template can only be used in the FIDL toolchain $fidl_toolchain.")
|
||||
|
||||
assert(defined(invoker.sources), "A FIDL library requires some sources.")
|
||||
|
||||
library_name = target_name
|
||||
if (defined(invoker.name)) {
|
||||
library_name = invoker.name
|
||||
}
|
||||
|
||||
response_file = "$target_gen_dir/$target_name.args"
|
||||
fidl_stem = "$target_gen_dir/$target_name.fidl"
|
||||
json_representation = "$fidl_stem.json"
|
||||
|
||||
coding_tables = "$fidl_stem.tables.c"
|
||||
|
||||
main_target_name = target_name
|
||||
response_file_target_name = "${target_name}_response_file"
|
||||
compilation_target_name = "${target_name}_compile"
|
||||
|
||||
# Only artifacts that have various associated FIDL generated targets.
|
||||
fidl_deps = []
|
||||
|
||||
# Artifacts other than FIDL, that are also dependencies.
|
||||
non_fidl_deps = []
|
||||
|
||||
if (defined(invoker.non_fidl_deps)) {
|
||||
non_fidl_deps += invoker.non_fidl_deps
|
||||
}
|
||||
|
||||
if (defined(invoker.deps)) {
|
||||
fidl_deps += invoker.deps - non_fidl_deps
|
||||
}
|
||||
if (defined(invoker.public_deps)) {
|
||||
fidl_deps += invoker.public_deps
|
||||
}
|
||||
|
||||
action(response_file_target_name) {
|
||||
visibility = [ ":*" ]
|
||||
|
||||
script = "//flutter/tools/fuchsia/fidl/gen_response_file.py"
|
||||
|
||||
forward_variables_from(invoker,
|
||||
[
|
||||
"deps",
|
||||
"public_deps",
|
||||
"sources",
|
||||
"testonly",
|
||||
])
|
||||
|
||||
libraries = "$target_gen_dir/$main_target_name.libraries"
|
||||
|
||||
outputs = [
|
||||
response_file,
|
||||
libraries,
|
||||
]
|
||||
|
||||
args = [
|
||||
"--out-response-file",
|
||||
rebase_path(response_file, root_build_dir),
|
||||
"--out-libraries",
|
||||
rebase_path(libraries, root_build_dir),
|
||||
"--json",
|
||||
rebase_path(json_representation, root_build_dir),
|
||||
"--tables",
|
||||
rebase_path(coding_tables, root_build_dir),
|
||||
"--name",
|
||||
library_name,
|
||||
"--sources",
|
||||
] + rebase_path(sources, root_build_dir)
|
||||
|
||||
if (fidl_deps != []) {
|
||||
dep_libraries = []
|
||||
|
||||
foreach(dep, fidl_deps) {
|
||||
gen_dir = get_label_info(dep, "target_gen_dir")
|
||||
name = get_label_info(dep, "name")
|
||||
dep_libraries += [ "$gen_dir/$name.libraries" ]
|
||||
}
|
||||
|
||||
inputs = dep_libraries
|
||||
|
||||
args += [ "--dep-libraries" ] + rebase_path(dep_libraries, root_build_dir)
|
||||
}
|
||||
}
|
||||
|
||||
executable_action(compilation_target_name) {
|
||||
forward_variables_from(invoker, [ "testonly" ])
|
||||
|
||||
visibility = [ ":*" ]
|
||||
|
||||
tool = "${fuchsia_sdk_path}/tools/fidlc"
|
||||
|
||||
inputs = [ response_file ]
|
||||
|
||||
outputs = [
|
||||
coding_tables,
|
||||
json_representation,
|
||||
]
|
||||
|
||||
args = [ "@" + rebase_path(response_file, root_build_dir) ]
|
||||
|
||||
deps = [ ":$response_file_target_name" ] + non_fidl_deps
|
||||
}
|
||||
|
||||
group(main_target_name) {
|
||||
forward_variables_from(invoker,
|
||||
[
|
||||
"testonly",
|
||||
"visibility",
|
||||
"response_file",
|
||||
])
|
||||
|
||||
# Metadata to allow us to query all FIDL IR files.
|
||||
metadata = {
|
||||
fidl_json = [ rebase_path(json_representation, root_build_dir) ]
|
||||
generated_sources = fidl_json
|
||||
}
|
||||
|
||||
public_deps = [
|
||||
":$compilation_target_name",
|
||||
":$response_file_target_name",
|
||||
]
|
||||
}
|
||||
}
|
||||
122
engine/src/flutter/tools/fuchsia/fidl/gen_response_file.py
Executable file
122
engine/src/flutter/tools/fuchsia/fidl/gen_response_file.py
Executable file
@@ -0,0 +1,122 @@
|
||||
#!/usr/bin/env python3.8
|
||||
# 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 argparse
|
||||
import os
|
||||
import string
|
||||
import sys
|
||||
|
||||
|
||||
def read_libraries(libraries_path):
|
||||
with open(libraries_path) as f:
|
||||
lines = f.readlines()
|
||||
return [l.rstrip("\n") for l in lines]
|
||||
|
||||
|
||||
def write_libraries(libraries_path, libraries):
|
||||
directory = os.path.dirname(libraries_path)
|
||||
if not os.path.exists(directory):
|
||||
os.makedirs(directory)
|
||||
with open(libraries_path, "w+") as f:
|
||||
for library in libraries:
|
||||
f.write(library)
|
||||
f.write("\n")
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Generate response file for FIDL frontend")
|
||||
parser.add_argument(
|
||||
"--out-response-file",
|
||||
help="The path for for the response file to generate",
|
||||
required=True)
|
||||
parser.add_argument(
|
||||
"--out-libraries",
|
||||
help="The path for for the libraries file to generate",
|
||||
required=True)
|
||||
parser.add_argument(
|
||||
"--json", help="The path for the JSON file to generate, if any")
|
||||
parser.add_argument(
|
||||
"--tables", help="The path for the tables file to generate, if any")
|
||||
parser.add_argument(
|
||||
"--deprecated-fuchsia-only-c-client",
|
||||
help="The path for the C simple client file to generate, if any")
|
||||
parser.add_argument(
|
||||
"--deprecated-fuchsia-only-c-header",
|
||||
help="The path for the C header file to generate, if any")
|
||||
parser.add_argument(
|
||||
"--deprecated-fuchsia-only-c-server",
|
||||
help="The path for the C simple server file to generate, if any")
|
||||
parser.add_argument(
|
||||
"--name", help="The name for the generated FIDL library, if any")
|
||||
parser.add_argument(
|
||||
"--depfile", help="The name for the generated depfile, if any")
|
||||
parser.add_argument(
|
||||
"--sources", help="List of FIDL source files", nargs="*")
|
||||
parser.add_argument(
|
||||
"--dep-libraries", help="List of dependent libraries", nargs="*")
|
||||
parser.add_argument(
|
||||
"--experimental-flag",
|
||||
help="List of experimental flags",
|
||||
action="append")
|
||||
args = parser.parse_args()
|
||||
|
||||
target_libraries = []
|
||||
|
||||
for dep_libraries_path in args.dep_libraries or []:
|
||||
dep_libraries = read_libraries(dep_libraries_path)
|
||||
for library in dep_libraries:
|
||||
if library in target_libraries:
|
||||
continue
|
||||
target_libraries.append(library)
|
||||
|
||||
target_libraries.append(" ".join(sorted(args.sources)))
|
||||
write_libraries(args.out_libraries, target_libraries)
|
||||
|
||||
response_file = []
|
||||
|
||||
response_file.append('--experimental allow_new_syntax')
|
||||
|
||||
if args.json:
|
||||
response_file.append("--json %s" % args.json)
|
||||
|
||||
if args.tables:
|
||||
response_file.append("--tables %s" % args.tables)
|
||||
|
||||
if args.deprecated_fuchsia_only_c_client:
|
||||
response_file.append(
|
||||
"--deprecated-fuchsia-only-c-client %s" %
|
||||
args.deprecated_fuchsia_only_c_client)
|
||||
|
||||
if args.deprecated_fuchsia_only_c_header:
|
||||
response_file.append(
|
||||
"--deprecated-fuchsia-only-c-header %s" %
|
||||
args.deprecated_fuchsia_only_c_header)
|
||||
|
||||
if args.deprecated_fuchsia_only_c_server:
|
||||
response_file.append(
|
||||
"--deprecated-fuchsia-only-c-server %s" %
|
||||
args.deprecated_fuchsia_only_c_server)
|
||||
|
||||
if args.name:
|
||||
response_file.append("--name %s" % args.name)
|
||||
|
||||
if args.depfile:
|
||||
response_file.append("--depfile %s" % args.depfile)
|
||||
|
||||
if args.experimental_flag:
|
||||
for experimental_flag in args.experimental_flag:
|
||||
response_file.append("--experimental %s" % experimental_flag)
|
||||
|
||||
response_file.extend(
|
||||
["--files %s" % library for library in target_libraries])
|
||||
|
||||
with open(args.out_response_file, "w+") as f:
|
||||
f.write(" ".join(response_file))
|
||||
f.write("\n")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
5
engine/src/flutter/tools/fuchsia/fidl/toolchain.gni
Normal file
5
engine/src/flutter/tools/fuchsia/fidl/toolchain.gni
Normal file
@@ -0,0 +1,5 @@
|
||||
# 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.
|
||||
|
||||
fidl_toolchain = "//flutter/tools/fuchsia/fidl:fidling"
|
||||
24
engine/src/flutter/tools/fuchsia/flutter/config.gni
Normal file
24
engine/src/flutter/tools/fuchsia/flutter/config.gni
Normal file
@@ -0,0 +1,24 @@
|
||||
# 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/fuchsia/flutter/flutter_build_config.gni")
|
||||
|
||||
declare_args() {
|
||||
# If set to true, will force the runners to be built in
|
||||
# product mode which means they will not have an exposed vm service
|
||||
flutter_force_product = false
|
||||
}
|
||||
|
||||
declare_args() {
|
||||
if (flutter_force_product) {
|
||||
# Product AOT
|
||||
flutter_default_build_cfg = flutter_release_build_cfg
|
||||
} else if (is_debug) {
|
||||
# Non-product JIT
|
||||
flutter_default_build_cfg = flutter_debug_build_cfg
|
||||
} else {
|
||||
# Non-product AOT
|
||||
flutter_default_build_cfg = flutter_profile_build_cfg
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
# 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.
|
||||
|
||||
# Non-product JIT is "debug". It launches the vm service.
|
||||
# Non-product AOT is "profile". It also launches the vm service, but lacks tools that rely on JIT.
|
||||
# Product AOT is "release". It doesn't launch the vm service.
|
||||
|
||||
# Builds the component in a non-product JIT build. This will
|
||||
# launch the vm service in the runner.
|
||||
flutter_debug_build_cfg = {
|
||||
runtime_meta = "//flutter/shell/platform/fuchsia/flutter/meta/jit_runtime"
|
||||
runner_dep = "//flutter/shell/platform/fuchsia/flutter:jit"
|
||||
platform_name = "flutter_runner"
|
||||
is_aot = false
|
||||
is_product = false
|
||||
enable_asserts = true
|
||||
}
|
||||
|
||||
# Builds the component in a non-product AOT build. This will
|
||||
# launch the vm service in the runner.
|
||||
# This configuration is not compatible with a --release build since the
|
||||
# profile aot runner is built without asserts.
|
||||
flutter_aot_debug_build_cfg = {
|
||||
runtime_meta = "//flutter/shell/platform/fuchsia/flutter/meta/aot_runtime"
|
||||
runner_dep = "//flutter/shell/platform/fuchsia/flutter:aot"
|
||||
platform_name = "flutter_runner"
|
||||
is_aot = true
|
||||
is_product = false
|
||||
enable_asserts = true
|
||||
}
|
||||
|
||||
# Builds the component in a non-product AOT build. This will
|
||||
# launch the vm service in the runner.
|
||||
flutter_profile_build_cfg = {
|
||||
runtime_meta =
|
||||
"//flutter/shell/platform/fuchsia/flutter/meta/aot_runtime" # profile
|
||||
# runner
|
||||
runner_dep = "//flutter/shell/platform/fuchsia/flutter:aot"
|
||||
platform_name = "flutter_runner"
|
||||
is_aot = true
|
||||
is_product = false
|
||||
enable_asserts = false
|
||||
}
|
||||
|
||||
# Builds the component in a product AOT build. This will
|
||||
# not launch the vm service in the runner.
|
||||
flutter_release_build_cfg = {
|
||||
runtime_meta =
|
||||
"//flutter/shell/platform/fuchsia/flutter/meta/aot_product_runtime"
|
||||
runner_dep = "//flutter/shell/platform/fuchsia/flutter:aot_product"
|
||||
platform_name = "flutter_runner"
|
||||
is_aot = true
|
||||
is_product = true
|
||||
enable_asserts = false
|
||||
}
|
||||
137
engine/src/flutter/tools/fuchsia/flutter/flutter_component.gni
Normal file
137
engine/src/flutter/tools/fuchsia/flutter/flutter_component.gni
Normal file
@@ -0,0 +1,137 @@
|
||||
# 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/fuchsia/dart/dart.gni")
|
||||
import("//flutter/tools/fuchsia/dart/dart_library.gni")
|
||||
import("//flutter/tools/fuchsia/flutter/config.gni")
|
||||
import("//flutter/tools/fuchsia/flutter/internal/flutter_dart_component.gni")
|
||||
|
||||
# Defines a Flutter component which can be used in a fuchsia package
|
||||
#
|
||||
# Flutter components require at least one library which contains a main
|
||||
# entry point. The library should be defined using the dart_library.gni.
|
||||
#
|
||||
# ```
|
||||
# dart_library("lib") {
|
||||
# package_name = "my_library"
|
||||
# sources = [ "main.dart" ]
|
||||
# deps = [ "//third_party/dart-pkg/git/flutter/packages/flutter" ]
|
||||
# }
|
||||
# ```
|
||||
#
|
||||
# Once a library is defined a flutter component can be created which
|
||||
# depends on this package. If the component needs any other resources they may
|
||||
# be defined using the resource target and added to the components deps.
|
||||
#
|
||||
# ```
|
||||
# resource("text-file") {
|
||||
# sources = [ "text_file.txt" ]
|
||||
# outputs = [ "data/text_file.txt" ]
|
||||
# }
|
||||
#
|
||||
# flutter_component("my-component") {
|
||||
# manifest = "meta/my-component.cmx"
|
||||
# main_package = "my_library"
|
||||
# deps = [
|
||||
# ":lib",
|
||||
# ":text-file",
|
||||
# ]
|
||||
# }
|
||||
# ```
|
||||
#
|
||||
# Once a component is defined it can be added as a dep of a fuchsia_package
|
||||
# ```
|
||||
# fuchsia_package("my-package") {
|
||||
# deps = [
|
||||
# ":my-component",
|
||||
# ]
|
||||
# }
|
||||
# ```
|
||||
#
|
||||
# Parameters
|
||||
#
|
||||
# manifest (required)
|
||||
# The component manifest
|
||||
# Type: path
|
||||
#
|
||||
# main_package (optional)
|
||||
# The name of the package containing main_dart
|
||||
# Type: string
|
||||
# Default: component_name with dashes replaced by underscores, if defined.
|
||||
# Otherwise, the target_name with dashes replaced by underscores will be
|
||||
# used.
|
||||
#
|
||||
# component_name (optional)
|
||||
# The name of the component.
|
||||
# Type: string
|
||||
# Default: target_name
|
||||
#
|
||||
# main_dart (optional)
|
||||
# File containing the main function of the component.
|
||||
# Type: string
|
||||
# Default: main.dart
|
||||
#
|
||||
# package_root (optional)
|
||||
# The root of the package generated for this component. Each component must
|
||||
# have a unique package_root. For each component, there must be a
|
||||
# pubspec.yaml and an analysis_options.yaml at the package root.
|
||||
# Type: path
|
||||
# Default: "."
|
||||
#
|
||||
# build_cfg (optional)
|
||||
# Specifies the parameters for building the component.
|
||||
# See //flutter/tools/fuchsia/flutter/flutter_build_config.gni for predefined configs.
|
||||
#
|
||||
# deps
|
||||
# testonly
|
||||
# visibility
|
||||
template("flutter_component") {
|
||||
assert(defined(invoker.manifest), "Must define manifest")
|
||||
|
||||
_component_deps = []
|
||||
if (defined(invoker.deps)) {
|
||||
_component_deps += invoker.deps
|
||||
}
|
||||
|
||||
if (defined(invoker.build_cfg)) {
|
||||
_build_cfg = invoker.build_cfg
|
||||
} else {
|
||||
_build_cfg = flutter_default_build_cfg
|
||||
}
|
||||
|
||||
if (defined(invoker.main_package)) {
|
||||
_main_package = invoker.main_package
|
||||
} else if (defined(invoker.component_name)) {
|
||||
_main_package = string_replace(invoker.component_name, "-", "_")
|
||||
} else {
|
||||
_main_package = string_replace(target_name, "-", "_")
|
||||
}
|
||||
|
||||
if (defined(invoker.main_dart)) {
|
||||
_main_dart = invoker.main_dart
|
||||
} else {
|
||||
_main_dart = "main.dart"
|
||||
}
|
||||
|
||||
# We need to specify the runner as a dependency to be bundled with the dill
|
||||
# files generated by dart_kernel.
|
||||
_component_deps += [ _build_cfg.runner_dep ]
|
||||
|
||||
flutter_dart_component(target_name) {
|
||||
forward_variables_from(invoker,
|
||||
"*",
|
||||
[
|
||||
"build_cfg",
|
||||
"deps",
|
||||
"main_dart",
|
||||
"main_package",
|
||||
])
|
||||
deps = _component_deps
|
||||
|
||||
main_dart = _main_dart
|
||||
main_package = _main_package
|
||||
|
||||
build_cfg = _build_cfg
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,244 @@
|
||||
# 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/dist/resource.gni")
|
||||
import("//flutter/tools/fuchsia/sdk/cmc.gni")
|
||||
import("//flutter/tools/fuchsia/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
|
||||
}
|
||||
|
||||
# merge the runner cmx into this one which allows us to switch runners based
|
||||
# on compilation modes
|
||||
_merged_target_name = "${target_name}_merged.cmx"
|
||||
|
||||
cmc_merge(_merged_target_name) {
|
||||
forward_variables_from(invoker,
|
||||
[
|
||||
"testonly",
|
||||
"visibility",
|
||||
])
|
||||
sources = [
|
||||
invoker.manifest,
|
||||
rebase_path(build_cfg.runtime_meta, "."),
|
||||
]
|
||||
}
|
||||
|
||||
_merged_outputs = []
|
||||
_merged_outputs += get_target_outputs(":$_merged_target_name")
|
||||
_merged_manifest = _merged_outputs[0]
|
||||
|
||||
_component_deps += [ ":$_merged_target_name" ]
|
||||
|
||||
_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 (is_debug && !dart_force_product)
|
||||
if (build_cfg.enable_asserts) {
|
||||
args += [ "--enable_asserts" ]
|
||||
}
|
||||
args += [ rebase_path(_kernel_path, root_build_dir) ]
|
||||
}
|
||||
|
||||
# copy the snapshot as a resource
|
||||
_snapshot_resource_target_name = "${target_name}_snapshot_resource"
|
||||
resource(_snapshot_resource_target_name) {
|
||||
sources = [ _snapshot_path ]
|
||||
outputs = [ "data/${_component_name}/app_aot_snapshot.so" ]
|
||||
}
|
||||
|
||||
_component_deps += [
|
||||
":$_snapshot_resource_target_name",
|
||||
":$_snapshot_target_name",
|
||||
]
|
||||
}
|
||||
|
||||
fuchsia_component(target_name) {
|
||||
forward_variables_from(invoker,
|
||||
[
|
||||
"testonly",
|
||||
"visibility",
|
||||
"component_name",
|
||||
])
|
||||
deps = _component_deps
|
||||
manifest = _merged_manifest
|
||||
}
|
||||
}
|
||||
0
engine/src/flutter/tools/fuchsia/make_build_info.py
Normal file → Executable file
0
engine/src/flutter/tools/fuchsia/make_build_info.py
Normal file → Executable file
145
engine/src/flutter/tools/fuchsia/python/package_python_binary.py
Executable file
145
engine/src/flutter/tools/fuchsia/python/package_python_binary.py
Executable file
@@ -0,0 +1,145 @@
|
||||
#!/usr/bin/env python3.8
|
||||
"""Creats a Python zip archive for the input main source."""
|
||||
|
||||
# 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 argparse
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import zipapp
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
'Creates a Python zip archive for the input main source')
|
||||
|
||||
parser.add_argument(
|
||||
'--target_name',
|
||||
help='Name of the build target',
|
||||
required=True,
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--main_source',
|
||||
help='Path to the source containing the main function',
|
||||
required=True,
|
||||
)
|
||||
parser.add_argument(
|
||||
'--main_callable',
|
||||
help=
|
||||
'Name of the the main callable, that is the entry point of the generated archive',
|
||||
required=True,
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--gen_dir',
|
||||
help='Path to gen directory, used to stage temporary directories',
|
||||
required=True,
|
||||
)
|
||||
parser.add_argument('--output', help='Path to output', required=True)
|
||||
|
||||
parser.add_argument(
|
||||
'--sources',
|
||||
help='Sources of this target, including main source',
|
||||
nargs='*',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--library_infos',
|
||||
help='Path to the library infos JSON file',
|
||||
type=argparse.FileType('r'),
|
||||
required=True,
|
||||
)
|
||||
parser.add_argument(
|
||||
'--depfile',
|
||||
help='Path to the depfile to generate',
|
||||
type=argparse.FileType('w'),
|
||||
required=True,
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
infos = json.load(args.library_infos)
|
||||
|
||||
# Temporary directory to stage the source tree for this python binary,
|
||||
# including sources of itself and all the libraries it imports.
|
||||
#
|
||||
# It is possible to have multiple python_binaries in the same directory, so
|
||||
# using target name, which should be unique in the same directory, to
|
||||
# distinguish between them.
|
||||
app_dir = os.path.join(args.gen_dir, args.target_name)
|
||||
os.makedirs(app_dir, exist_ok=True)
|
||||
|
||||
# Copy over the sources of this binary.
|
||||
for source in args.sources:
|
||||
basename = os.path.basename(source)
|
||||
if basename == '__main__.py':
|
||||
print(
|
||||
'__main__.py in sources of python_binary is not supported, see https://fxbug.dev/73576',
|
||||
file=sys.stderr,
|
||||
)
|
||||
return 1
|
||||
dest = os.path.join(app_dir, basename)
|
||||
shutil.copy2(source, dest)
|
||||
|
||||
# For writing a depfile.
|
||||
files_to_copy = []
|
||||
# Make sub directories for all libraries and copy over their sources.
|
||||
for info in infos:
|
||||
dest_lib_root = os.path.join(app_dir, info['library_name'])
|
||||
os.makedirs(dest_lib_root, exist_ok=True)
|
||||
|
||||
src_lib_root = info['source_root']
|
||||
# Sources are relative to library root.
|
||||
for source in info['sources']:
|
||||
src = os.path.join(src_lib_root, source)
|
||||
dest = os.path.join(dest_lib_root, source)
|
||||
# Make sub directories if necessary.
|
||||
os.makedirs(os.path.dirname(dest), exist_ok=True)
|
||||
files_to_copy.append(src)
|
||||
shutil.copy2(src, dest)
|
||||
|
||||
args.depfile.write('{}: {}\n'.format(args.output, ' '.join(files_to_copy)))
|
||||
|
||||
# Main module is the main source without its extension.
|
||||
main_module = os.path.splitext(os.path.basename(args.main_source))[0]
|
||||
# Manually create a __main__.py file for the archive, instead of using the
|
||||
# `main` parameter from `create_archive`. This way we can import everything
|
||||
# from the main module (create_archive only `import pkg`), which is
|
||||
# necessary for including all test cases for unit tests.
|
||||
#
|
||||
# TODO(https://fxbug.dev/73576): figure out another way to support unit
|
||||
# tests when users need to provide their own custom __main__.py.
|
||||
main_file = os.path.join(app_dir, "__main__.py")
|
||||
with open(main_file, 'w') as f:
|
||||
f.write(
|
||||
f'''
|
||||
import sys
|
||||
from {main_module} import *
|
||||
|
||||
sys.exit({args.main_callable}())
|
||||
''')
|
||||
|
||||
zipapp.create_archive(
|
||||
app_dir,
|
||||
target=args.output,
|
||||
interpreter='/usr/bin/env python3.8',
|
||||
compressed=True,
|
||||
)
|
||||
|
||||
# Manually remove the temporary app directory and all the files, instead of
|
||||
# using shutil.rmtree. rmtree records reads on directories which throws off
|
||||
# the action tracer.
|
||||
for root, dirs, files in os.walk(app_dir, topdown=False):
|
||||
for file in files:
|
||||
os.remove(os.path.join(root, file))
|
||||
for dir in dirs:
|
||||
os.rmdir(os.path.join(root, dir))
|
||||
os.rmdir(app_dir)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
123
engine/src/flutter/tools/fuchsia/python/python_binary.gni
Normal file
123
engine/src/flutter/tools/fuchsia/python/python_binary.gni
Normal file
@@ -0,0 +1,123 @@
|
||||
# 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/python/python3_action.gni")
|
||||
|
||||
# Defines a Python binary.
|
||||
#
|
||||
# Example
|
||||
#
|
||||
# ```
|
||||
# python_binary("main") {
|
||||
# main_source = "main.py"
|
||||
# main_callable = "main"
|
||||
# sources = [
|
||||
# "foo.py",
|
||||
# "bar.py",
|
||||
# ]
|
||||
# output_name = "main.pyz"
|
||||
# deps = [ "//path/to/lib" ]
|
||||
# }
|
||||
# ```
|
||||
#
|
||||
# Parameters
|
||||
#
|
||||
# main_source (required)
|
||||
# Source file including the entry callable for this binary.
|
||||
# This file will typically contain
|
||||
# ```
|
||||
# if __name__ == "__main__":
|
||||
# main()
|
||||
# ```
|
||||
# Type: path
|
||||
#
|
||||
# main_callable (optional)
|
||||
# Main callable, which serves as the entry point of the output zip archive.
|
||||
# In the example above, this is "main".
|
||||
# Type: string
|
||||
# Default: main
|
||||
#
|
||||
# output_name (optional)
|
||||
# Name of the output Python zip archive, must have .pyz as extension.
|
||||
# Type: string
|
||||
# Default: ${target_name}.pyz
|
||||
#
|
||||
# sources
|
||||
# deps
|
||||
# visibility
|
||||
# testonly
|
||||
template("python_binary") {
|
||||
assert(defined(invoker.main_source), "main_source is required")
|
||||
|
||||
_library_infos_target = "${target_name}_library_infos"
|
||||
_library_infos_json = "${target_gen_dir}/${target_name}_library_infos.json"
|
||||
generated_file(_library_infos_target) {
|
||||
forward_variables_from(invoker,
|
||||
[
|
||||
"testonly",
|
||||
"deps",
|
||||
])
|
||||
visibility = [ ":*" ]
|
||||
|
||||
outputs = [ _library_infos_json ]
|
||||
output_conversion = "json"
|
||||
data_keys = [ "library_info" ]
|
||||
walk_keys = [ "library_info_barrier" ]
|
||||
}
|
||||
|
||||
# action(target_name) {
|
||||
python3_action(target_name) {
|
||||
forward_variables_from(invoker,
|
||||
[
|
||||
"testonly",
|
||||
"visibility",
|
||||
])
|
||||
|
||||
sources = [ invoker.main_source ]
|
||||
if (defined(invoker.sources)) {
|
||||
sources += invoker.sources
|
||||
}
|
||||
inputs = [ _library_infos_json ]
|
||||
deps = [ ":${_library_infos_target}" ]
|
||||
|
||||
# Output must be a .pyz, so our build knows to use a vendored Python
|
||||
# interpreter to run them.
|
||||
#
|
||||
# Output a single .pyz file makes the output deterministic, otherwise we'd
|
||||
# have to list out all the library sources that will be copied to output
|
||||
# directory, which is not possible because they are not known until the
|
||||
# generated JSON file is parsed at build time.
|
||||
_output = "${target_out_dir}/${target_name}.pyz"
|
||||
if (defined(invoker.output_name)) {
|
||||
assert(get_path_info(invoker.output_name, "extension") == "pyz",
|
||||
"output_name must have .pyz as extension")
|
||||
_output = "${target_out_dir}/${invoker.output_name}"
|
||||
}
|
||||
outputs = [ _output ]
|
||||
|
||||
_main_callable = "main"
|
||||
if (defined(invoker.main_callable)) {
|
||||
_main_callable = invoker.main_callable
|
||||
}
|
||||
|
||||
script = "//flutter/tools/fuchsia/python/package_python_binary.py"
|
||||
depfile = "${target_out_dir}/${target_name}.d"
|
||||
args = [ "--sources" ] + rebase_path(sources, root_build_dir) + [
|
||||
"--target_name",
|
||||
target_name,
|
||||
"--main_source",
|
||||
rebase_path(invoker.main_source, root_build_dir),
|
||||
"--main_callable",
|
||||
_main_callable,
|
||||
"--library_infos",
|
||||
rebase_path(_library_infos_json, root_build_dir),
|
||||
"--depfile",
|
||||
rebase_path(depfile, root_build_dir),
|
||||
"--gen_dir",
|
||||
rebase_path(target_gen_dir, root_build_dir),
|
||||
"--output",
|
||||
rebase_path(_output, root_build_dir),
|
||||
]
|
||||
}
|
||||
}
|
||||
243
engine/src/flutter/tools/fuchsia/sdk/cmc.gni
Normal file
243
engine/src/flutter/tools/fuchsia/sdk/cmc.gni
Normal file
@@ -0,0 +1,243 @@
|
||||
# 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("config/config.gni")
|
||||
|
||||
# Internal template for the cmc tool.
|
||||
#
|
||||
# Invokes cmc
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# ```
|
||||
# _cmc_tool("validate_cmx") {
|
||||
# inputs = [ manifest ]
|
||||
# outputs = [ stamp_file ]
|
||||
#
|
||||
# args = [
|
||||
# "--stamp",
|
||||
# rebase_path(stamp_file, root_build_dir),
|
||||
# "validate",
|
||||
# rebase_path(invoker.manifest),
|
||||
# ]
|
||||
# }
|
||||
# ```
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# inputs (required)
|
||||
# List of files that are input for cmc.
|
||||
# Type: list(path)
|
||||
#
|
||||
# outputs (required)
|
||||
# List paths that are output for the run of cmc.
|
||||
# Type: list(path)
|
||||
#
|
||||
# args (required)
|
||||
# List command line args for cmc.
|
||||
# Type: list(path)
|
||||
#
|
||||
# deps
|
||||
# public_deps
|
||||
# testonly
|
||||
# visibility
|
||||
#
|
||||
template("_cmc_tool") {
|
||||
action(target_name) {
|
||||
forward_variables_from(invoker,
|
||||
[
|
||||
"deps",
|
||||
"public_deps",
|
||||
"testonly",
|
||||
"visibility",
|
||||
])
|
||||
script = "//build/gn_run_binary.py"
|
||||
_cmc_tool_path = "${fuchsia_tool_dir}/cmc"
|
||||
|
||||
assert(defined(invoker.inputs), "inputs is a required parameter.")
|
||||
assert(defined(invoker.outputs), "outputs is a required parameter.")
|
||||
assert(defined(invoker.args), "args is a required parameter.")
|
||||
|
||||
inputs =
|
||||
[
|
||||
_cmc_tool_path,
|
||||
|
||||
# Depend on the SDK hash, to ensure rebuild if the SDK tools change.
|
||||
fuchsia_sdk_manifest_file,
|
||||
] + invoker.inputs
|
||||
|
||||
outputs = invoker.outputs
|
||||
|
||||
args = [ rebase_path(_cmc_tool_path, root_build_dir) ] + invoker.args
|
||||
}
|
||||
}
|
||||
|
||||
# Compiles a Components Framework v2 manifest (.cml) file to .cm
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# ```
|
||||
# cmc_compile(_compiled_manifest_target) {
|
||||
# forward_variables_from(invoker, [ "deps" ])
|
||||
# manifest = rebase_path(manifest)
|
||||
# }
|
||||
# ```
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# manifest (required)
|
||||
# The input Component Framework v2 manifest source (.cml) file.
|
||||
# The file must have the extension ".cml".
|
||||
#
|
||||
# output_name (optional)
|
||||
# Name of the output file to generate. Defaults to $target_name.
|
||||
# This should not include a file extension (.cm)
|
||||
#
|
||||
# deps
|
||||
# public_deps
|
||||
# testonly
|
||||
# visibility
|
||||
#
|
||||
template("cmc_compile") {
|
||||
output_name = target_name
|
||||
if (defined(invoker.output_name)) {
|
||||
output_name = invoker.output_name
|
||||
}
|
||||
|
||||
_cmc_tool(target_name) {
|
||||
forward_variables_from(invoker,
|
||||
[
|
||||
"deps",
|
||||
"manifest",
|
||||
"public_deps",
|
||||
"testonly",
|
||||
"visibility",
|
||||
])
|
||||
assert(defined(manifest), "manifest file required")
|
||||
|
||||
inputs = [ manifest ]
|
||||
|
||||
output_file = "$target_out_dir/$output_name.cm"
|
||||
outputs = [ output_file ]
|
||||
|
||||
depfile = "$target_out_dir/$target_name.d"
|
||||
|
||||
args = [
|
||||
"compile",
|
||||
rebase_path(manifest, root_build_dir),
|
||||
"--output",
|
||||
rebase_path(output_file, root_build_dir),
|
||||
"--includeroot",
|
||||
rebase_path("//", root_build_dir),
|
||||
"--includepath",
|
||||
rebase_path("$fuchsia_sdk/pkg/", root_build_dir),
|
||||
"--depfile",
|
||||
rebase_path(depfile, root_build_dir),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
# Validates a component manifest file
|
||||
#
|
||||
# The cmc_validate template will ensure that a given cmx file is conformant to
|
||||
# the cmx schema, as defined by //tools/cmc/schema.json. A stamp file is
|
||||
# generated to mark that a given cmx file has passed.
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# manifest (required)
|
||||
# [file] The path to the cmx file that is to be validated
|
||||
#
|
||||
# deps
|
||||
# testonly
|
||||
# visibility
|
||||
#
|
||||
template("cmc_validate") {
|
||||
_cmc_tool(target_name) {
|
||||
forward_variables_from(invoker,
|
||||
[
|
||||
"manifest",
|
||||
"deps",
|
||||
"testonly",
|
||||
"visibility",
|
||||
])
|
||||
stamp_file = "$target_gen_dir/$target_name.verified"
|
||||
|
||||
assert(defined(manifest), "manifest file required")
|
||||
|
||||
inputs = [ manifest ]
|
||||
|
||||
outputs = [ stamp_file ]
|
||||
|
||||
args = [
|
||||
"--stamp",
|
||||
rebase_path(stamp_file, root_build_dir),
|
||||
"validate",
|
||||
rebase_path(invoker.manifest),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
# Merges multiple component manifest files into one.
|
||||
#
|
||||
# Combines mutliple component manifests into a single manifest.
|
||||
# This is useful for merging fragments of sandbox configurations into
|
||||
# a single component manifest.
|
||||
#
|
||||
# Example
|
||||
#
|
||||
# ```
|
||||
# cmc_merge("combined_cmx") {
|
||||
# sources = ["sandbox.cmx", "services.cmx", "program.cmx"]
|
||||
# output_name = "my-component.cmx"
|
||||
# }
|
||||
# ```
|
||||
#
|
||||
# Parameters
|
||||
#
|
||||
# sources
|
||||
# The list of cmx files to merge together.
|
||||
#
|
||||
# Type: list of strings (filepath)
|
||||
#
|
||||
# output_name [optional]
|
||||
# The name of the merged cmx file. This file is created in $target_out_dir.
|
||||
# If not specified, $target_name.cmx is used.
|
||||
#
|
||||
# Type: string
|
||||
#
|
||||
# Standard parameters:
|
||||
# deps
|
||||
# testonly
|
||||
# visibility
|
||||
#
|
||||
template("cmc_merge") {
|
||||
_cmc_tool(target_name) {
|
||||
forward_variables_from(invoker,
|
||||
[
|
||||
"deps",
|
||||
"output_name",
|
||||
"sources",
|
||||
"testonly",
|
||||
"visibility",
|
||||
])
|
||||
if (!defined(output_name)) {
|
||||
output_name = "${target_name}.cmx"
|
||||
}
|
||||
|
||||
merged_output = "${target_out_dir}/${output_name}"
|
||||
inputs = invoker.sources
|
||||
outputs = [ merged_output ]
|
||||
|
||||
args = [
|
||||
"merge",
|
||||
"--output",
|
||||
rebase_path(merged_output, root_build_dir),
|
||||
]
|
||||
|
||||
foreach(source, sources) {
|
||||
args += [ rebase_path(source, root_build_dir) ]
|
||||
}
|
||||
}
|
||||
}
|
||||
233
engine/src/flutter/tools/fuchsia/sdk/component.gni
Normal file
233
engine/src/flutter/tools/fuchsia/sdk/component.gni
Normal file
@@ -0,0 +1,233 @@
|
||||
# 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("cmc.gni")
|
||||
|
||||
declare_args() {
|
||||
# Enable code coverage for Fuchsia components. Only applies to v1 components.
|
||||
fuchsia_code_coverage = false
|
||||
}
|
||||
|
||||
# Defines a Fuchsia component.
|
||||
# See: https://fuchsia.dev/fuchsia-src/glossary#component
|
||||
#
|
||||
# A component is defined by a component manifest.
|
||||
# A component is a unit of executable software on Fuchsia. When the componet is executed, there are usually many files
|
||||
# needed at runtime, such as the executable itself, shared libraries, and possibly other data resources. These files are
|
||||
# specified by using the GN concept of "data_deps".
|
||||
#
|
||||
# Components are distributed using a fuchsia package which can contain multiple components. The component manifest and
|
||||
# the runtime dependencies of the component are packaged using the fuchsia_package rule.
|
||||
#
|
||||
# By default, the runtime depenencies of the component are included in the package using relative paths calcualted from
|
||||
# the "closest" root of: $root_gen_dir, $root_dir, $out_dir. If a specific path is desired in the package, the "resources" parameter can
|
||||
# be used to explicitly specify the path of a specific file.
|
||||
#
|
||||
# A component is launched by a URL which identifies the package and the component manifest.
|
||||
# See: https://fuchsia.dev/fuchsia-src/glossary#component_url
|
||||
#
|
||||
# Example
|
||||
#
|
||||
# ```
|
||||
# fuchsia_component("my_component") {
|
||||
# manifest = "meta/component-manifest.cmx"
|
||||
# resources = [
|
||||
# path = "testdata/use_case1.json"
|
||||
# dest = "data/testdata/use_case1.json"
|
||||
# ]
|
||||
# data_deps = [ ":hello_world_executable"]
|
||||
# }
|
||||
# ```
|
||||
#
|
||||
# Parameters
|
||||
#
|
||||
# manifest
|
||||
# The source manifest file for this component. This can be either v1 (.cmx)
|
||||
# or v2 (.cml) manifest.
|
||||
#
|
||||
# Type: string (filepath)
|
||||
#
|
||||
# data_deps
|
||||
# The labels of targets that generate the files needed at runtime by the component.
|
||||
# At minimum, this should include the label of the binary to include in the component.
|
||||
#
|
||||
# Type: list of labels
|
||||
#
|
||||
# manifest_output_name [optional]
|
||||
# The name of the manifest file contained in the distribution that this
|
||||
# component is included in. The output name should have no extension or
|
||||
# prefixes. The resulting filename will have the extension correct for the
|
||||
# manifest version. For example, if `manifest` is "foo.cmx"
|
||||
# and `manifest_output_name` is "bar", the filename will be "bar.cmx". If
|
||||
# `manifest` is "foo.cml" (a v2 manifest), the filename will be "bar.cm".
|
||||
#
|
||||
# Type: string
|
||||
# Default: The base file name of `manifest` without an extension.
|
||||
#
|
||||
# resources [optional]
|
||||
# Lists additional files to include for runtime access by the component.
|
||||
# Defines the resources in a package containing this component. A resource
|
||||
# is a data file that may be produced by the build system, checked in to a
|
||||
# source repository, or produced by another system that runs before the
|
||||
# build. Resources are placed in the `data/` directory of the assembled
|
||||
# package.
|
||||
#
|
||||
# Type: list of scopes. Entries in a scope in the resources list:
|
||||
# path (required)
|
||||
# Location of resource in source or build directory. If the
|
||||
# resource is checked in, this will typically be specified
|
||||
# as a path relative to the BUILD.gn file containing the
|
||||
# `package()` target. If the resource is generated, this will
|
||||
# typically be specified relative to `$target_gen_dir`.
|
||||
#
|
||||
# dest (required) string (path) Location the resource will be placed within `data/`.
|
||||
#
|
||||
# Standard parameters:
|
||||
# deps
|
||||
# testonly
|
||||
# visibility
|
||||
#
|
||||
# Metadata
|
||||
# contents - list of scopes describing files for this component. This metadata is consumed by
|
||||
# The fuchsia_package rule, which describes the entries used.
|
||||
# Entries in scope:
|
||||
# type: the usage type of the element, manifest or resource.
|
||||
# Each type can have specific properties included in the scope.
|
||||
# source [type == manifest || resource] The source file to include in
|
||||
# the package for this component. In the case of v2 components,
|
||||
# this is the compiled manifest.
|
||||
# output_name [type == manifest] The basename of the manifest as it should appear in the package.
|
||||
# manifest_version [type == manifest]
|
||||
# dest: [type == resource] The package relative path of the resource.
|
||||
|
||||
template("fuchsia_component") {
|
||||
forward_variables_from(invoker,
|
||||
[
|
||||
"manifest",
|
||||
"manifest_output_name",
|
||||
])
|
||||
|
||||
assert(defined(manifest), "manifest file required for this component")
|
||||
|
||||
if (!defined(manifest_output_name)) {
|
||||
manifest_output_name = get_path_info(manifest, "name")
|
||||
}
|
||||
|
||||
# Determine manifest_version from the `manifest` file extension.
|
||||
_manifest_extension = get_path_info(manifest, "extension")
|
||||
assert(_manifest_extension == "cmx" || _manifest_extension == "cml",
|
||||
"Manifest file extension must be .cmx or .cml")
|
||||
if (_manifest_extension == "cmx") {
|
||||
_manifest_version = "v1"
|
||||
} else if (_manifest_extension == "cml") {
|
||||
_manifest_version = "v2"
|
||||
}
|
||||
|
||||
if (fuchsia_code_coverage) {
|
||||
if (_manifest_version == "v1") {
|
||||
merged_manifest = "${target_name}-coverage.cmx"
|
||||
cmc_merge(merged_manifest) {
|
||||
forward_variables_from(invoker,
|
||||
[
|
||||
"deps",
|
||||
"testonly",
|
||||
])
|
||||
sources = [
|
||||
"${fuchsia_sdk}/build/enable_coverage_data.cmx",
|
||||
manifest,
|
||||
]
|
||||
output_name = merged_manifest
|
||||
}
|
||||
manifest = "${target_out_dir}/${merged_manifest}"
|
||||
}
|
||||
}
|
||||
|
||||
# The component manifest validated using cmx_validation for v1,
|
||||
# or cmc_compile for v2.
|
||||
_cm_validation_target =
|
||||
"${target_name}_validate_" + get_path_info(manifest, "file")
|
||||
|
||||
if (_manifest_version == "v1") {
|
||||
cmc_validate(_cm_validation_target) {
|
||||
forward_variables_from(invoker, [ "testonly" ])
|
||||
manifest = manifest
|
||||
deps = []
|
||||
if (defined(invoker.deps)) {
|
||||
deps += invoker.deps
|
||||
}
|
||||
if (fuchsia_code_coverage) {
|
||||
deps += [ ":${merged_manifest}" ]
|
||||
}
|
||||
}
|
||||
|
||||
_manifest_source = manifest
|
||||
} else if (_manifest_version == "v2") {
|
||||
cmc_compile(_cm_validation_target) {
|
||||
forward_variables_from(invoker,
|
||||
[
|
||||
"deps",
|
||||
"testonly",
|
||||
])
|
||||
manifest = rebase_path(manifest)
|
||||
}
|
||||
|
||||
_compiled_manifest_outputs = get_target_outputs(":$_cm_validation_target")
|
||||
_manifest_source = _compiled_manifest_outputs[0]
|
||||
}
|
||||
|
||||
group(target_name) {
|
||||
forward_variables_from(invoker,
|
||||
[
|
||||
"data",
|
||||
"deps",
|
||||
"data_deps",
|
||||
"resources",
|
||||
"testonly",
|
||||
"visibility",
|
||||
])
|
||||
|
||||
# Data is used for adding files as runtime dependencies. Files used as
|
||||
# sources in the resources parameter are added as data to make sure
|
||||
# non-generated files listed are captured as dependencies.
|
||||
if (!defined(data)) {
|
||||
data = []
|
||||
}
|
||||
|
||||
if (!defined(resources)) {
|
||||
resources = []
|
||||
}
|
||||
|
||||
if (!defined(deps)) {
|
||||
deps = []
|
||||
}
|
||||
deps += [ ":$_cm_validation_target" ]
|
||||
|
||||
# Create the component metadata entries. These capture the manifest information and
|
||||
# the resources parameter contents. The metadata is intended for the fuchsia_package rule.
|
||||
component_contents = [
|
||||
{
|
||||
type = "manifest"
|
||||
source = rebase_path(_manifest_source)
|
||||
output_name = manifest_output_name
|
||||
manifest_version = _manifest_version
|
||||
},
|
||||
]
|
||||
foreach(resource, resources) {
|
||||
data += [ resource.path ]
|
||||
component_contents += [
|
||||
{
|
||||
type = "resource"
|
||||
source = rebase_path(resource.path)
|
||||
dest = resource.dest
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
# The contents of the component are enumerated in the
|
||||
# metadata.
|
||||
metadata = {
|
||||
contents = [ component_contents ]
|
||||
}
|
||||
}
|
||||
}
|
||||
39
engine/src/flutter/tools/fuchsia/sdk/config/config.gni
Normal file
39
engine/src/flutter/tools/fuchsia/sdk/config/config.gni
Normal file
@@ -0,0 +1,39 @@
|
||||
# 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/fuchsia/sdk.gni")
|
||||
|
||||
declare_args() {
|
||||
# Path to the fuchsia SDK. This is intended for use in other templates & rules
|
||||
# to reference the contents of the fuchsia SDK.
|
||||
fuchsia_sdk = "$fuchsia_sdk_path"
|
||||
|
||||
# Build ID uniquely identifying the Fuchsia IDK. This is exposed as a property so
|
||||
# it can be used to locate images and packages on GCS and as a marker to indicate the
|
||||
# "version" of the IDK. If it is empty, then it is most likely that something is fatally wrong.
|
||||
fuchsia_sdk_id = ""
|
||||
}
|
||||
|
||||
declare_args() {
|
||||
# The SDK manifest file. This is useful to include as a dependency
|
||||
# for some targets in order to cause a rebuild when the version of the
|
||||
# SDK is changed.
|
||||
fuchsia_sdk_manifest_file = "$fuchsia_sdk/meta/manifest.json"
|
||||
|
||||
# fuchsia_tool_dir is use to specify the directory in the SDK to locate tools for the
|
||||
# host cpu architecture. If the host_cpu is not recognized, then tool dir
|
||||
# defaults to x64.
|
||||
fuchsia_tool_dir = "$fuchsia_sdk/tools/x64"
|
||||
if (host_cpu == "x64" || host_cpu == "arm64") {
|
||||
fuchsia_tool_dir = "${fuchsia_sdk}/tools/${host_cpu}"
|
||||
}
|
||||
}
|
||||
|
||||
if (fuchsia_sdk_id == "") {
|
||||
# Note: If we need to expose more than just the id in the future,
|
||||
# we should consider exposing the entire json object for the metadata vs.
|
||||
# adding a bunch of variables.
|
||||
_meta = read_file(fuchsia_sdk_manifest_file, "json")
|
||||
fuchsia_sdk_id = _meta.id
|
||||
}
|
||||
92
engine/src/flutter/tools/fuchsia/sdk/find_dart_libraries.py
Executable file
92
engine/src/flutter/tools/fuchsia/sdk/find_dart_libraries.py
Executable file
@@ -0,0 +1,92 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# 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.
|
||||
|
||||
""" Resolve a dart third_party library dependency by returning the path to an
|
||||
existing downloaded version one of a few possible subdirectories under
|
||||
//third_party. Some of these pre-downloaded libraries may be directly downloaded
|
||||
via a //flutter/DEPS entry. Others may be bundled with the Dart SDK, in one of
|
||||
its provided libraries or its third_party packages.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import yaml
|
||||
import os
|
||||
import sys
|
||||
import pkg_resources
|
||||
|
||||
|
||||
def find_package(root, local_paths, package, version):
|
||||
"""Return the package target if found with at least this version"""
|
||||
needed_version = pkg_resources.parse_version(version)
|
||||
for local_path in local_paths:
|
||||
package_path = os.path.join(local_path, package)
|
||||
pubspec_yaml = os.path.join(root, package_path, 'pubspec.yaml')
|
||||
if os.path.exists(pubspec_yaml):
|
||||
with open(pubspec_yaml) as yaml_file:
|
||||
pubspec = yaml.safe_load(yaml_file)
|
||||
found_version = pkg_resources.parse_version(pubspec['version'])
|
||||
if found_version >= needed_version:
|
||||
return "//" + package_path
|
||||
return None
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
parser.add_argument(
|
||||
'--ignore-missing',
|
||||
action='store_true',
|
||||
help=('Return a success exit status, with all matched dart libraries, '
|
||||
'even if one or more matches were not found'))
|
||||
parser.add_argument(
|
||||
'--root',
|
||||
help='Path to the flutter engine src root',
|
||||
required=True)
|
||||
parser.add_argument(
|
||||
'--target',
|
||||
help='The name of the target that consolidates the derived deps',
|
||||
required=True)
|
||||
parser.add_argument(
|
||||
'--local-path',
|
||||
help=('A parent directory of pre-existing third_party dart libraries '
|
||||
'(multiple --local-path arguments allowed)'),
|
||||
action='append',
|
||||
dest='local_paths',
|
||||
required=True)
|
||||
|
||||
(args, versioned_dart_packages) = parser.parse_known_args()
|
||||
|
||||
assert os.path.exists(args.root)
|
||||
|
||||
for path in args.local_paths:
|
||||
assert os.path.isdir(os.path.join(args.root, path))
|
||||
|
||||
if len(versioned_dart_packages) > 0:
|
||||
assert len(versioned_dart_packages) % 2 == 0, (
|
||||
'Each third_party_dep package must be accompanied by a version')
|
||||
|
||||
dart_package_paths = []
|
||||
it = iter(versioned_dart_packages)
|
||||
for item in it:
|
||||
(package, version) = item, next(it)
|
||||
path = find_package(args.root, args.local_paths, package, version)
|
||||
if path is not None:
|
||||
dart_package_paths.append(path)
|
||||
else:
|
||||
print(
|
||||
'No package found for %s with version %s' % (package, version),
|
||||
file=sys.stderr)
|
||||
if not args.ignore_missing:
|
||||
return 1
|
||||
|
||||
json.dump(dart_package_paths, sys.stdout)
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
139
engine/src/flutter/tools/fuchsia/sdk/sdk_targets.gni
Normal file
139
engine/src/flutter/tools/fuchsia/sdk/sdk_targets.gni
Normal file
@@ -0,0 +1,139 @@
|
||||
# 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/fuchsia/sdk.gni")
|
||||
import("//flutter/tools/fuchsia/dart/dart_library.gni")
|
||||
import("//flutter/tools/fuchsia/fidl/fidl.gni")
|
||||
|
||||
_fuchsia_sdk_path = "//fuchsia/sdk/$host_os"
|
||||
|
||||
template("_fuchsia_dart_library") {
|
||||
assert(defined(invoker.meta), "The meta file content must be specified.")
|
||||
meta = invoker.meta
|
||||
assert(meta.type == "dart_library")
|
||||
|
||||
_output_name = meta.name
|
||||
_sources = []
|
||||
_deps = []
|
||||
|
||||
if (defined(meta.dart_library_null_safe) && meta.dart_library_null_safe) {
|
||||
_dart_language_version = "2.12"
|
||||
} else {
|
||||
_dart_language_version = "2.0"
|
||||
}
|
||||
|
||||
foreach(source, meta.sources) {
|
||||
_sources += [ string_replace("$source", "${meta.root}/lib/", "") ]
|
||||
}
|
||||
|
||||
foreach(dep, meta.deps) {
|
||||
_deps += [ "../dart:$dep" ]
|
||||
}
|
||||
|
||||
foreach(dep, meta.fidl_deps) {
|
||||
_deps += [ "//flutter/tools/fuchsia/fidl:$dep" ]
|
||||
}
|
||||
|
||||
# Compute the third_party deps. The Fuchsia SDK doesn't know where to resolve
|
||||
# a third_party dep, and Flutter has third_party Dart libraries in more than
|
||||
# one location (some downloaded directly, others as part of the Dart SDK or
|
||||
# bundled as a Dart SDK third_party dep). Find a matching library. If a match
|
||||
# is required by a build dependency, and a match is not found, you may need to
|
||||
# add an entry for it in `flutter/DEPS`.
|
||||
known_pkg_paths = [
|
||||
"third_party/pkg",
|
||||
"third_party/dart/pkg",
|
||||
"third_party/dart/third_party/pkg",
|
||||
]
|
||||
|
||||
args = [
|
||||
"--ignore-missing",
|
||||
"--root",
|
||||
rebase_path("//"),
|
||||
"--target",
|
||||
rebase_path(target_name, "//"),
|
||||
]
|
||||
|
||||
foreach(path, known_pkg_paths) {
|
||||
args += [
|
||||
"--local-path",
|
||||
path,
|
||||
]
|
||||
}
|
||||
|
||||
foreach(third_party_dep, meta.third_party_deps) {
|
||||
name = third_party_dep.name
|
||||
version = third_party_dep.version
|
||||
args += [
|
||||
name,
|
||||
version,
|
||||
]
|
||||
}
|
||||
|
||||
third_party_deps_json =
|
||||
exec_script("//flutter/tools/fuchsia/sdk/find_dart_libraries.py",
|
||||
args,
|
||||
"json")
|
||||
|
||||
_deps += third_party_deps_json
|
||||
|
||||
dart_library(target_name) {
|
||||
package_root = "${_fuchsia_sdk_path}/${meta.root}"
|
||||
package_name = _output_name
|
||||
language_version = _dart_language_version
|
||||
sources = _sources
|
||||
deps = _deps
|
||||
}
|
||||
}
|
||||
|
||||
template("_fuchsia_fidl_library") {
|
||||
assert(defined(invoker.meta), "The meta file content must be specified.")
|
||||
meta = invoker.meta
|
||||
assert(meta.type == "fidl_library")
|
||||
|
||||
fidl(target_name) {
|
||||
sources = []
|
||||
foreach(source, meta.sources) {
|
||||
sources += [ "$fuchsia_sdk_path/$source" ]
|
||||
}
|
||||
public_deps = []
|
||||
foreach(dep, meta.deps) {
|
||||
public_deps += [ ":$dep" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template("sdk_targets") {
|
||||
assert(defined(invoker.meta), "The meta.json file path must be specified.")
|
||||
|
||||
target_type = invoker.target_name
|
||||
|
||||
meta_json = read_file(invoker.meta, "json")
|
||||
|
||||
foreach(part, meta_json.parts) {
|
||||
part_meta_json = {
|
||||
}
|
||||
|
||||
part_meta = part.meta
|
||||
part_meta_rebased = "$fuchsia_sdk_path/$part_meta"
|
||||
|
||||
part_meta_json = read_file(part_meta_rebased, "json")
|
||||
subtarget_name = part_meta_json.name
|
||||
|
||||
if (part.type == target_type) {
|
||||
if (target_type == "dart_library") {
|
||||
_fuchsia_dart_library(subtarget_name) {
|
||||
meta = part_meta_json
|
||||
}
|
||||
} else if (target_type == "fidl_library") {
|
||||
_fuchsia_fidl_library(subtarget_name) {
|
||||
meta = part_meta_json
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
group(target_name) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
# 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/fuchsia/toolchain/default_tools.gni")
|
||||
|
||||
declare_args() {
|
||||
toolchain_variant = {
|
||||
}
|
||||
}
|
||||
|
||||
# Define a basic GN toolchain() instance that only has the "stamp" and "copy"
|
||||
# tools. Use this for toolchains that will only have action() targets.
|
||||
#
|
||||
# Parameters:
|
||||
# expected_label: Optional
|
||||
# If provided, this template will assert that the full toolchain label
|
||||
# matches this value. This is useful when the definition should match
|
||||
# a global variable (e.g. go_toolchain or dart_toolchain).
|
||||
# Type: GN label
|
||||
#
|
||||
# toolchain_args: Optional
|
||||
# A scope of extra toolchain_args keys for this toolchain instance.
|
||||
#
|
||||
# NOTE: This also ensures this defines the global `toolchain_variant.base`
|
||||
# variable, allowing BUILDCONFIG.gn to detect that this is not the default
|
||||
# toolchain (see the definition of in_default_toolchain in that file for
|
||||
# more details).
|
||||
template("basic_toolchain") {
|
||||
# The line below is required, otherwise 'gn gen' will complain with an error
|
||||
# (i.e. 'You set the variable "invoker" here and it was unused before it went
|
||||
# out of scope') if the template is called without any arguments.
|
||||
not_needed([ "invoker" ])
|
||||
|
||||
toolchain(target_name) {
|
||||
tool("stamp") {
|
||||
command = stamp_command
|
||||
description = stamp_description
|
||||
}
|
||||
tool("copy") {
|
||||
command = copy_command
|
||||
description = copy_description
|
||||
}
|
||||
toolchain_args = {
|
||||
if (defined(invoker.toolchain_args)) {
|
||||
forward_variables_from(invoker.toolchain_args, "*")
|
||||
}
|
||||
toolchain_variant = {
|
||||
base = get_label_info(":$target_name", "label_no_toolchain")
|
||||
if (defined(invoker.expected_label)) {
|
||||
assert(
|
||||
base == invoker.expected_label,
|
||||
"Invalid toolchain label $base, expected ${invoker.expected_label}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
48
engine/src/flutter/tools/fuchsia/toolchain/copy.py
Executable file
48
engine/src/flutter/tools/fuchsia/toolchain/copy.py
Executable file
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/env python3.8
|
||||
# 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.
|
||||
"""Emulation of `rm -f out && cp -af` in out. This is necessary on Mac in order
|
||||
to preserve nanoseconds of mtime. See https://fxbug.dev/56376#c5."""
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) != 3:
|
||||
print('usage: copy.py source dest', file=sys.stderr)
|
||||
return 1
|
||||
source = sys.argv[1]
|
||||
dest = sys.argv[2]
|
||||
|
||||
if os.path.isdir(source):
|
||||
print(
|
||||
f'{source} is a directory, tool "copy" does not support directory copies'
|
||||
)
|
||||
return 1
|
||||
|
||||
if os.path.exists(dest):
|
||||
if os.path.isdir(dest):
|
||||
|
||||
def _on_error(fn, path, dummy_excinfo):
|
||||
# The operation failed, possibly because the file is set to
|
||||
# read-only. If that's why, make it writable and try the op
|
||||
# again.
|
||||
if not os.access(path, os.W_OK):
|
||||
os.chmod(path, stat.S_IWRITE)
|
||||
fn(path)
|
||||
|
||||
shutil.rmtree(dest, onerror=_on_error)
|
||||
else:
|
||||
if not os.access(dest, os.W_OK):
|
||||
# Attempt to make the file writable before deleting it.
|
||||
os.chmod(dest, stat.S_IWRITE)
|
||||
os.unlink(dest)
|
||||
|
||||
shutil.copy2(source, dest)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
28
engine/src/flutter/tools/fuchsia/toolchain/default_tools.gni
Normal file
28
engine/src/flutter/tools/fuchsia/toolchain/default_tools.gni
Normal file
@@ -0,0 +1,28 @@
|
||||
# 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.
|
||||
|
||||
# Each toolchain must define "stamp" and "copy" tools,
|
||||
# but they are always the same in every toolchain.
|
||||
stamp_command = "touch {{output}}"
|
||||
stamp_description = "STAMP {{output}}"
|
||||
|
||||
# mtime on directories may not reflect the latest of a directory. For example in
|
||||
# popular file systems, modifying a file in a directory does not affect mtime of
|
||||
# the directory. Because of this, disable directory copy for incremental
|
||||
# correctness. See https://fxbug.dev/73250.
|
||||
copy_command = "if [ -d {{source}} ]; then echo 'Tool \"copy\" does not support directory copies'; exit 1; fi; "
|
||||
|
||||
# We use link instead of copy; the way "copy" tool is being used is
|
||||
# compatible with links since Ninja is tracking changes to the source.
|
||||
if (host_os == "mac") {
|
||||
# `cp -af` does not correctly preserve mtime (the nanoseconds are truncated to
|
||||
# microseconds) which causes spurious ninja rebuilds. As a result, shell to a
|
||||
# helper to copy rather than calling cp -r. See https://fxbug.dev/56376#c5.
|
||||
copy_command += "ln -f {{source}} {{output}} 2>/dev/null || (" +
|
||||
rebase_path("//flutter/tools/fuchsia/toolchain/copy.py") +
|
||||
" {{source}} {{output}})"
|
||||
} else {
|
||||
copy_command += "ln -f {{source}} {{output}} 2>/dev/null || (rm -f {{output}} && cp -af {{source}} {{output}})"
|
||||
}
|
||||
copy_description = "COPY {{source}} {{output}}"
|
||||
Reference in New Issue
Block a user