# 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_args (optional)
#     List of flags to pass directly to the test binary, e.g.
#     ["--nocapture"].
#
#   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"
      }

      if (defined(invoker.test_args)) {
        args = invoker.test_args
      }

      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,
                             "*",
                             [
                               # Do not forward configs otherwise the defaults
                               # for rustc_test get clobbered.
                               "configs",
                               "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",
                           ])
  }
}
