%YAML 1.2
--- |
<%doc>
Header piece
</%doc>\
# GRPC Chromium GN build file
# This file has been automatically generated from a template file.
# Please look at the templates directory instead.
# See //third_party/grpc/README.chromium for more information.
declare_args() {
# Compiles with ares.
enable_grpc_ares = false
# TODO(169395837): Somehow gRPC symbols cannot be found on Android.
# Keep using static linking for now.
# In windows, mac and iOS use static linking.
# Use static linking on Chrome OS as a workaround for the symbol lookup
# error(crbug/1241330) due to a gRPC version mismatch between what Chrome
# uses and what CrOS provides.
grpc_use_static_linking =
is_android || is_win || is_chromeos || is_mac || is_ios
}
if (is_android) {
import("//build/config/android/config.gni")
import("//build/config/android/rules.gni")
}
config("grpc_config") {
include_dirs = [
"src/include",
"src",
"src/src/core/ext/upb-generated",
"src/src/core/ext/upbdefs-generated",
"src/third_party/cares",
"//third_party/cares/include",
"src/third_party/upb",
"//third_party/abseil-cpp",
]
defines = [
"GRPC_USE_PROTO_LITE",
"HAVE_CONFIG_H",
"PB_FIELD_16BIT",
"GRPC_NO_XDS",
"GRPC_NO_RLS",
]
if (!is_android) {
# This prevents android specific object files from getting
# included in shared library built for other platforms
defines += [ "GRPC_NO_BINDER", ]
}
if (is_android) {
libs = [ "log" ] # For __android_log_write
}
if (is_android) {
include_dirs += [ "src/third_party/cares/config_android" ]
} else if (is_fuchsia) {
include_dirs += [ "third_party/cares/config_fuchsia" ]
} else {
include_dirs += [ "src/third_party/cares/config_linux" ]
}
if (is_fuchsia) {
defines += [
# Allows zircon sockets to use file descriptors with gRPC.
"GPR_SUPPORT_CHANNELS_FROM_FD",
]
}
if (!enable_grpc_ares) {
defines += [
# Disable c-ares since it doesn't currently support Fuchsia
"GRPC_ARES=0",
]
}
}
config("grpc_config_private") {
# TODO(b/311287092): Clean up the code and remove this list.
cflags = [
"-Wno-c++98-compat-extra-semi",
"-Wno-deprecated-copy",
"-Wno-extra-semi",
"-Wno-implicit-fallthrough",
"-Wno-shadow",
"-Wno-sign-compare",
"-Wno-unreachable-code",
"-Wno-unreachable-code-break",
"-Wno-unreachable-code-return",
]
# TODO(b/260740023): Remove when gRPC has CFI checks enabled.
if (is_chromeos) {
cflags += [ "-fno-sanitize=cfi-derived-cast,cfi-unrelated-cast" ]
}
}
template("grpc_so") {
if (grpc_use_static_linking) {
source_set(target_name) {
forward_variables_from(invoker, "*")
}
} else {
shared_library(target_name) {
forward_variables_from(invoker, "*")
inputs = [ "./grpc_shared_lib.map" ]
ldflags = [ "-Wl,--version-script=" + rebase_path("./grpc_shared_lib.map", root_build_dir) ]
}
}
}
<%doc>
Python convenience functions.
</%doc>
<%!
import os
import re
import glob
# Sort list of sources or dependencies in a GN target.
def gn_sort(l):
new_l = []
l = set(l)
for i in l:
if i.startswith(':'):
new_l.append('1_{}'.format(i))
elif i.startswith('//'):
new_l.append('3_{}'.format(i))
else:
new_l.append('2_{}'.format(i))
new_l.sort()
return [i[2:] for i in new_l]
# Find repeated basenames to avoid conflicts in GN.
# Split the sources into 3 set of sources so that
# sources with repeated basenames are in different sets
def find_repeated(sources):
# Deduplicate the sources files in the input so the same source file
# don't appear in multiple sets
sources = set(sources)
# Convert sources to sorted list so the sources are split into 3 targets deterministically
sources = sorted(sources)
out_sources = []
repeated1 = []
repeated2 = []
repeated3 = []
repeated4 = []
out_sources_basenames = set()
repeated1_basenames = set()
repeated2_basenames = set()
repeated3_basenames = set()
repeated4_basenames = set()
for s in sources:
basename = os.path.basename(s)
ext = os.path.splitext(basename)
if (len(ext) > 1) and (ext[1] == '.h') and not re.search('ext/upb', s):
out_sources.append(s)
continue
if basename in out_sources_basenames:
if basename in repeated3_basenames:
# If there is a basename that appears more than 5 times,
# we need to create more GN targets for it
assert(s not in repeated4_basenames)
repeated4_basenames.add(basename)
repeated4.append(s)
elif basename in repeated2_basenames:
assert(s not in repeated3_basenames)
repeated3_basenames.add(basename)
repeated3.append(s)
elif basename in repeated1_basenames:
assert(s not in repeated2_basenames)
repeated2_basenames.add(basename)
repeated2.append(s)
else:
repeated1_basenames.add(basename)
repeated1.append(s)
else:
out_sources_basenames.add(basename)
out_sources.append(s)
return (gn_sort(out_sources), gn_sort(repeated1), gn_sort(repeated2),
gn_sort(repeated3), gn_sort(repeated4))
def is_xds_source(s):
file_names = [
'src/src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc',
'src/src/core/ext/xds/xds_server_config_fetcher.cc',
'src/src/core/lib/security/credentials/xds/xds_credentials.cc',
'src/src/core/lib/security/credentials/xds/xds_credentials.h',
'src/src/cpp/client/xds_credentials.cc',
'src/src/cpp/client/xds_credentials.cc',
'src/src/cpp/client/xds_credentials.h',
'src/src/cpp/client/xds_credentials.h',
'src/src/cpp/server/csds/csds.cc',
'src/src/cpp/server/xds_server_credentials.cc',
'src/src/cpp/server/xds_server_credentials.cc',
'src/src/cpp/server/xds_server_credentials.h',
'src/src/core/ext/filters/rbac/rbac_filter.cc',
'src/src/core/ext/filters/rbac/rbac_filter.h',
'src/src/core/ext/filters/rbac/rbac_service_config_parser.cc',
'src/src/core/ext/filters/rbac/rbac_service_config_parser.h',
'src/src/core/lib/security/authorization/grpc_authorization_engine.cc',
'src/src/core/lib/security/authorization/grpc_authorization_engine.h',
'src/src/core/lib/security/authorization/matchers.cc',
'src/src/core/lib/security/authorization/matchers.h',
'src/src/core/lib/security/authorization/rbac_policy.cc',
'src/src/core/lib/security/authorization/rbac_policy.h',
]
return s in file_names
# Add comments for some files.
def get_commented_sources(sources):
out_sources = []
for s in sources:
if s == 'src/src/core/lib/gpr/wrap_memcpy.cc':
out_sources.append('# gRPC memcpy wrapping logic isn\'t useful here.')
out_sources.append('# See https://crbug.com/661171')
out_sources.append('# "{}",'.format(s))
elif s == 'src/src/core/plugin_registry/grpc_plugin_registry.cc':
out_sources.append('# Disabling some default plugins.')
out_sources.append('# "{}",'.format(s))
out_sources.append('"plugin_registry/grpc_plugin_registry.cc",')
elif s == 'src/src/core/lib/matchers/matchers.cc':
# matchers are disabled to reduce binary size
out_sources.append('# "{}",'.format(s))
elif s == 'src/src/core/lib/matchers/matchers.h':
# matchers are disabled to reduce binary size
out_sources.append('# "{}",'.format(s))
elif is_xds_source(s):
# xds is disabled to reduce binary size
# We need to manually remove these sources because generated build
# target info provided by upstream does not consider xds disabled
out_sources.append('# "{}",'.format(s))
else:
out_sources.append('"{}",'.format(s))
return out_sources
# Get dependencies for a target.
def get_deps_from_target(target_dict):
deps = set()
if target_dict.get("secure", False):
deps.add("//third_party/boringssl")
if target_dict.get("build", None) == "protoc":
deps.add("//third_party/protobuf:protoc_lib")
name = target_dict.get("name", None)
if name in ("grpc++", "grpc++_codegen_lib"):
deps.add("//third_party/protobuf:protobuf_lite")
elif name in ("grpc", "grpc_unsecure"):
deps.add("//third_party/zlib")
add_absl = False
add_boring_ssl = False
for d in target_dict.get("deps", []):
if d.startswith('libssl'):
add_boring_ssl = True
elif d.startswith('absl'):
add_absl = True
elif d.startswith(("//", ":")):
deps.add(d)
else:
deps.add(":%s" % d)
if add_absl:
deps.add("//third_party/abseil-cpp:absl")
if add_boring_ssl:
deps.add("//third_party/boringssl",)
return list(deps)
# Get dependencies for a list of sources.
def get_deps_from_sources(sources):
deps = set()
if needs_ares(sources):
deps.add(":cares")
deps.add(":address_sorting")
return list(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 get_include_dirs(sources):
dirs = []
if needs_ares(sources):
dirs = [":cares"]
if needs_address_sorting(sources):
dirs.append("src/third_party/address_sorting/include")
return dirs
def get_extra_stuff():
extra_stuff = []
extra_stuff.append('visibility = [ "./*" ]')
extra_stuff.append('if (!grpc_use_static_linking) {')
extra_stuff.append(' configs -= [ "//build/config/gcc:symbol_visibility_hidden" ]')
extra_stuff.append(' configs += [ "//build/config/gcc:symbol_visibility_default" ]')
extra_stuff.append('}')
return extra_stuff
def strip_sources(sources):
exceptions = [
"src/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h",
"src/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc",
"src/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc",
]
return [f for f in sources
if "ruby_generator" not in f
and not (re.match("src/src/core/ext/filters/client_channel/lb_policy/.*/.*",f)
and not f in exceptions)
and not re.match("src/src/core/ext/filters/client_channel/resolver/xds/.*",f)
and not re.match("src/src/core/ext/xds/.*",f)
]
def adjust_srcs(sources):
return ["src/" + f for f in sources]
def get_sources(target):
sources = (([] if not hasattr(target, "public_headers") else target.public_headers or []) +
(target.headers or []) +
(target.src or []))
return adjust_srcs(sources)
def in_main_lib(lib):
main_libs = ("gpr", "grpc", "grpc++")
return lib.name in main_libs
def wanted_lib(lib):
wanted_libs = ("grpc_plugin_support", "address_sorting", "upb")
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")
def find_sources(path):
sources = []
for (root, ds, fs) in os.walk(path):
for f in fs:
ext = os.path.splitext(f)
if (len(ext) > 1) and (ext[1] in ('.h', '.c')):
sources.append(os.path.join(root, f))
return ["src/" + s for s in sources]
cares_sources = glob.glob('third_party/cares/cares/include/*.h') + \
glob.glob('third_party/cares/cares/src/lib/*.c')
# cares is only used in chromecast. Use chromium/src/third_party/cares in chromecast
cares_sources = gn_sort([s.replace('third_party/cares/cares', '//third_party/cares')
for s in cares_sources])
cares_sources = [s for s in cares_sources if s not in (
'//third_party/cares/cares/src/lib/ahost.c',
'//third_party/cares/cares/src/lib/adig.c',
'//third_party/cares/cares/src/lib/acountry.c')]
%>\
<%doc>
Body of GN file
</%doc>\
${cc_main_library(libs)}
% 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, " ", True)}
}
% else:
${cc_library(lib, "", False)}
% 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
<%doc>
Template Functions
</%doc>\
<%def name="cc_main_library(libs)">\
<%
extra_configs = [':grpc_config_private']
sources = []
headers = []
deps = []
upb_sources = []
for lib in libs:
if lib.name == 'upb':
upb_sources = get_sources(lib)
for lib in libs:
if in_main_lib(lib):
if lib.src:
sources += lib.src
if lib.headers:
headers += lib.headers
if lib.public_headers:
headers += lib.public_headers
deps += get_deps_from_target(lib)
headers = adjust_srcs(headers)
headers = [f for f in headers if f not in upb_sources]
headers = strip_sources(headers)
sources = adjust_srcs(sources)
sources = [f for f in sources if f not in upb_sources]
sources = strip_sources(sources)
(sources, repeated1, repeated2, repeated3, repeated4) = find_repeated(sources)
deps = [d for d in deps if d not in (':gpr', ':grpc')]
cc_lib_name = 'grpc++_cc'
h_lib_name = 'grpc++_h'
repeated_lib_name1 = 'grpc++_repeated1'
repeated_lib_name2 = 'grpc++_repeated2'
repeated_lib_name3 = 'grpc++_repeated3'
repeated_lib_name4 = 'grpc++_repeated4'
other_deps = deps[:]
other_deps.append(":{}".format(h_lib_name))
deps_so = [
':{}'.format(cc_lib_name),
':{}'.format(repeated_lib_name1),
':{}'.format(repeated_lib_name2),
':{}'.format(repeated_lib_name3),
':{}'.format(repeated_lib_name4),
]
public_deps_so = [
':{}'.format(h_lib_name),
]
extra_stuff = get_extra_stuff()
%>\
grpc_so("grpc++") {
deps = [
% for dep in deps_so:
"${dep}",
% endfor
]
public_deps = [
% for dep in public_deps_so:
"${dep}",
% endfor
]
}
# GN doesn't like .cc files with the same base name in the same target.
# Moving them to another target.
${cc_library_internal(h_lib_name, '', headers, deps, extra_stuff, extra_configs)}
${cc_library_internal(cc_lib_name, '', sources, other_deps, extra_stuff, extra_configs)}
${cc_library_internal(repeated_lib_name1, '', repeated1, other_deps, extra_stuff, extra_configs)}
${cc_library_internal(repeated_lib_name2, '', repeated2, other_deps, extra_stuff, extra_configs)}
${cc_library_internal(repeated_lib_name3, '', repeated3, other_deps, extra_stuff, extra_configs)}
${cc_library_internal(repeated_lib_name4, '', repeated4, other_deps, extra_stuff, extra_configs)}
</%def>\
<%def name="cc_library(lib, indent, is_host)">\
<%
sources = get_sources(lib)
sources = strip_sources(sources)
repeated_lib_name1 = "{}_repeated1".format(lib.name)
repeated_lib_name2 = "{}_repeated2".format(lib.name)
repeated_lib_name3 = "{}_repeated3".format(lib.name)
repeated_lib_name4 = "{}_repeated4".format(lib.name)
(sources, repeated1, repeated2, repeated3, repeated4) = find_repeated(sources)
extra_configs = [':grpc_config_private']
extra_stuff = []
target_type = 'source_set'
if not is_host:
extra_stuff = get_extra_stuff()
deps = get_deps_from_target(lib)
repeated_deps = deps[:]
if repeated1:
deps.append(":{}".format(repeated_lib_name1))
if repeated2:
deps.append(":{}".format(repeated_lib_name2))
if repeated3:
deps.append(":{}".format(repeated_lib_name3))
if repeated4:
deps.append(":{}".format(repeated_lib_name4))
%>\
${cc_library_internal(lib.name, indent, sources, deps, extra_stuff, extra_configs)}
% if repeated1:
# GN doesn't like .cc files with the same base name in the same target.
# Moving them to another target.
${cc_library_internal(repeated_lib_name1, indent, repeated1, repeated_deps, extra_stuff, extra_configs)}
% endif
% if repeated2:
# There are some .cc files that are in multiple places. GN doesn't like
# that. Moving them to another target.
${cc_library_internal(repeated_lib_name2, indent, repeated2, repeated_deps, extra_stuff, extra_configs)}
% endif
% if repeated3:
# There are some .cc files that are in multiple places. GN doesn't like
# that. Moving them to another target.
${cc_library_internal(repeated_lib_name3, indent, repeated3, repeated_deps, extra_stuff, extra_configs)}
% endif
% if repeated4:
# There are some .cc files that are in multiple places. GN doesn't like
# that. Moving them to another target.
${cc_library_internal(repeated_lib_name4, indent, repeated4, repeated_deps, extra_stuff, extra_configs)}
% endif
</%def>\
<%def name="cc_library_internal(name, indent, sources, lib_deps, extra_stuff, extra_configs)">\
<%
include_dirs = get_include_dirs(sources)
lib_deps += get_deps_from_sources(sources)
lib_deps = gn_sort(lib_deps)
sources = gn_sort(sources)
sources = get_commented_sources(sources)
%>\
${indent}source_set("${name}") {
% if sources:
${indent} sources = [
% for src in sources:
${indent} ${src}
% endfor
${indent} ]
% endif
% if lib_deps:
${indent} deps = [
% for dep in lib_deps:
${indent} "${dep}",
% endfor
${indent} ]
% endif
${indent} public_configs = [
${indent} ":grpc_config",
${indent} ]
% if extra_configs:
${indent} configs += [
% for config in extra_configs:
${indent} "${config}",
% endfor
${indent} ]
% endif
% if include_dirs:
${indent} include_dirs = [
% for d in include_dirs:
${indent} "${d}",
% endfor
${indent} ]
% endif
% if extra_stuff:
% for e in extra_stuff:
${indent} ${e}
% endfor
% endif
${indent}}\
</%def>
<%def name="cc_binary(tgt, indent)">\
<%
sources = ["src/"+s for s in tgt.src]
sources = gn_sort(sources)
deps = get_deps_from_target(tgt) + get_deps_from_sources(sources)
deps = gn_sort(deps)
%>
${indent}executable("${tgt.name}") {
${indent} sources = [
% for src in sources:
${indent} "${src}",
% endfor
${indent} ]
${indent} deps = [
% for dep in deps:
${indent} "${dep}",
% endfor
${indent} ]
${indent} configs += [
${indent} "//third_party/protobuf:protobuf_config",
${indent} ]
${indent} public_configs = [ ":grpc_config" ]
${indent}}
</%def><%!
%>\
<%doc>
Manual targets
</%doc>\
config("cares_config") {
cflags = [
"-Wno-macro-redefined",
"-Wno-unused-variable",
]
}
source_set("cares") {
sources = [
"src/third_party/cares/ares_build.h",
]
if (enable_grpc_ares) {
include_dirs = [ "//third_party/cares/include" ]
sources += [
% for src in cares_sources:
"${src}",
% endfor
]
}
if (is_android) {
sources += [ "src/third_party/cares/config_android/ares_config.h" ]
configs += [ ":cares_config" ]
} else if (is_fuchsia) {
sources += [ "third_party/cares/config_fuchsia/ares_config.h" ]
} else {
sources += [ "src/third_party/cares/config_linux/ares_config.h" ]
}
deps = [
"//third_party/boringssl",
]
public_configs = [ ":grpc_config" ]
}
group("fuzzers") {}
if (is_android) {
# gRPC BinderTransport's Java API and internal code, which cannot be handled by GN's source_set
# and we need manually create a android_library target for them.
android_library("binder_java_helper") {
sources = [
"src/src/core/ext/transport/binder/java/io/grpc/binder/cpp/GrpcBinderConnection.java",
"src/src/core/ext/transport/binder/java/io/grpc/binder/cpp/GrpcCppServerBuilder.java",
"src/src/core/ext/transport/binder/java/io/grpc/binder/cpp/NativeConnectionHelper.java",
]
}
}