# 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/config/clang/clang.gni")
import("//build/rust/config.gni")
import("//build/toolchain/zircon/clang.gni")

# NOTE: Keep in sync with //zircon/public/gn/toolchain/toolchain_runtime_deps.gni
# until build unification completes.

# ## runtime.json
#
# Each toolchain (i.e. Clang or rustc) provides a "runtime.json" file
# in its top-level lib/ sub-directory.
#
# This file is provided by the toolchain to describe the runtime
# dependencies implied by linking a binary based on --target and other
# compiler switches.  The file contains a JSON array of objects that map to
# the following GN schema.  Each entry matches a single compilation mode
# and yields all the runtime dependencies implied by that mode.
#
# Type: list(scope)
#
# * target
#   - Required: --target tuple a la `${toolchain.target_tuple}`.
#   - Type: string
#
# * cflags
#   - Optional: List of compilation flags that select this mode,
#     e.g. `"-fsanitizer=..."` and the like.
#     If not specified, cflags are ignored during selection.
#   - Type: list(string)
#
# * ldflags
#   - Optional: Link-time flags that select this mode.
#     This is usually either `[ "-static-libstdc++" ]` or `[]`.
#     If not specified, ldflags are ignored during selection.
#   - Type: list(string)
#
# * runtime
#   - Required: List of runtime files needed by binaries in this mode.
#   - Type: list(scope)
#
#     * name
#       - Optional: A stable name for the library to use when publishing a
#         zx_manifest. If omitted, soname is used.
#       - Type: string
#
#     * soname
#       - Required: `DT_SONAME` string in the ELF shared library.
#       - Type: string
#
#     * dist
#       - Required: File to load to satisfy $soname `DT_NEEDED` entries.
#       - Type: path relative to `${toolchain_spec.lib_dir}`
#
#     * debug
#       - Optional: Unstripped or separate debug file matching $dist.
#       - Type: path relative to `${toolchain_spec.lib_dir}`
#
#     * breakpad
#       - Required if `debug` is present and `toolchain.use_breakpad` is true:
#         Path to breakpad .sym file.
#       - Type: path relative to `${toolchain_spec.lib_dir}`
#
_clang_lib_dir = rebase_path("$clang_prefix/../lib", ".", root_build_dir)
_clang_runtime_file = "$_clang_lib_dir/runtime.json"
_clang_runtime = read_file(_clang_runtime_file, "json")

# As a special case, on Fuchsia and for ASan builds, libclang_rt.asan.so depends
# on libc++abi.so even if the generated machine code does not (i.e. when
# -static-libstdc++ is also used). libc++abi.so depends on libwundind.so itself.
# Linking issues appear because these dependencies are not listed properly, so
# work-around this by patching _clang_runtime for Asan.

# First, record a map of runtimes for Fuchsia for Asan without -static-libstdc++
_asan_runtimes_map = []
foreach(entry, _clang_runtime) {
  if (entry.cflags == [ "-fsanitize=address" ] && entry.ldflags == []) {
    _targets = []
    _targets = entry.target
    _target = _targets[0]
    if (string_replace(_target, "-fuchsia", "") != _target) {
      _asan_runtimes_map += [
        {
          target = _target
          runtime = entry.runtime
        },
      ]
    }
  }
}

# Then patch up the entry of Asan with -static-libstdc++ to be the same.
_new_clang_runtime = []
foreach(entry, _clang_runtime) {
  _new_clang_runtime += [
    {
      forward_variables_from(entry, "*")
      if (cflags == [ "-fsanitize=address" ] &&
          ldflags == [ "-static-libstdc++" ]) {
        _target = target[0]
        if (string_replace(_target, "-fuchsia", "") != _target) {
          foreach(_asan_entry, _asan_runtimes_map) {
            if (_asan_entry.target == _target) {
              runtime = []
              runtime = _asan_entry.runtime
            }
          }
        }
      }
    },
  ]
}

# Do the same for the 'libclang_rt.ubsan_standalone.so' which also depends
# on libc++abi.so.
_clang_runtime = []
_clang_runtime = _new_clang_runtime

_ubsan_runtimes_map = []
foreach(entry, _clang_runtime) {
  if (entry.cflags == [ "-fsanitize=undefined" ] && entry.ldflags == []) {
    _targets = []
    _targets = entry.target
    _target = _targets[0]
    if (string_replace(_target, "-fuchsia", "") != _target) {
      _ubsan_runtimes_map += [
        {
          target = _target
          runtime = entry.runtime
        },
      ]
    }
  }
}

_new_clang_runtime = []
foreach(entry, _clang_runtime) {
  _new_clang_runtime += [
    {
      forward_variables_from(entry, "*")
      if (cflags == [ "-fsanitize=undefined" ] &&
          ldflags == [ "-static-libstdc++" ]) {
        _target = target[0]
        if (string_replace(_target, "-fuchsia", "") != _target) {
          foreach(_ubsan_entry, _ubsan_runtimes_map) {
            if (_ubsan_entry.target == _target) {
              runtime = []
              runtime = _ubsan_entry.runtime
            }
          }
        }
      }
    },
  ]
}

_clang_runtime = []
_clang_runtime = _new_clang_runtime

_rustc_lib_dir = rebase_path("$rustc_prefix/../lib", ".", root_build_dir)
_rustc_runtime_file = "$_rustc_lib_dir/runtime.json"
_rustc_runtime = read_file(_rustc_runtime_file, "json")

# ## Toolchain specifications
#
# Each <runtime>_toolchain_spec below is a scope with the following keys:
#
#     * runtime
#       - Required: The contents of the runtimes manifest (runtime.json).
#         See above for the schema.
#       - Type: scope
#
#     * runtime_file
#       - Required: The path to runtime.json from which `runtime` was read.
#       - Type: file
#
#     * flag_vars
#       - Required: The set of flags to match on in the runtimes manifest.
#       - Example: `[ "cflags", "ldflags" ]`
#       - Type: list(string)
#
#     * lib_dir
#       - Required: The base path for all libraries in runtime.json.
#       - Type: string
#
#     * version_string
#       - Required: A string that changes every time the toolchain is updated,
#         so we know when to force a recompile.
#       - Type: string
#
#     * version_description
#       - Required: Something that can lead a human to find the specific toolchain,
#         such as a source repository URL and revision identifier. If not available,
#         supply an empty string.
#       - Type: string
#
# Clang toolchain spec for use with toolchain_runtime_deps().
clang_toolchain_spec = {
  runtime = _clang_runtime
  runtime_file = _clang_runtime_file
  lib_dir = _clang_lib_dir
  version_string = clang_version_string
  version_description = clang_version_description
  flag_vars = [
    "cflags",
    "ldflags",
  ]
}

# Rust toolchain spec for use with toolchain_runtime_deps().
rustc_toolchain_spec = {
  runtime = _rustc_runtime
  runtime_file = _rustc_runtime_file
  lib_dir = _rustc_lib_dir
  version_string = rustc_version_string
  version_description = rustc_version_description
  flag_vars = [ "rustflags" ]
}

# Provide deps required by toolchain-provided runtime libraries.
#
# Every linking target, such as executable(), shared_library(), or
# loadable_module(), needs this in deps to represent the link-time and
# runtime dependencies of support code the compiler links in implicitly.
# The parameters indicate the compilation mode in terms of the link-time
# and compile-time flags used.  These must exactly match lists supplied by
# the toolchain in $clang_runtime to select for things like instrumentation
# and shared vs static linking of the standard C++ library.
#
# ## Parameters
#
# * toolchain_spec
#   - Required: Path information about the compiler runtimes.
#   - Type: scope with the following:
#
# * <flag variables>
#   - Required: Flags to match in the runtimes manifest. Should have a value for
#     every flag in toolchain_spec.flag_vars.
#   - Example: `cflags = [] ldflags = [ "-static-libstdc++" ]`
#   - Type: list(string)
#
# * libraries
#   - Optional: List of library names to include in this target. If not specific
#     all libraries matching the flag variables in the toolchain spec for the
#     current variant will be added.
#   - Type: list(string)
#
template("toolchain_runtime_deps") {
  not_needed(invoker, [ "libraries" ])
  group(target_name) {
    forward_variables_from(invoker,
                           [
                             "testonly",
                             "visibility",
                           ])

    toolchain_spec = invoker.toolchain_spec

    # This information comes out the same in the main and the shlib
    # toolchains.  But we don't want two copies to appear in the metadata
    # collection, so we always redirect to the shlib toolchain (when there
    # is one).  Note that multiple toolchains (variants that aren't that
    # different, e.g. uninstrumented variants) may produce identical
    # manifest entries because they match the same entries in the
    # clang_runtime and use the same ${toolchain.libprefix} string.  That
    # is less than ideal but it does no harm since the tools like zbi that
    # consume manifests accept redundant entries if they are identical.
    if (toolchain_variant.with_shared && current_toolchain != shlib_toolchain) {
      public_deps = [ ":$target_name($shlib_toolchain)" ]
      not_needed(invoker, toolchain_spec.flag_vars)
    } else {
      if (toolchain_variant.with_shared && defined(visibility)) {
        visibility += [ ":$target_name" ]
      }

      match = false
      match_flags = {
        forward_variables_from(invoker, toolchain_spec.flag_vars)
      }
      foreach(config, toolchain_spec.runtime) {
        # Clear value from last iteration.
        config_flags = {
        }
        config_flags = {
          forward_variables_from(config, toolchain_spec.flag_vars)
        }
        if (config_flags == match_flags && config.target + [ clang_target ] -
                                           [ clang_target ] != config.target) {
          assert(match == false,
                 "${toolchain_spec.runtime_file} has multiple matches for" +
                     " --target=${clang_target} + $invoker")
          match = config
        }
      }
      assert(match != false,
             "${toolchain_spec.runtime_file} has no match for" +
                 " --target=${clang_target} + $invoker")

      metadata = {
        binaries = []
        distribution_entries = []
        runtime_deps_manifest_lines = []
      }

      _label = get_label_info(":$target_name", "label_with_toolchain")

      # The installation path prefix for runtime libraries depends on the variant.
      # Note that fuzzer variants use the base variant name, i.e. without the -fuzzer
      # suffix for this prefix.
      _libprefix = ""
      if (toolchain_variant.instrumented) {
        _libprefix = string_replace(toolchain_variant.name, "-fuzzer", "") + "/"
      }

      # In many cases, the loop below will be empty.
      not_needed([
                   "_label",
                   "_libprefix",
                 ])

      foreach(lib, match.runtime) {
        # For build_api_module("binaries") in //BUILD.gn.
        metadata.binaries += [
          {
            cpu = current_cpu
            os = current_os
            label = get_label_info(":$target_name", "label_with_toolchain")
            type = "shared_library"
            dist = rebase_path(lib.dist, root_build_dir, toolchain_spec.lib_dir)
            if (defined(lib.debug)) {
              debug =
                  rebase_path(lib.debug, root_build_dir, toolchain_spec.lib_dir)
              if (output_breakpad_syms) {
                breakpad = rebase_path(lib.breakpad,
                                       root_build_dir,
                                       toolchain_spec.lib_dir)
              }
            }

            target_tuple = match.target
            forward_variables_from(match, toolchain_spec.flag_vars)

            if (toolchain_spec.version_string != "") {
              toolchain_id = toolchain_spec.version_string
            }
            if (toolchain_spec.version_description != "") {
              toolchain_version = toolchain_spec.version_description
            }
          },
        ]

        if (!defined(invoker.libraries) || invoker.libraries + [ lib.name ] -
                                           [ lib.name ] != invoker.libraries) {
          _dist_file =
              rebase_path(lib.dist, root_build_dir, toolchain_spec.lib_dir)

          if (defined(lib.soname)) {
            _soname = lib.soname
          } else {
            _soname = get_path_info(lib.dist, "file")
          }

          # Used by runtime_deps_manifest().
          metadata.runtime_deps_manifest_lines +=
              [ "lib/${_libprefix}${_soname}=" +
                rebase_path(lib.dist, root_build_dir, toolchain_spec.lib_dir) ]

          # Used by the distribution_manifest() template.
          metadata.distribution_entries += [
            {
              destination = "lib/${_libprefix}${_soname}"
              label = _label
              source = _dist_file
            },
          ]
        }
      }
    }
  }
}

# Generate a fini manifest that lists all toolchain runtime dependencies and their
# installation location.
#
# deps, data_deps, public_deps (optional)
#   [list of labels] The targets to generate a manifest for.
#
# testonly, visibility (optional)
#   See `gn help`.
#
# outputs (optional)
#   Singleton list containing the path to the manifest file.
#   Defaults to `[ "$target_gen_dir/$target_name.runtime_deps" ]`.
template("toolchain_runtime_deps_manifest") {
  # Build the name of the output file.
  if (defined(invoker.outputs)) {
    _outputs = invoker.outputs
    assert(_outputs != [] && _outputs == [ _outputs[0] ],
           "Outputs list must have exactly one element.")
    manifest_file = _outputs[0]
  } else {
    manifest_file = "$target_gen_dir/$target_name.runtime_deps"
  }

  generated_file(target_name) {
    forward_variables_from(invoker,
                           [
                             "data_deps",
                             "deps",
                             "public_deps",
                             "testonly",
                           ])
    data_keys = [ "runtime_deps_manifest_lines" ]
    walk_keys = [ "runtime_deps_manifest_barrier" ]
    outputs = [ manifest_file ]
  }
}
