# Copyright 2016 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/config/clang/clang.gni")

# This file introduces two related templates that act like action and
# action_foreach but instead of running a script, it will compile a given tool
# in the host toolchain and run that (either once or over the list of inputs,
# depending on the variant).
#
# Parameters
#
#   tool (required)
#       [label] Label of the tool to run. This should be an executable, and
#       this label should not include a toolchain (anything in parens). The
#       host compile of this tool will be used.
#
#   tool_output_name (optional)
#       [string] The `output_name` in the `executable()` for `tool`.
#       This default's to the `tool` target's name.
#
#   outputs (required)
#       [list of files] Like the outputs of action (if using "compiled_action",
#       this would be just the list of outputs), or action_foreach (if using
#       "compiled_action_foreach", this would contain source expansions mapping
#       input to output files).
#
#   args (required)
#       [list of strings] Same meaning as action/action_foreach.
#
#   inputs (optional)
#   sources (optional)
#       Files the binary 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
#       binary itself changes.
#
#   args (all optional)
#   depfile
#   deps
#   public_deps
#   testonly
#   visibility
#       Same meaning as action/action_foreach.
#
# Example of usage:
#
#   compiled_action("run_my_tool") {
#     tool = "//tools/something:mytool"
#     outputs = [
#       "$target_gen_dir/mysource.cc",
#       "$target_gen_dir/mysource.h",
#     ]
#
#     # The tool takes this input.
#     sources = [ "my_input_file.idl" ]
#
#     # In this case, the tool takes as arguments the input file and the output
#     # build dir (both relative to the "cd" that the script will be run in)
#     # and will produce the output files listed above.
#     args = [
#       rebase_path("my_input_file.idl", root_build_dir),
#       "--output-dir", rebase_path(target_gen_dir, root_build_dir),
#     ]
#   }
#
# You would typically declare your tool like this:
#   if (host_toolchain == current_toolchain) {
#     executable("mytool") {
#       ...
#     }
#   }
#
# The if statement around the executable is optional. That says "I only care
# about this target in the host toolchain". Usually this is what you want, and
# saves unnecessarily compiling your tool for the target platform. But if you
# need a target build of your tool as well, just leave off the if statement.
template("_compiled_action_target") {
  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")

  target(invoker._target_type, target_name) {
    forward_variables_from(invoker,
                           [
                             "all_outputs_fresh",
                             "assert_no_deps",
                             "data_deps",
                             "depfile",
                             "deps",
                             "hermetic_deps",
                             "hermetic_inputs_file",
                             "hermetic_inputs_target",
                             "no_output_dir_leaks",
                             "repeatable",
                             "inputs",
                             "metadata",
                             "outputs",
                             "public_deps",
                             "sources",
                             "testonly",
                             "tool_output_name",
                             "visibility",
                           ])
    if (!defined(deps)) {
      deps = []
    }
    if (!defined(inputs)) {
      inputs = []
    }

    script = "//build/gn_run_binary.sh"

    # Construct the host toolchain version of the tool.
    host_tool = "${invoker.tool}($host_toolchain)"

    # Get the path to the executable.
    if (!defined(tool_output_name)) {
      tool_output_name = get_label_info(host_tool, "name")
    }
    tool_out_dir = get_label_info(host_tool, "root_out_dir")
    host_executable = "$tool_out_dir/$tool_output_name"

    # Add the executable itself as an input.
    inputs += [ host_executable ]

    deps += [ host_tool ]

    # The script takes as arguments Clang bin directory (for passing
    # llvm-symbolizer to runtimes), the binary to run, and then the
    # arguments to pass it.
    args = [
             rebased_clang_prefix,
             rebase_path(host_executable, root_build_dir),
           ] + invoker.args
  }
}

# See _compiled_action_target().
template("compiled_action") {
  _compiled_action_target(target_name) {
    _target_type = "action"
    forward_variables_from(invoker, [ "visibility" ])
    forward_variables_from(invoker, "*", [ "visibility" ])
  }
}

# See _compiled_action_target().
template("compiled_action_foreach") {
  _compiled_action_target(target_name) {
    _target_type = "action_foreach"
    forward_variables_from(invoker, [ "visibility" ])
    forward_variables_from(invoker, "*", [ "visibility" ])
  }
}
