# Copyright 2021 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import("//build/config/rust.gni")
import("//build/rust/rust_target.gni")

# This template allows for building Cargo crates within gn.
#
# It is intended for use with pre-existing (third party) code and
# is none too efficient. (It will stall the build pipeline whilst
# it runs build scripts to work out what flags are needed). First
# party code should directly use first-class gn targets, such as
# //build/rust/rust_static_library.gni or similar.
#
# Because it's intended for third-party code, it automatically
# defaults to //build/config/compiler:no_chromium_code which
# suppresses some warnings. If you *do* use this for first party
# code, you should remove that config and add the equivalent
# //build/config/compiler:chromium_code config.
#
# Arguments:
#  sources
#  crate_root
#  epoch
#  deps
#  aliased_deps
#  features
#  build_native_rust_unit_tests
#  edition
#  crate_name
#    All just as in rust_static_library.gni
#  library_configs/executable_configs
#    All just as in rust_target.gni
#
#  dev_deps
#    Same meaning as test_deps in rust_static_library.gni, but called
#    dev_deps to match Cargo.toml better.
#
#  build_root (optional)
#    Filename of build.rs build script.
#
#  build_deps (optional)
#    Build script dependencies
#
#  build_sources (optional)
#    List of sources for build script. Must be specified if
#    build_root is specified.
#
#  build_script_outputs (optional)
#    List of .rs files generated by the build script, if any.
#    Fine to leave undefined even if you have a build script.
#    This doesn't directly correspond to any Cargo variable,
#    but unfortunately is necessary for gn to build its dependency
#    trees automatically.
#    Many build scripts just output --cfg directives, in which case
#    no source code is generated and this can remain empty.
#
#  build_script_inputs (optional)
#    If the build script reads any files generated by build_deps,
#    as opposed to merely linking against them, add a list of such
#    files here. Again, this doesn't correspond to a Cargo variable
#    but is necessary for gn.
#
#  crate_type "bin", "proc-macro" or "rlib" (optional)
#    Whether to build an executable. The default is "rlib".
#    At present others are not supported.
#
#  cargo_pkg_authors
#  cargo_pkg_version
#  cargo_pkg_name
#  cargo_pkg_description
#    Strings as found within 'version' and similar fields within Cargo.toml.
#    Converted to environment variables passed to rustc, in case the crate
#    uses clap `crate_version!` or `crate_authors!` macros (fairly common in
#    command line tool help)

template("cargo_crate") {
  _orig_target_name = target_name

  _crate_name = _orig_target_name
  if (defined(invoker.crate_name)) {
    _crate_name = invoker.crate_name
  }

  # Executables need to have unique names. Work out a prefix.
  if (defined(invoker.build_root)) {
    _epochlabel = "vunknown"
    if (defined(invoker.epoch)) {
      _tempepoch = string_replace(invoker.epoch, ".", "_")
      _epochlabel = "v${_tempepoch}"
    }

    # This name includes the target name to ensure it's unique for each possible
    # build target in the same BUILD.gn file.
    _build_script_name =
        "${_crate_name}_${target_name}_${_epochlabel}_build_script"

    # Where the OUT_DIR will point when running the build script exe, and
    # compiling the crate library/binaries. This directory must include the
    # target name to avoid collisions between multiple GN targets that exist
    # in the same BUILD.gn.
    _build_script_env_out_dir = "$target_gen_dir/$target_name"
  }

  _rustenv = []
  if (defined(invoker.rustenv)) {
    _rustenv = invoker.rustenv
  }
  if (defined(invoker.cargo_pkg_authors)) {
    _rustenv += [ "CARGO_PKG_AUTHORS=${invoker.cargo_pkg_authors}" ]
  }
  if (defined(invoker.cargo_pkg_version)) {
    _rustenv += [ "CARGO_PKG_VERSION=${invoker.cargo_pkg_version}" ]
  }
  if (defined(invoker.cargo_pkg_name)) {
    _rustenv += [ "CARGO_PKG_NAME=${invoker.cargo_pkg_name}" ]
  }
  if (defined(invoker.cargo_pkg_description)) {
    _rustenv += [ "CARGO_PKG_DESCRIPTION=${invoker.cargo_pkg_description}" ]
  }

  # The main target, either a Rust source set or an executable.
  rust_target(target_name) {
    forward_variables_from(invoker,
                           "*",
                           TESTONLY_AND_VISIBILITY + [
                                 "build_root",
                                 "build_deps",
                                 "build_sources",
                                 "build_script_inputs",
                                 "build_script_outputs",
                                 "unit_test_target",
                                 "target_type",
                                 "configs",
                                 "rustenv",
                               ])
    forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)

    # Work out what we're building.
    crate_type = "rlib"
    if (defined(invoker.crate_type)) {
      crate_type = invoker.crate_type
    }

    # TODO(crbug.com/1422745): don't default to true. This requires changes to
    # third_party.toml and gnrt when generating third-party build targets.
    allow_unsafe = true

    if (!defined(rustflags)) {
      rustflags = []
    }
    rustenv = _rustenv
    if (crate_type == "bin") {
      target_type = "executable"
      assert(!defined(invoker.epoch))
    } else if (crate_type == "proc-macro") {
      target_type = "rust_proc_macro"
    } else {
      assert(crate_type == "rlib")
      target_type = "rust_library"
    }

    if (!defined(build_native_rust_unit_tests)) {
      build_native_rust_unit_tests = true
    }

    # The unit tests for each target, if generated, should be unique as well.
    # a) It needs to be unique even if multiple build targets have the same
    #    `crate_name`, but different target names.
    # b) It needs to be unique even if multiple build targets have the same
    #    `crate_name` and target name, but different epochs.
    _unit_test_unique_target_name = ""
    if (_crate_name != _orig_target_name) {
      _unit_test_unique_target_name = "${_orig_target_name}_"
    }
    _unit_test_unique_epoch = ""
    if (defined(invoker.epoch)) {
      _epoch_str = string_replace(invoker.epoch, ".", "_")
      _unit_test_unique_epoch = "v${_epoch_str}_"
    }
    if (defined(output_dir) && output_dir != "") {
      unit_test_output_dir = output_dir
    }
    unit_test_target = "${_unit_test_unique_target_name}${_crate_name}_${_unit_test_unique_epoch}unittests"

    if ((!defined(output_dir) || output_dir == "") && crate_type == "rlib") {
      # Cargo crate rlibs can be compiled differently for tests, and must not
      # collide with the production outputs. This does *not* override the
      # unit_test_output_dir, which is set above, as that target is not an rlib.
      output_dir = "$target_out_dir/$_orig_target_name"
    }

    if (defined(invoker.build_root)) {
      # Uh-oh, we have a build script
      if (!defined(deps)) {
        deps = []
      }
      if (!defined(sources)) {
        sources = []
      }
      if (defined(invoker.dev_deps)) {
        test_deps = invoker.dev_deps
      }

      # This... is a bit weird. We generate a file called cargo_flags.rs which
      # does not actually contain Rust code, but instead some flags to add
      # to the rustc command line. We need it to end in a .rs extension so that
      # we can include it in the 'sources' line and thus have dependency
      # calculation done correctly. data_deps won't work because targets don't
      # require them to be present until runtime.
      flags_file = "$_build_script_env_out_dir/cargo_flags.rs"
      rustflags += [ "@" + rebase_path(flags_file, root_build_dir) ]
      sources += [ flags_file ]
      if (defined(invoker.build_script_outputs)) {
        # Build scripts may output arbitrary files. They are usually included in
        # the main Rust target using include! or include_str! and therefore the
        # filename may be .rs or may be arbitrary. We want to educate ninja
        # about the dependency either way.
        foreach(extra_source,
                filter_include(invoker.build_script_outputs, [ "*.rs" ])) {
          sources += [ "$_build_script_env_out_dir/$extra_source" ]
        }
        inputs = []
        foreach(extra_source,
                filter_exclude(invoker.build_script_outputs, [ "*.rs" ])) {
          inputs += [ "$_build_script_env_out_dir/$extra_source" ]
        }
      }
      deps += [ ":${_build_script_name}_output" ]
    }
  }

  if (defined(invoker.build_root)) {
    # Extra targets required to make build script work
    action("${_build_script_name}_output") {
      script = rebase_path("//build/rust/run_build_script.py")
      build_script_target =
          ":${_build_script_name}($host_toolchain_no_sanitizers)"
      deps = [ build_script_target ]

      # The build script output is always in the name-specific output dir. It
      # may be built with a different toolchain when cross-compiling (the host
      # toolchain) so we must find the path relative to that.
      _build_script_target_out_dir =
          get_label_info(build_script_target, "target_out_dir")
      _build_script_exe =
          "$_build_script_target_out_dir/$_orig_target_name/$_build_script_name"
      if (is_win) {
        _build_script_exe = "${_build_script_exe}.exe"
      }

      _flags_file = "$_build_script_env_out_dir/cargo_flags.rs"

      inputs = [ _build_script_exe ]
      outputs = [ _flags_file ]
      args = [
        "--build-script",
        rebase_path(_build_script_exe, root_build_dir),
        "--output",
        rebase_path(_flags_file, root_build_dir),
        "--rust-prefix",
        rebase_path("${rust_sysroot}/bin"),
        "--out-dir",
        rebase_path(_build_script_env_out_dir, root_build_dir),
        "--src-dir",
        rebase_path(get_path_info(invoker.build_root, "dir"), root_build_dir),
      ]
      if (defined(rust_abi_target) && rust_abi_target != "") {
        args += [
          "--target",
          rust_abi_target,
        ]
      }
      if (defined(invoker.features)) {
        args += [ "--features" ]
        args += invoker.features
      }
      if (defined(invoker.build_script_outputs)) {
        args += [ "--generated-files" ]
        args += invoker.build_script_outputs
        foreach(generated_file, invoker.build_script_outputs) {
          outputs += [ "$_build_script_env_out_dir/$generated_file" ]
        }
      }
      if (_rustenv != []) {
        args += [ "--env" ]
        args += _rustenv
      }
      if (defined(invoker.build_script_inputs)) {
        inputs += invoker.build_script_inputs
      }
    }

    if (current_toolchain == host_toolchain_no_sanitizers) {
      rust_target(_build_script_name) {
        target_type = "executable"
        sources = invoker.build_sources
        crate_root = invoker.build_root
        if (defined(invoker.build_deps)) {
          deps = invoker.build_deps
        }

        # An rlib's build script may be built differently for tests and for
        # production, so they must be in a name specific to the GN target. The
        # ${_build_script_name}_output target looks for the exe in this
        # location.
        output_dir = "$target_out_dir/$_orig_target_name"
        rustenv = _rustenv
        forward_variables_from(invoker,
                               [
                                 "features",
                                 "edition",
                                 "rustflags",
                               ])
        executable_configs -= [ "//build/config/compiler:chromium_code" ]
        executable_configs += [ "//build/config/compiler:no_chromium_code" ]
      }
    } else {
      not_needed(invoker,
                 [
                   "build_sources",
                   "build_deps",
                   "build_root",
                   "build_script_inputs",
                   "build_script_outputs",
                 ])
    }
  } else {
    not_needed([
                 "_name_specific_output_dir",
                 "_orig_target_name",
               ])
  }
}

set_defaults("cargo_crate") {
  library_configs = default_compiler_configs
  executable_configs = default_executable_configs
}
