Files
sdk/build/dart/dart_action.gni
T
asiva 5399dbf6f6 [VM/dartdev] Switch dartdev to use an AOT runtime.
- split the Dart CLI tool out of the VM into it's own embedder which
  runs in AOT mode. The pure Dart VM executable is called 'dartvm' and
  has no Dart CLI functionality in it
- the Dart CLI executable parses the CLI commands and invokes the rest
  of the AOT tools in the same process, for the 'run' and 'test'
  commands it execs a process which runs 'dartvm' to run
- 'dart hello.dart' execs the 'dartvm' process and runs 'hello.dart'
- the Dart CLI is not generated for ia32 as we are not shipping a
  Dart SDK for ia32 anymore (support to execute the 'dartvm' for ia32
  architecture is retained)
- the Dart CLI tool is not built in the internal Dart SDK builds

TEST=ci

Some performance improvement numbers
'dart format pkg/dartdev' goes from 1.17 secs to 0.22 secs
'dart doc pkg/dartdev' goes from 100.2 secs to 66.6 secs
'dart fix pkg/dartdev' goes from 19.3 secs to 14.5 secs

Change-Id: I66984a26cb2ab014b34dc1873f1f3d2884e13518
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/364202
Commit-Queue: Ben Konyi <bkonyi@google.com>
Reviewed-by: Ben Konyi <bkonyi@google.com>
2025-07-04 13:22:13 -07:00

441 lines
14 KiB
Plaintext

# Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
import("../executable_suffix.gni")
# This file defines templates for running and compiling Dart code during
# Dart's build.
#
# - prebuilt_dart_action()
# Runs Dart scripts using the downloaded prebuilt Dart SDK. This is the
# preferred method of running Dart code during the build as it is much
# faster than using dartvm_action() in debug and cross builds.
# However, prebuilt_dart_action() should *not* be used to generate snapshots.
#
# - prebuilt_dartaotruntime_action()
# Runs Dart AOT snapshots using the downloaded prebuilt Dart SDK. This is the
# preferred method of running Dart AOT code during the build as it avoids
# the multiple layers of code that prebuilt_dart_action goes through.
#
# - dartvm_action()
# Runs Dart scripts using the binary built for runtime/bin:dart using the
# host toolchain. It should only be used when an artifact agreeing exactly
# with the version of the Dart VM being built must be produced, for example
# an App-JIT snapshot. This will be slow in Debug builds, and very slow in
# cross builds.
#
# - gen_snapshot_action()
# Runs the binary built for runtime/bin:gen_snapshot using the host
# toolchain. It should only be used when an artifact agreeing exactly
# with the version of the Dart VM being built must be produced.
# This assigns _dart_root the GN absolute path of the Dart repo. For example,
# in a Dart checkout, this will be "//". In a client repo it might be
# "//third_party/dart".
_dart_root = get_path_info("../..", "abspath")
_is_dart = _dart_root == get_path_info("//", "abspath")
if (_is_dart) {
import("../toolchain/rbe.gni")
}
template("_compiled_action") {
assert(defined(invoker.tool), "tool must be defined for $target_name")
assert(defined(invoker.outputs), "outputs must be defined for $target_name")
assert(defined(invoker.args), "args must be defined for $target_name")
action(target_name) {
if (defined(invoker.visibility)) {
visibility = invoker.visibility
}
if (defined(invoker.testonly)) {
testonly = invoker.testonly
}
if (defined(invoker.pool)) {
pool = invoker.pool
}
script = "$_dart_root/build/gn_run_binary.py"
if (defined(invoker.inputs)) {
inputs = invoker.inputs
} else {
inputs = []
}
outputs = invoker.outputs
# Construct the host toolchain version of the tool.
host_tool = invoker.tool + "($host_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") + executable_suffix
# Add the executable itself as an input.
inputs += [ host_executable ]
deps = [ host_tool ]
if (defined(invoker.deps)) {
deps += invoker.deps
}
if (defined(invoker.depfile)) {
depfile = invoker.depfile
}
# The "compiled_action" argument to gn_run_binary.py indicates that
# it will exit with a non-zero status when the target program does.
args = [ "compiled_action" ]
if (_is_dart && use_rbe && host_os == rbe_os && host_cpu == rbe_cpu) {
args += [
"/usr/bin/python3",
rebase_path("//build/rbe/rewrapper_dart.py", root_build_dir),
] + rewrapper_args +
[
"--exec_strategy=" + rbe_expensive_exec_strategy,
"--",
]
} else if (!defined(invoker.pool)) {
pool = "$_dart_root/build/dart:dart_action_pool($default_toolchain)"
}
args += [ rebase_path(host_executable, root_build_dir) ] + invoker.args
}
}
template("_prebuilt_tool_action") {
assert(defined(invoker.binary),
"The path to where the prebuilt binary lives must be defined")
vm_args = []
if (defined(invoker.vm_args)) {
vm_args += invoker.vm_args
}
action(target_name) {
forward_variables_from(invoker,
[
"depfile",
"deps",
"outputs",
"pool",
"testonly",
"visibility",
])
script = "$_dart_root/build/gn_run_binary.py"
inputs = []
if (defined(invoker.inputs)) {
inputs += invoker.inputs
}
if (defined(invoker.script)) {
inputs += [ invoker.script ]
}
if (defined(invoker.packages)) {
inputs += [ invoker.packages ]
}
args = [ "compiled_action" ]
if (_is_dart && use_rbe && host_os == rbe_os && host_cpu == rbe_cpu) {
args += [
"/usr/bin/python3",
rebase_path("//build/rbe/rewrapper_dart.py", root_build_dir),
] + rewrapper_args +
[
"--exec_strategy=" + rbe_expensive_exec_strategy,
"--",
]
} else if (!defined(invoker.pool)) {
pool = "$_dart_root/build/dart:dart_action_pool($default_toolchain)"
}
args += [ rebase_path(invoker.binary, root_build_dir) ] + vm_args
if (defined(invoker.packages)) {
args += [ "--packages=" + rebase_path(invoker.packages, root_build_dir) ]
}
if (defined(invoker.dfe)) {
args += [ "--dfe=" + rebase_path(invoker.dfe, root_build_dir) ]
}
if (defined(invoker.script)) {
args += [ rebase_path(invoker.script, root_build_dir) ]
}
args += invoker.args
}
}
# A template for running Dart scripts during the build using the prebuilt Dart
# SDK. This should *not* be used for generating snapshots. It uses the dart
# binary from the prebuilt Dart SDK.
#
# Parameters:
# script:
# The un-rebased path to the Dart script.
#
# vm_args (optional):
# Arguments to pass to the Dart VM.
#
# args (optional):
# The arguments to pass to the Dart script.
#
# packages (optional):
# The un-rebased path to the package_config.json file.
#
# Forwarded to action() with the usual meaning:
# depfile
# deps
# inputs
# metadata
# outputs
# testonly
# visibility
template("prebuilt_dart_action") {
assert(defined(invoker.outputs), "outputs must be defined for $target_name")
assert(defined(invoker.args), "args must be defined for $target_name")
assert(!defined(invoker.sources),
"prebuilt_dart_action doesn't take a sources arg. Use inputs instead.")
_prebuilt_tool_action(target_name) {
forward_variables_from(invoker, "*")
binary = "$_dart_root/tools/sdks/dart-sdk/bin/dart$executable_suffix"
dfe = "$_dart_root/tools/sdks/dart-sdk/bin/snapshots/kernel-service.dart.snapshot"
}
}
# A template for running Dart AOT snapshots during the build using the prebuilt
# Dart SDK. This should *not* be used for generating snapshots. It uses the dart
# binary from the prebuilt Dart SDK.
#
# Parameters:
# script:
# The un-rebased path to the Dart AOT snapshot.
#
# vm_args (optional):
# Arguments to pass to the Dart VM.
#
# args (optional):
# The arguments to pass to the Dart AOT snapshot.
#
# packages (optional):
# The un-rebased path to the package_config.json file.
#
# Forwarded to action() with the usual meaning:
# depfile
# deps
# inputs
# metadata
# outputs
# testonly
# visibility
template("prebuilt_dartaotruntime_action") {
assert(defined(invoker.outputs), "outputs must be defined for $target_name")
assert(defined(invoker.args), "args must be defined for $target_name")
assert(
!defined(invoker.sources),
"prebuilt_dartaotruntime_action doesn't take a sources arg. Use inputs instead.")
_prebuilt_tool_action(target_name) {
forward_variables_from(invoker, "*")
binary =
"$_dart_root/tools/sdks/dart-sdk/bin/dartaotruntime$executable_suffix"
}
}
# This template runs the specified tool produced by the in-progress build.
#
# Parameters:
# tool:
# The target of the tool to run.
#
# script (optional):
# The un-rebased path to the Dart script.
#
# vm_args (optional):
# Arguments to pass to the Dart VM.
#
# args (optional):
# The arguments to pass to the Dart script.
#
# packages (optional):
# The un-rebased path to the package_config.json file.
#
# Forwarded to action() with the usual meaning:
# depfile
# deps
# inputs
# metadata
# outputs
# testonly
# visibility
template("_built_tool_action") {
assert(defined(invoker.tool), "tool must be defined for $target_name")
assert(defined(invoker.outputs), "outputs must be defined for $target_name")
assert(defined(invoker.args), "args must be defined for $target_name")
assert(!defined(invoker.sources),
"sources arg not supported for $target_name. Use inputs instead.")
vm_args = []
if (defined(invoker.vm_args)) {
vm_args += invoker.vm_args
}
_compiled_action(target_name) {
forward_variables_from(invoker,
[
"depfile",
"deps",
"inputs",
"metadata",
"outputs",
"pool",
"tool",
"testonly",
"visibility",
])
if (!defined(invoker.inputs)) {
inputs = []
}
if (defined(invoker.script)) {
inputs += [ invoker.script ]
}
if (defined(invoker.packages)) {
inputs += [ invoker.packages ]
}
args = vm_args
if (defined(invoker.packages)) {
args += [ "--packages=" + rebase_path(invoker.packages, root_build_dir) ]
}
if (defined(invoker.script)) {
args += [ rebase_path(invoker.script, root_build_dir) ]
}
args += invoker.args
}
}
# This template runs the Dart VM produced by the in-progress build.
#
# Parameters:
# script:
# The un-rebased path to the Dart script.
#
# dfe (optional):
# Sets the DFE file used by Dart. If not set the VM will attempt to load it
# from a snapshot, or fall back on its built-in kernel.
#
# vm_args (optional):
# Arguments to pass to the Dart VM.
#
# args (optional):
# The arguments to pass to the Dart script.
#
# packages (optional):
# The un-rebased path to the package_config.json file.
#
# Forwarded to action() with the usual meaning:
# depfile
# deps
# inputs
# metadata
# outputs
# testonly
# visibility
template("dartvm_action") {
assert(defined(invoker.script), "script must be defined for $target_name")
_built_tool_action(target_name) {
tool = "$_dart_root/runtime/bin:dartvm"
forward_variables_from(invoker,
[
"args",
"depfile",
"deps",
"inputs",
"metadata",
"outputs",
"packages",
"pool",
"script",
"testonly",
"tool",
"visibility",
"vm_args",
])
# Dart has an implicit dependency on the kernel service so unless DFE is
# passed, we need to add this dep.
if (defined(invoker.dfe)) {
vm_args += [ "--dfe=" + rebase_path(invoker.dfe, root_build_dir) ]
} else {
if (!defined(invoker.deps)) {
deps = []
}
deps += [ "$_dart_root/utils/kernel-service:kernel-service" ]
}
}
}
# This template runs the gen_snapshot produced by the in-progress build.
#
# Parameters:
# vm_args (optional):
# Arguments to pass to the Dart VM.
#
# args (optional):
# The arguments to pass to the Dart script.
#
# packages (optional):
# The un-rebased path to the package_config.json file.
#
# force_product_mode (optional):
# Setting this to true will cause snapshot to be built in product mode even
# if dart_runtime_mode is not product.
#
# Forwarded to action() with the usual meaning:
# depfile
# deps
# inputs
# metadata
# outputs
# testonly
# visibility
template("gen_snapshot_action") {
product_mode =
(defined(dart_runtime_mode) && dart_runtime_mode == "release") ||
(defined(invoker.force_product_mode) && invoker.force_product_mode)
assert(
!defined(invoker.script),
"script must not be defined for $target_name. If there is a script use args instead.")
_built_tool_action(target_name) {
if (product_mode) {
tool = "$_dart_root/runtime/bin:gen_snapshot_product"
} else {
tool = "$_dart_root/runtime/bin:gen_snapshot"
}
forward_variables_from(invoker,
[
"args",
"depfile",
"deps",
"inputs",
"metadata",
"outputs",
"packages",
"pool",
"testonly",
"tool",
"visibility",
"vm_args",
])
}
}