# 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")

# ## 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 `${current_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 = "$clang_prefix/../lib"
_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.

_cflags = []

# First, record a map of runtimes for Fuchsia for Asan without -static-libstdc++
_asan_runtimes_map = []
foreach(entry, _clang_runtime) {
  if (entry.cflags == _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 == _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.hwasan.so' which also depends
# on libc++abi.so.
_clang_runtime = []
_clang_runtime = _new_clang_runtime

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

_new_clang_runtime = []
foreach(entry, _clang_runtime) {
  _new_clang_runtime += [
    {
      forward_variables_from(entry, "*")
      if (cflags == [ "-fsanitize=hwaddress" ] &&
          ldflags == [ "-static-libstdc++" ]) {
        _target = target[0]
        if (string_replace(_target, "-fuchsia", "") != _target) {
          foreach(_hwasan_entry, _hwasan_runtimes_map) {
            if (_hwasan_entry.target == _target) {
              runtime = []
              runtime = _hwasan_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 == _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 == _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 = "$rustc_prefix/lib"
_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_variant.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 + [ current_target_tuple ] -
            [ current_target_tuple ] != config.target) {
          assert(match == false,
                 "${toolchain_spec.runtime_file} has multiple matches for" +
                     " --target=${current_target_tuple} + $invoker")
          match = config
        }
      }
      assert(match != false,
             "${toolchain_spec.runtime_file} has no match for" +
                 " --target=${current_target_tuple} + $invoker")

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

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

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

      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/${toolchain_variant.libprefix}${_soname}=" +
                rebase_path(lib.dist, root_build_dir, toolchain_spec.lib_dir) ]

          # Used by the distribution_manifest() template.
          metadata.distribution_entries += [
            {
              destination = "lib/${toolchain_variant.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 ]
  }
}
