# Copyright 2020 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 library that outputs a shared .wasm library file.
#
# 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. All dashes will be replaced
#     with underscores in the library name: <name_underscored>
#
#   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.
#
#   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.
#
#   non_rust_deps (optional)
#     List of non-rust_library GN targets on which this crate depends.
#
#   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).
#
#   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'
#
#   output_dir (optional)
#     Directory that the resulting library should be placed in.
#     See: `gn help output_dir`
#
# Example of usage:
#   if (current_toolchain == unknown_wasm32_toolchain) {
#     rustc_wasm_library("foo-bar") {
#       deps = [
#         "//garnet/public/rust/bar",
#         "//third_party/rust_crates:clap",
#         "//third_party/rust_crates:serde",
#         "//third_party/rust_crates:slab",
#       ]
#       sources = [ "src/lib.rs" ]
#     }
#   }
#
# Example of using the outputs of the above:
#
#   test_package("foo-bar-tests") {
#     deps = [
#       ":foo-bar_test",
#     ]
#
#    tests = [
#      {
#        name = "foo_bar_lib_test($unknown_wasm32_toolchain)"
#      }
#    ]
#
template("rustc_wasm_library") {
  assert(!(defined(invoker.output_name) && defined(invoker.name)),
         "Only one of output_name and name may be specified.")
  package_name = target_name
  if (defined(invoker.output_name)) {
    package_name = invoker.output_name
  } else if (defined(invoker.name)) {
    package_name = invoker.name
  }
  crate_name = string_replace(package_name, "-", "_")

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

  features = []
  if (defined(invoker.features)) {
    foreach(i, invoker.features) {
      features += [ "--cfg=feature=\"${i}\"" ]
    }
  }

  _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" ]
  }

  rust_library(target_name) {
    crate_root = source_root
    crate_name = crate_name
    output_name = crate_name

    assert(
        current_toolchain == unknown_wasm32_toolchain,
        "This library can only be compiled using toolchain ($unknown_wasm32_toolchain).")

    crate_type = "cdylib"

    configs = []
    configs = invoker.configs

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

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

    rustflags = features

    sources = _sources

    # 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" ]
    }

    forward_variables_from(invoker,
                           [
                             "enforce_source_listing",
                             "inputs",
                             "output_dir",
                             "testonly",
                             "visibility",
                           ])
  }
}
