blob: d18d37529f3868ce35fdfcc81a73e8c3394180db [file] [log] [blame]
# Copyright 2021 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//build/compiled_action.gni")
# This file is created by '//src/developer/ffx/build:ffx_env_config'
# and needs to be kept in sync with that.
ffx_env_for_build_label =
"//src/developer/ffx/build:ffx_env_config($host_toolchain)"
ffx_env_config = root_build_dir + "/.ffx.env"
sdk_host_tools_label = "//sdk:host_tools.modular($host_toolchain)"
sdk_host_tools_manifest = get_label_info(sdk_host_tools_label, "root_out_dir") +
"/sdk/manifest/host_tools.modular"
# Executes an ffx command as an action during the build.
#
# This is a wrapper around compiled_action() that automatically adds ffx as
# a dependency and an input, and properly configures the args.
#
# Parameters
#
# args (required)
# [list of strings] Same meaning as action(). All args to ffx need to be
# specified.
#
# outputs (required)
# [list of files] Like the outputs of action().
#
# inputs (optional)
#
# hermetic_inputs_file (optional)
# Implicit inputs to the ffx plugin.
#
# sources (optional)
# Files the plugin takes as input. The step will be re-run whenever any
# of these change. If inputs is empty, the step will run only when the
# plugin itself changes.
#
# args (all optional)
# depfile
# deps
# public_deps
# testonly
# visibility
# Same meaning as action()
#
# Example of usage:
#
# ffx_action("run_a_plugin") {
# outputs = [
# "$target_obj_dir/some_output_file",
# "$target_obj_dir/some_other_output_file",
# ]
#
# # The tool takes this input.
# inputs = [ "my_input_file" ]
#
# # In this case, the plugin takes as arguments the input file and the output
# # build dir (both relative to the root_build_dir that the plugin will be
# # run in) and will produce the output files listed above.
# args = [
# "path",
# "to",
# "plugin",
# rebase_path("my_input_file", root_build_dir),
# "--output-dir", rebase_path(target_out_dir, root_build_dir),
# ]
# }
#
# Which is equivalent to:
# `ffx path to plugin src/foo/my_input_file --output-dir obj/bar`
template("ffx_action") {
assert(defined(invoker.args), "args must be defined for $target_name")
assert(defined(invoker.outputs), "outputs must be defined for $target_name")
# Only generate our own hermetic inputs file if a depfile is not specified
# OR hermetic_deps is not turned off.
_use_hermetic_inputs_file =
!defined(invoker.depfile) &&
(!defined(invoker.hermetic_deps) || invoker.hermetic_deps)
if (_use_hermetic_inputs_file) {
# Generate a list of hermetic inputs based on the files in the SDK manifest.
# Also, merge in any additional inputs if necessary.
hermetic_inputs_label = "${target_name}_all_inputs"
hermetic_inputs_path = "${target_out_dir}/${target_name}_all_inputs"
hermetic_inputs_action(hermetic_inputs_label) {
forward_variables_from(invoker,
[
"testonly",
"visibility",
])
deps = [ sdk_host_tools_label ]
if (defined(invoker.deps)) {
deps += invoker.deps
}
script = "//src/developer/ffx/build/hermetic_inputs_for_ffx.py"
inputs = [ sdk_host_tools_manifest ]
outputs = [ hermetic_inputs_path ]
args = [
"--sdk-manifest",
rebase_path(sdk_host_tools_manifest, root_build_dir),
"--output",
rebase_path(hermetic_inputs_path, root_build_dir),
]
if (defined(invoker.hermetic_inputs_file)) {
inputs += [ invoker.hermetic_inputs_file ]
args += [
"--additional-hermetic-inputs",
rebase_path(invoker.hermetic_inputs_file, root_build_dir),
]
}
if (defined(invoker.hermetic_inputs_target)) {
deps += [ invoker.hermetic_inputs_target ]
}
}
}
# Invoke the compiled_action template for the call to the ffx plugin.
#
# This uses the compiled_action() template instead of directly creating an
# action so that it will pick up the "gn_run_binary.sh" and hermetic deps
# checking that's done with the compiled_action() template.
compiled_action(target_name) {
forward_variables_from(invoker,
[
"assert_no_deps",
"data_deps",
"depfile",
"hermetic_deps",
"inputs",
"metadata",
"no_output_dir_leaks",
"outputs",
"public_deps",
"repeatable",
"sources",
"testonly",
"tool_output_name",
"visibility",
])
# Use a builddir-specific environment, not the user's own environment.
_ffx_config = [
"analytics.disabled=true",
"sdk.root=" + rebase_path(root_build_dir, root_build_dir),
"sdk.type=in-tree",
"sdk.module=host_tools.modular",
]
# Pass the ffx config at runtime. ffx checks that it has read and write access to the
# config files which causes hermetic actions error if using a global ffx config file.
args = [
"--env",
rebase_path(ffx_env_config, root_build_dir),
"--config",
string_join(",", _ffx_config),
] + invoker.args
deps = [
ffx_env_for_build_label,
sdk_host_tools_label,
]
if (defined(invoker.deps)) {
deps += invoker.deps
}
inputs += [
ffx_env_config,
sdk_host_tools_manifest,
]
if (_use_hermetic_inputs_file) {
hermetic_inputs_target = ":${hermetic_inputs_label}"
hermetic_inputs_file = hermetic_inputs_path
}
tool = "//src/developer/ffx:ffx_bin"
tool_output_name = "ffx"
}
}