%YAML 1.2
--- |
  # GRPC Fuchsia GN build file

  # This file has been automatically generated from a template file.
  # Please look at the templates directory instead.
  # This file can be regenerated from the template by running
  # tools/buildgen/generate_projects.sh

  # Copyright 2019 gRPC authors.
  #
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  #
  #     http://www.apache.org/licenses/LICENSE-2.0
  #
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.

  config("grpc_config") {
    include_dirs = [
      ".",
      "include/",
    ]
    defines = [
      "GRPC_USE_PROTO_LITE",
      "GPR_SUPPORT_CHANNELS_FROM_FD",
      "PB_FIELD_16BIT",
    ]
  }
  <%!
  def get_deps(target_dict):
    deps = []
    if target_dict.get("build", None) == "protoc":
      deps.append("//third_party/protobuf:protoc_lib")
    name = target_dict.get("name", None)
    if name in ("grpc++", "grpc++_codegen_lib"):
      deps.append("//third_party/protobuf:protobuf_lite")
    elif name in ("grpc", "grpc_unsecure"):
      deps.append("//third_party/zlib")
    for d in target_dict.get("deps", []):
      if d == "libssl":
        deps.append("//third_party/boringssl")
      elif d.startswith(("//", ":")):
        deps.append(d)
      else:
        deps.append(":%s" % d)
    if needs_ares(target_dict.src):
      deps.append("//third_party/cares")
      deps.append(":address_sorting")
    if needs_health_proto(target_dict.src) and target_dict.name != "health_proto":
      deps.append(":health_proto")
    return deps

  %><%!
  def needs_ares(srcs):
    return any("/c_ares/" in f for f in srcs) if srcs else False

  %><%!
  def needs_address_sorting(sources):
    return needs_ares(sources) or any("address_sorting" in s for s in sources)

  %><%!
  def needs_health_proto(srcs):
    return any("health.pb" in f for f in srcs)

  %><%!
  def get_include_dirs(sources):
    dirs = []
    if needs_ares(sources):
      dirs = ["third_party/cares"]
    if needs_address_sorting(sources):
      dirs.append("third_party/address_sorting/include")
    return dirs

  %><%!
  def strip_sources(sources, name):
    return [f for f in sources
            if "ruby_generator" not in f
            and ("health.pb" not in f or name == "health_proto")]

  %><%!
  def get_sources(target):
    return ((target.public_headers or []) +
            (target.headers or []) +
            (target.src or []))

  %><%!
  def get_extra_configs(target_dict):
    if target_dict.get("name", "") == "grpc_cpp_plugin":
      return ["//third_party/protobuf:protobuf_config"]
    return []

  %><%!
  def wanted_lib(lib):
    wanted_libs = ("gpr", "grpc", "grpc++", "grpc_plugin_support", "address_sorting")
    return lib.build in ("all", "protoc") and lib.get("name", "") in wanted_libs

  %><%!
  def wanted_binary(tgt):
    wanted_binaries = ("grpc_cpp_plugin",)
    return tgt.build == "protoc" and tgt.get("name", "") in wanted_binaries

  %><%!
  def only_on_host_toolchain(tgt):
    return tgt.get("name", "") in ("grpc_plugin_support", "grpc_cpp_plugin")

  %>
  % for lib in filegroups:
    % if lib.name in ("health_proto"):
      ${cc_library(lib)}
    %endif
  %endfor
  % for lib in libs:
    % if wanted_lib(lib):
      % if only_on_host_toolchain(lib):
        # Only compile the plugin for the host architecture.
        if (current_toolchain == host_toolchain) {
          ${cc_library(lib)}
        }
      % else:
        ${cc_library(lib)}
      % endif
    % endif
  % endfor
  % for tgt in targets:
    % if wanted_binary(tgt):
      % if only_on_host_toolchain(tgt):
        # Only compile the plugin for the host architecture.
        if (current_toolchain == host_toolchain) {
          ${cc_binary(tgt)}
        }
      % else:
        ${cc_binary(tgt)}
      % endif
    % endif
  % endfor
  <%def name="cc_library(lib)">
    <%
      sources = get_sources(lib)
      include_dirs = get_include_dirs(sources)
      sources = strip_sources(sources, lib.name)
      sources.sort()
    %>
    source_set("${lib.name}") {
      %if sources:
      sources = [
        % for src in sources:
          "${src}",
        % endfor
      ]
      %endif
      deps = [
        % for dep in get_deps(lib):
          "${dep}",
        % endfor
      ]
      <% extra_configs = get_extra_configs(lib) %>
      % if extra_configs:
        configs += [
          % for config in extra_configs:
            "${config}",
          % endfor
        ]
      % endif
      public_configs = [
        ":grpc_config",
      ]
      %if include_dirs:
      include_dirs = [
        %for d in include_dirs:
          "${d}",
        %endfor
      ]
      %endif
    }
  </%def>
  <%def name="cc_binary(tgt)">
    executable("${tgt.name}") {
      sources = [
        % for src in tgt.src:
          "${src}",
        % endfor
      ]
      deps = [
        % for dep in get_deps(tgt):
          "${dep}",
        % endfor
      ]
      <% extra_configs = get_extra_configs(tgt) %>
      % if extra_configs:
        configs += [
          % for config in extra_configs:
            "${config}",
          % endfor
        ]
      % endif
      public_configs = [ ":grpc_config" ]
    }
  </%def>
  ## vim: set ft=mako:ts=2:et:sw=2
