# 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 static library
#
# 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.
#
#   version
#     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.
#
#   test_configs (optional)
#     A list of config labels applying to the test target, in addition to those in `configs`.
#
#   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 in addition to those in
#     `deps`.
#
#   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>-bin-unit-test` test file in the output directory.
#
#   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).
#
#   output_name (optional)
#     Name of the output file.
#
# Example of usage:
#
#   rustc_staticlib("foo") {
#     deps = [
#       "//garnet/public/rust/bar",
#       "//third_party/rust_crates:clap",
#       "//third_party/rust_crates:serde",
#       "//third_party/rust_crates:slab",
#     ]
#     with_unit_tests = true
#   }
template("rustc_staticlib") {
  not_needed(invoker, [ "version" ])

  # 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") {
      not_needed(invoker, [ "public" ])
      deps = []
      forward_variables_from(invoker,
                             "*",
                             [
                               "name",
                               "test_configs",
                               "test_deps",
                             ])
      name = invoker.target_name + "_staticlib_test"
      if (defined(invoker.name)) {
        name = invoker.name + "_staticlib_test"
      }
      if (defined(invoker.test_configs)) {
        configs += invoker.test_configs
      }
      if (defined(invoker.test_deps)) {
        deps += invoker.test_deps
      }
    }
  }

  group_target = target_name

  rustc_target = "_${target_name}_rustc_static"
  if (defined(invoker.name)) {
    rustc_target = "_${invoker.name}_rustc_static"
  }
  rustc_target = string_replace(rustc_target, "-", "_")

  if (!defined(invoker.source_root)) {
    source_root = "src/lib.rs"
  } else {
    source_root = invoker.source_root
  }

  static_library(rustc_target) {
    crate_root = source_root
    output_name = rustc_target
    if (defined(invoker.non_rust_deps)) {
      data_deps = invoker.non_rust_deps
    }

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

    forward_variables_from(invoker,
                           [
                             "deps",
                             "testonly",
                             "visibility",
                           ])
  }

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

  header_target = "_${rustc_target}_staticlib_headers"

  source_set(header_target) {
    public = public_hdrs
    visibility = [ ":${group_target}" ]
    deps = []
    if (defined(invoker.non_rust_deps)) {
      # TODO(43781): This allows propagating non rust dependencies through a
      # single level of indirection, but does not handle propagating
      # dependencies through an intermediate Rust target.
      deps += invoker.non_rust_deps
    }
  }

  group(group_target) {
    forward_variables_from(invoker, [ "testonly" ])
    forward_variables_from(invoker, [ "visibility" ])
    public_deps = [
      ":$header_target",
      ":$rustc_target",
    ]
  }
}
