# Copyright 2018 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/rust/rustc_test.gni")

# Defines a Rust binary
#
# Parameters
#
#   name
#     Name of the crate as defined in its manifest file. If not specified, it is
#     assumed to be the same as the target name.  All dashes will be replaced
#     with underscores in the binary name: <name_underscored>
#
#   version (optional)
#     Semver version of the crate as seen on crates.io.
#
#   edition (optional)
#     Edition of the Rust language to be used.
#     Options are "2015" and "2018". Defaults to "2018".
#
#   configs (optional)
#     A list of config labels applying to this target.
#
#   deps (optional)
#     List of rust_library GN targets on which this crate depends.
#     Third party crates can be included through paths like
#     "//third_party/rust_crates:<cratename>",
#
#   test_deps (optional)
#     List of rust_library GN targets on which this crate's tests depend.
#
#   non_rust_deps (optional)
#     List of non-rust_library GN targets on which this crate depends.
#
#   with_unit_tests (optional)
#     Builds unit tests associated with the binary. This will create a
#     `<name_underscored>_bin_test` test file in the output directory, and a
#     new GN target called <name>_test.
#     Equivalent to adding a `rustc_test` target with that name and the same
#     source_root.
#
#   test_environments (optional)
#     What environments unit tests, if provided, should target. Only used here
#     for linux and mac tests, with a default value of a general linux/mac
#     environment (as a function of $current_os).
#     See environments parameter //build/testing/test_spec.gni for more
#     details.
#
#   sdk_category (optional)
#     If this field is set, this rust binary will be included in SDK builds for
#     the provided category. See //build/sdk/sdk_atom.gni for available
#     categories.
#
#   source_root (optional)
#     Location of the crate root (e.g. `src/main.rs` or `src/lib.rs`).
#     This defaults to `./src/main.rs` for binaries and `./src/lib.rs` for libraries,
#     and should only be changed when absolutely necessary
#     (such as in the case of generated code).
#
#   force_opt (optional)
#     Force a particular optimization level for this target (even when building in debug mode).
#     Values include 0-3, s, or z. This does not change the optimization level of dependencies,
#     so consider combining with LTO for best results.
#
#   features (optional)
#     A list of conditional compilation flags to enable. This can be used to set features for crates
#     built in-tree which are also published to crates.io. This would be passed to rustc as
#     '--cfg feature=XXX'
#
# Example of usage:
#
#   rustc_binary("foo-bar") {
#     deps = [
#       "//garnet/public/rust/bar",
#       "//third_party/rust_crates:clap",
#       "//third_party/rust_crates:serde",
#       "//third_party/rust_crates:slab",
#     ]
#     with_unit_tests = true
#   }
#
# Example of using the outputs of the above:
#
#   package("foo") {
#     deps = [
#       ":foo-bar",
#     ]
#
#     binaries = [
#       {
#         name = "foo_bar"
#         dest = "foo-bar"
#       }
#    }
#
#   test_package("foo-bar-tests") {
#     deps = [
#       ":foo-bar_test",
#     ]
#
#    tests = [
#      {
#        name = "foo_bar_bin_test"
#      }
#    ]
#
template("rustc_binary") {
  # TODO(bwb) remove all versions from the callers
  # this is a hold-over. It's just noise right now.
  not_needed(invoker, [ "version" ])

  # TODO soft-migration
  not_needed(invoker, [ "with_lto" ])

  # if "with_unit_tests" is set to true, generate an additional rust test target
  # TODO(bwb) deprecate this. All tests should be declared independently
  if (defined(invoker.with_unit_tests) && invoker.with_unit_tests == true) {
    rustc_test("${target_name}_test") {
      name = invoker.target_name + "_bin_test"
      if (defined(invoker.name)) {
        name = invoker.name + "_bin_test"
      }

      configs = []
      configs = invoker.configs

      # rustc_test defaults to assuming the input is a binary.
      # specify the source_root here to avoid this.
      source_root = "src/main.rs"
      if (defined(invoker.source_root)) {
        source_root = invoker.source_root
      }
      forward_variables_from(invoker,
                             "*",
                             [
                               "name",
                               "source_root",
                             ])
    }
  }

  ### Shim that converts rustc_binary to a default GN executable pattern ###

  # default location for rust binaries
  source_root = "src/main.rs"
  if (defined(invoker.source_root)) {
    source_root = invoker.source_root
  }

  # use the target name unless another name is specified
  package_name = target_name
  if (defined(invoker.name)) {
    package_name = invoker.name
  }

  # built-in gn rules do not support dashes
  crate_name = string_replace(package_name, "-", "_")

  # enable these features for the target
  features = []
  if (defined(invoker.features)) {
    foreach(i, invoker.features) {
      features += [ "--cfg=feature=\"${i}\"" ]
    }
  }

  executable(target_name) {
    crate_root = source_root
    output_name = crate_name
    crate_name = crate_name
    rustflags = features

    configs = []
    configs = invoker.configs

    deps = []
    if (defined(invoker.deps)) {
      deps += invoker.deps
    }

    # TODO(bwb) remove "non_rust_deps" as a concept
    if (defined(invoker.non_rust_deps)) {
      deps += invoker.non_rust_deps
    }

    # in-tree default in 2018 edition
    if (defined(invoker.edition) && invoker.edition == "2015") {
      configs -= [ "//build/config:rust_edition_2018" ]
      configs += [ "//build/config:rust_edition_2015" ]
    }

    # some binary targets override the optimization level
    if (defined(invoker.force_opt)) {
      if (invoker.force_opt == "z") {
        configs += [ "//build/config:rust_opt_level_z" ]
      }
    }

    # pass through these variables unmodified
    forward_variables_from(invoker,
                           [
                             "testonly",
                             "visibility",
                           ])
  }
}
