# 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/toolchain/rbe.gni")
import("//build/toolchain/restat.gni")

# Defines a Rust procedural macro
#
# 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 (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.
#
#   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>".
#
#   non_rust_deps (optional)
#     List of non-rust_library GN targets on which this crate depends.
#     Obsolete. Please use deps instead.
#
#   data_deps (optional)
#     List of GN targets that are only needed at runtime.
#
#   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 macro should be placed in.
#     See: `gn help output_dir`
#
#   disable_rbe (optional)
#     Set to true to force this target to build locally, overriding the global `enable_rbe`.
#
# Example of usage:
#
#   rustc_macro("foo") {
#     deps = [
#       "//garnet/public/rust/bar",
#       "//third_party/rust_crates:serde",
#       "//third_party/rust_crates:slab",
#     ]
#     sources = [ "src/lib.rs" ]
#   }
template("rustc_macro") {
  # Compiling procedural macros is... a bit awkward.
  #
  # Even though they're provided to crates that use them as if they were normal
  # external crates, they're actually '.so'/'.dylib's that are compiled for the host machine
  # and then linked into the compiler, so they and all their dependencies should
  # be built for the host target.
  #
  # Once this is done, the resulting artifacts are copied into the Fuchsia target
  # directories to act as if they had been built for Fuchsia. In order to avoid
  # conflicts, the outputs of the original (host) artifact are built with a
  # `_proc_macro` suffix added onto the end, which is removed when they're copied
  # into the final target directory.
  forward_variables_from(invoker, [ "visibility" ])

  proc_macro_target = "${target_name}_proc_macro"

  assert(!(defined(invoker.output_name) && defined(invoker.name)),
         "Only one of output_name and name may be specified.")

  # The 'is_host' var is true in situations that we don't want, such as
  # sanitizers and cross-compiling for _other_ hosts.
  #
  # We only want this to be run in _this_ machine's host_toolchain, and then
  # only in its base variant.

  # This confirms that this is running on _this_ machine's host_toolchain.
  in_host_compiler_toolchain = current_toolchain == host_toolchain

  # This confirms that it's also running on the base variant of the host_toolchain.
  in_host_base_variant =
      in_host_compiler_toolchain && current_toolchain == toolchain_variant.base

  # The actual host-target build of the proc macro crate.
  if (in_host_base_variant) {
    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 = "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" ]
    }

    rust_proc_macro(proc_macro_target) {
      configs = []
      configs = invoker.configs

      not_needed(invoker,
                 [
                   "version",
                   "non_rust_deps",
                   "force_opt",
                 ])
      crate_root = source_root
      output_name = crate_name

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

      # TODO(https://fxbug.dev/43781) remove "non_rust_deps"
      if (defined(invoker.non_rust_deps)) {
        deps += invoker.non_rust_deps
      }

      sources = _sources

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

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

      inputs = []
      if (defined(invoker.inputs)) {
        inputs = invoker.inputs
      }
      _use_rbe = enable_rbe
      if (defined(invoker.disable_rbe) && invoker.disable_rbe) {
        _use_rbe = false
      }
      if (_use_rbe) {
        # Depend on Rust/RBE scripts and tools
        inputs += rust_rbe_deps
      }
    }
  } else {
    not_needed(invoker, "*")
  }

  # proc_macros are loadable modules that are used by the rustc compiler itself,
  # and as such, need to be compiled in the _base_ (non-sanitizer) variant of
  # host toolchain.
  #
  # The following creates a set of dependencies through groups that
  # link from the current toolchain to the base toolchain of the host_toolchain
  # variant:
  #
  # target_name($current_toolchain)   // omitted if already in host.
  #  |- target_name($host_toolchain)
  #      |- proc_macro_target($host_toolchain_base)

  # If not in _this_ machine's host_toolchain, switch to it.
  if (!in_host_compiler_toolchain) {
    group(target_name) {
      public_deps = [ ":${target_name}($host_toolchain)" ]
    }

    # the proc_macro_target isn't used.
    not_needed([ "proc_macro_target" ])
  } else {
    # now in the proper host_toolchain, have the group depend on the base of the host
    # toolchain's variant
    group(target_name) {
      public_deps = [ ":${proc_macro_target}(${toolchain_variant.base})" ]
    }
  }
}
