# 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 dart_action() in debug and cross builds. # However, prebuilt_dart_action() should *not* be used to generate snapshots. # # - dart_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 && (target_os == rbe_os || (target_os == "android" && rbe_os == "linux")) && target_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, "--", ] } 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 && (target_os == rbe_os || (target_os == "android" && rbe_os == "linux")) && target_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, "--", ] } 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 .packages 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" } } # 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 .packages 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 .packages file. # # Forwarded to action() with the usual meaning: # depfile # deps # inputs # metadata # outputs # testonly # visibility template("dart_action") { assert(defined(invoker.script), "script must be defined for $target_name") _built_tool_action(target_name) { tool = "$_dart_root/runtime/bin:dart" 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", ]) } }