# Copyright 2017 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")
import("//build/config/sysroot.gni")
import("//build/sdk/sdk_atom.gni")

# A template for an action that builds a Go binary. Users should instead use the
# go_binary or go_test rules.
#
# Every go_build target with any go_dependencies declared has a new GOPATH
# constructed. The scopes contained within go_dependencies define symlinks that
# will be added to the GOPATH.
#
# Example:
# go_build("mypackage") {
#   gopackage = "fuchsia.googlesource.com/mypackage"
#   go_dependencies = [
#     {
#       package = "fuchsia.googlesource.com/mypackage"
#     },
#     {
#       source = "//third_party/golang/crypto"
#       package = "golang.org/x/crypto"
#     }
#   ]
# }
#
# The above go_dependencies declaration is most typical, it creates a GOPATH
# entry for "fuchsia.googlesource.com/mypackage" that points to the directory
# containing the caller BUILD.gn. If source is ever omitted, it is assumed to be
# the directory of the containing action.
#
# At minimum there should be a go_dependencies declaration for the package to
# be built.
#
# Parameters
#
#   sdk_category (optional)
#     Publication level of the library in SDKs.
#     See //build/sdk/sdk_atom.gni.

template("go_build") {
  assert(defined(invoker.gopackage),
         "gopackage must be defined for $target_name")

  main_target_name = target_name

  output_name = target_name
  if (defined(invoker.output_name)) {
    output_name = invoker.output_name
  }
  output_path = "${root_out_dir}/${output_name}"

  action(main_target_name) {
    forward_variables_from(invoker, [ "deps" ])

    if (!defined(deps)) {
      deps = []
    }

    use_strip = is_fuchsia

    outputs = [
      output_path,
    ]

    if (use_strip) {
      unstripped_output_path = "${root_out_dir}/exe.unstripped/${output_name}"
      outputs += [ unstripped_output_path ]
    }

    script = "//build/go/build.py"
    depfile = "${output_path}.d"

    sources = [
      "//build/go/gen_libraries.py",
    ]

    # The same Go toolchain is used for host and target.
    # It lives in $root_out_dir/goroot for the target's value of root_out_dir.
    # TODO(dje): Move go toolchain to host root_out_dir. It runs on the host.
    target_root_out_dir = get_label_info("//third_party/go:go_runtime($target_toolchain)", "root_out_dir")
    go_root = rebase_path("$target_root_out_dir/goroot")

    deps += [ "//third_party/go:go_runtime" ]

    if (is_fuchsia) {
      deps += [
        "//garnet/public/sdk:zircon_sysroot_export",
        "//zircon/public/lib/fdio",
        "//zircon/public/lib/launchpad",
      ]
    }

    go_dependencies = []
    if (defined(invoker.go_dependencies)) {
      go_dependencies = invoker.go_dependencies
    }

    zircon_sysroot = sysroot
    if (is_fuchsia) {
      zircon_sysroot = rebase_path("$root_out_dir/sdks/zircon_sysroot/sysroot")
    }

    args = [
      "--fuchsia-root",
      rebase_path("//."),
      "--root-out-dir",
      rebase_path(root_out_dir, root_build_dir),
      "--zircon-sysroot",
      zircon_sysroot,
      "--depfile",
      rebase_path(depfile),
      "--current-cpu",
      current_cpu,
      "--current-os",
      current_os,
      "--go-root",
      go_root,
      "--binname",
      output_name,
      "--toolchain-prefix",
      rebase_path(clang_prefix, "", root_build_dir),
    ]

    if (use_strip) {
      args += [
        "--unstripped-binname",
        "exe.unstripped/${output_name}",
      ]
    }

    if (defined(invoker.test) && invoker.test) {
      args += [ "--is-test=true" ]
    }

    if (defined(invoker.extra_dependencies)) {
      deps += invoker.extra_dependencies
      args += [ "--go-dep-files" ]
      foreach(dep, invoker.extra_dependencies) {
        gen_dir = get_label_info(dep, "target_gen_dir")
        name = get_label_info(dep, "name")
        args += [ rebase_path("$gen_dir/$name.go_deps") ]
      }
    }

    foreach(dep, go_dependencies) {
      if (!defined(dep.source)) {
        dep.source = "."
      }
      source = dep.source
      args += [
        "--go-dependency",
        dep.package + "=" + rebase_path(source),
      ]
    }

    args += [
      "--package",
      invoker.gopackage,
    ]
  }

  if (defined(invoker.sdk_category) && invoker.sdk_category != "excluded") {
    sdk_atom("${target_name}_sdk") {
      domain = "exe"
      name = output_name

      category = invoker.sdk_category

      if (is_fuchsia) {
        tags = [ "arch:target" ]
      } else {
        tags = [ "arch:host" ]
      }

      files = [
        {
          source = output_path
          dest = output_name
        },
      ]

      non_sdk_deps = [ ":$main_target_name" ]
    }
  }
}
