# 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/config/fuchsia/rust_target_api_level.gni")
import("//build/testing/host_test_data.gni")
import("config.gni")

group("disable_strict_sources_check_allowlist") {
  #  ________  _________  ________  ________
  # |\   ____\|\___   ___\\   __  \|\   __  \
  # \ \  \___|\|___ \  \_\ \  \|\  \ \  \|\  \
  #  \ \_____  \   \ \  \ \ \  \\\  \ \   ____\
  #   \|____|\  \   \ \  \ \ \  \\\  \ \  \___|
  #     ____\_\  \   \ \__\ \ \_______\ \__\
  #    |\_________\   \|__|  \|_______|\|__|
  #    \|_________|
  # This is an allowlist of packages that do not enforce that the source files
  # are listed in `source`. This is only intended to be used as a temporary
  # allowlist during soft migrations.
  #
  # All file dependencies of the targets in this list should be covered by the
  # paths in the skipAnalysisAllowlist in
  # //tools/integration/fint/should_build.go.
  visibility = []
}

# NOTE: This target is used by "fx set --cargo-toml-gen ..." which
# will do the following:
#
#  1) Ensure that "fx gen" (and "fx build") will pass `--ide-json`
#     to `gn gen`, which generates an up-to-date
#     `$root_build_dir/project.json` file, used here as input.
#
#  2) Add this target to the host_labels list to ensure its action script is
#     run by "fx build".
#
# For more details, see docs/development/language/rust/README.md
#
# Notes on transitioning this target from `base_package_labels` to `host_tools`:
#
#  1) Existing `args.gn` files created by `fx set --cargo-toml-gen` will have
#     added the target to the `base_package_labels` list.  This list assumes the
#     default toolchain.
#  2) `base_package_labels` currently feeds into
#       - `//:developer_base_package_labels`
#  3) New `args.gn` files created by `fx set --cargo-toml-gen` will instead use
#     the `host_labels` arg (which assumes the host toolchain).  That list is
#     currently being used with the `//:host` group, but it's being split into
#       - `//build/input/product:host_labels`
#       - `//build/input/board:host_labels`
#       - `//:host` will remain for developer-specified host tools to include in
#         the build.
#   4) Developers _may_ have added `//build/rust:cargo_toml_gen` to either of
#      following:
#        - `cache_package_labels` (`//:developer_cache_packages`)
#        - `universe_package_labels` (`//:developer_universe_packages`)
#      and those are being split as well, and so the following groups will need
#      to be added to visibility:
#        - `//:developer_cache_packages`
#        - `//:developer_universe_packages`
#
if (current_toolchain != default_toolchain) {
  # This is a redirect from the host toolchain to the default toolchain, as it
  # is added to the host_labels group, not the product definition inputs.
  group("cargo_toml_gen") {
    public_deps = [ ":cargo_toml_gen($default_toolchain)" ]
    visibility = [
      # This is the supported group for developers to add tools to, going
      # forward, and the group used by `fx set --cargo-toml-gen`.
      ":tests",
      "//:developer_host_tools",
      "//:host",
    ]
  }
} else {
  gn_desc_label = "//tools/gn_desc:gn_desc.json"
  gn_desc_out = "$root_build_dir/gn_desc.json"

  action("cargo_toml_gen") {
    # Nothing in-tree should depend on Cargo files.
    visibility = [
      # The only expected use of this target, going forward (the above group)
      ":cargo_toml_gen",
      ":tests",

      # `fx set ... --cargo-toml-gen` previously used the `base_package_labels`
      # GN arg, which feeds into `//:developer_base_packages`.  This is here for
      # providing a transition for developers' existing `args.gn` files.
      "//:developer_base_packages",

      # Developers may have used these as well (also deprecated for this
      # target).
      "//:developer_cache_packages",
      "//:developer_universe_packages",

      # via --with-host or `host_labels`, and specifying the fuchsia toolchain:
      "//:host",
    ]
    script = "//scripts/generate_cargo.py"
    sources = []
    inputs = [
      gn_desc_out,
      "//third_party/rust_crates/Cargo.toml",
    ]
    hermetic_deps = false

    outputs = [ "$root_build_dir/cargo/generate_cargo.stamp" ]
    args = [
      rebase_path(gn_desc_out, root_build_dir),
      "--root_build_dir",
      ".",
      "--fuchsia_dir",
      rebase_path("//", root_build_dir),
    ]
    deps = [ gn_desc_label ]
  }
}

# Generated file containing flags to pass to each invocation of `rustc` (or
# similar tools). Pass it to rustc by specifying `@rust_api_level_cfg_flags.txt`
# in the command line.
generated_file("api_level_cfg_flags") {
  outputs = [ "$root_build_dir/rust_api_level_cfg_flags.txt" ]
  output_conversion = "list lines"
  contents = []

  foreach(level, rust_lesser_or_equal_fuchsia_api_levels) {
    contents += [ "--cfg=fuchsia_api_level_at_least=\"${level}\"" ]
  }
  foreach(level, rust_greater_fuchsia_api_levels) {
    contents += [ "--cfg=fuchsia_api_level_less_than=\"${level}\"" ]
  }
}

# Multiple integration tests rely on having a Rust toolchain available on the host test
# runner, and host_test_data does not appear to support multiple definitions of the
# same output path in the same build, so we provide a central target here to be used
# by integration tests that need cargo or rustc.
if (is_host) {
  action("make_toolchain_host_binaries") {
    script = "//build/copy_tree.py"

    _stamp = "$target_gen_dir/$target_name.stamp"
    _depfile = "$target_out_dir/$target_name.d"
    args = [
      rebased_rustc_prefix,
      out_rustc_prefix,
      rebase_path(_stamp, root_build_dir),
      "--depfile",
      rebase_path(_depfile, root_build_dir),
    ]
    outputs = [ _stamp ]
    depfile = _depfile
  }

  # This target adds llvm-profdata for the rust toolchain to tool_paths.json.
  # Since this tool has the same name as the clang counterpart, we need to
  # append -rust to the name to differentiate them. It also needs to be built
  # in the host_toolchain in order for the tool path to be correct.
  group("tool_paths.llvm-profdata-rust") {
    visibility = [ "//:tool_paths" ]
    deps = [ ":make_toolchain_host_binaries" ]
    metadata = {
      tool_paths = [
        {
          cpu = host_cpu
          label = get_label_info(":$target_name", "label_with_toolchain")
          name = "llvm-profdata-rust"
          os = host_os
          path = rebase_path("$rustc_prefix/bin/llvm-profdata", root_build_dir)
        },
      ]
    }
  }

  host_test_data("prebuilt_toolchain_host_test_data") {
    deps = [ ":make_toolchain_host_binaries" ]
    sources = [ "$root_build_dir/$out_rustc_prefix" ]
  }
}

if (current_toolchain == host_toolchain) {
  # Make a shim called rust-analyzer that runs the actual rust-analyzer binary.
  # fx will link to that from out/, giving a predictable location to run
  # rust-analyzer from regardless of the user's host, and taking into account
  # custom toolchains.
  #
  # We want this to be available as soon as gen is done, so we don't wait for
  # the build itself.  The only reason this needs to be done as a script instead
  # of write_file is because the shim needs the executable bit set.
  rust_analyzer_path = "${rustc_prefix}/bin/rust-analyzer"
  if (rebase_path(rustc_prefix, "") == rustc_prefix) {
    # rustc_prefix is already a system-absolute path; leave it alone.
  } else {
    # Otherwise, make it relative to the build dir.
    rust_analyzer_path = rebase_path(rust_analyzer_path, root_build_dir)
  }
  exec_script("make_tool_shim.sh", [ rust_analyzer_path ])
}

group("tests") {
  testonly = true
  deps = [
    ":cargo_toml_gen",
    "docs/rustdoc-index",
    "docs/rustdoc-index:rustdoc-index(//build/toolchain:host_x64)",
    "tests",
  ]
}
