# Copyright 2020 The Fuchsia Authors
#
# Use of this source code is governed by a MIT-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/MIT

import("//build/zircon/c_utils.gni")
import("//build/zircon/migrated_targets.gni")

_is_phys = toolchain_environment == "kernel.phys" ||
           toolchain_environment == "kernel.phys32"

# These both work together and must be presented in this order (for BFD ld).
_phys_linker_scripts = [
  "//zircon/kernel/phys/phys-end.ld",
  "//zircon/kernel/phys/phys.ld",
]

# Build an executable for the phys environment.
#
# This defines one public target whose output is the raw binary image.
# The target is used like executable(), but deps on this target from
# other environments transparently redirect to the phys environment, and
# a custom linker script is always required.  There are also implicit
# deps to supply the phys entry point code that calls the C++ PhysMain
# via the "main.h" API.
#
# Parameters
#
#   * output_extension
#     - Optional: See executable(), but defaults to "bin".
#     - Type: string
#     - Default: "bin"
#
#   * images_metadata
#     - Optional: This can override keys in the `images` metadata entry.
#     - Type: scope
#     - Default: {}
# See executable() for other parameters.
#
template("phys_executable") {
  if (!_is_phys) {
    group(target_name) {
      forward_variables_from(invoker,
                             [
                               "testonly",
                               "visibility",
                             ])
      public_deps =
          [ ":$target_name(//zircon/kernel/phys:kernel.phys_$current_cpu)" ]
    }
    not_needed(invoker, "*")
  } else {
    image_target = target_name
    executable_target = "_phys_executable.$target_name.executable"

    # This is the actual linking target.  It creates an ELF file that acts
    # as the debug file but is not used at runtime.
    executable(executable_target) {
      visibility = [ ":*" ]
      deps = []
      inputs = []
      ldflags = []
      forward_variables_from(invoker,
                             "*",
                             [
                               "images_metadata",
                               "metadata",
                               "output_dir",
                               "output_extension",
                               "target_name",
                               "visibility",
                             ])
      deps += [ "//zircon/kernel/phys:phys_executable.deps" ]
      inputs += _phys_linker_scripts
      foreach(ldscript, _phys_linker_scripts) {
        ldflags += [ "-Wl,-T," + rebase_path(ldscript, root_build_dir) ]
      }
    }

    # This is the main target of the template, a raw binary load image file.
    image_binary(image_target) {
      forward_variables_from(invoker,
                             [
                               "output_dir",
                               "output_extension",
                               "output_name",
                               "testonly",
                               "visibility",
                             ])
      if (defined(visibility)) {
        # Make sure it's visible to the environment_redirect() target above.
        visibility += [ ":$image_target" ]
      }
      deps = [ ":$executable_target" ]

      if (!defined(output_dir)) {
        output_dir = root_out_dir
      }
      if (!defined(output_name)) {
        output_name = target_name
      }
      if (!defined(output_extension)) {
        output_extension = "bin"
      }
      output_path = "$output_dir/$output_name.$output_extension"

      metadata = {
        images = []

        if (defined(invoker.metadata)) {
          forward_variables_from(invoker.metadata, "*")
        }

        # For the //:images build_api_module().
        images += [
          {
            name = target_name
            label = get_label_info(":$target_name", "label_with_toolchain")
            cpu = current_cpu

            # Botanist needs this exact value for images used as QEMU kernels.
            type = "kernel"

            # The caller can override those values and/or add others.
            if (defined(invoker.images_metadata)) {
              forward_variables_from(invoker.images_metadata, "*")
            }

            # The caller can't override `path` since that would
            # not refer to this target's output any more.
            path = rebase_path(output_path, root_build_dir)
          },
        ]
      }
    }
  }
}

if (_is_phys) {
  set_defaults("phys_executable") {
    configs = default_executable_configs
  }
}
