# 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",
]

phys_toolchain = "//zircon/kernel/phys:kernel.phys_$current_cpu"

# 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($phys_toolchain)" ]
    }
    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) ]
      }
      if (is_gcc) {
        ldflags += [ "-Wl,--no-warn-rwx-segments" ]
      }
    }

    # 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
  }
}
