# 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
#
#   output_name (optional)
#   name (optional, deprecated)
#     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`.
#
#   enforce_source_listing (optional)
#     When true, enforces that any source files used by the Rust compiler are
#     listed in `sources`. Defaults to true.
#
#   sources (optional)
#     List of source files which this crate is allowed to compile. Only
#     allowed when `enforce_source_listing = true`.
#     The Rust compiler discovers source files by following `mod` declarations
#     starting at the `source_root`. The discovered source files must match this
#     list.
#
#   inputs (optional)
#     List of additional non-source files read by the compiler. These are typically
#     configuration or test-data files included in the build with the `include_str!`
#     macro. Only allowed when `enforce_source_listing = true`.
#
#   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_dir (optional)
#     Directory that the resulting library should be placed in.
#     See: `gn help output_dir`
#
# Example of usage:
#
#   rustc_staticlib("foo") {
#     deps = [
#       "//garnet/public/rust/bar",
#       "//third_party/rust_crates:argh",
#       "//third_party/rust_crates:serde",
#       "//third_party/rust_crates:slab",
#     ]
#     with_unit_tests = true
#     sources = [ "src/lib.rs" ]
#   }
template("rustc_staticlib") {
  not_needed(invoker, [ "version" ])
  assert(!(defined(invoker.output_name) && defined(invoker.name)),
         "Only one of output_name and name may be specified.")

  # 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_internal("${target_name}_test") {
      not_needed(invoker, [ "public" ])
      deps = []
      forward_variables_from(invoker,
                             "*",
                             [
                               "name",
                               "output_name",
                               "test_configs",
                               "test_deps",
                             ])
      output_name = invoker.target_name + "_staticlib_test"
      if (defined(invoker.output_name)) {
        output_name = invoker.output_name + "_staticlib_test"
      } else if (defined(invoker.name)) {
        output_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.output_name)) {
    rustc_target = "_${invoker.output_name}_rustc_static"
  } else 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
  }

  _sources = []
  _deps = []

  if (!defined(invoker.enforce_source_listing) ||
      invoker.enforce_source_listing == true) {
    # fail early when the user forgets to list sources
    assert(defined(invoker.sources), "sources must be listed")
    _sources = invoker.sources
  } else {
    not_needed(invoker, [ "sources" ])

    # This is a hack to workaround the fact that a GN `tool` invocation can't receive arbitrary input.
    # Add a sentinel value so that enforcement is skipped.
    _sources = [ "//build/rust/__SKIP_ENFORCEMENT__.rs" ]

    # Opting out of strict sources check requires that the package is present
    # in a global allow-list.
    _deps += [ "//build/rust:disable_strict_sources_check_allowlist" ]
  }

  static_library(rustc_target) {
    crate_root = source_root
    output_name = rustc_target

    deps = _deps
    if (defined(invoker.deps)) {
      deps += invoker.deps
    }

    sources = _sources

    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,
                           [
                             "inputs",
                             "output_dir",
                             "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(fxbug.dev/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",
    ]
  }
}
