-
Notifications
You must be signed in to change notification settings - Fork 4.2k
/
Copy pathbuild_defs.bzl
171 lines (161 loc) · 5.98 KB
/
build_defs.bzl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
"""BUILD rules to generate gRPC service interfaces.
You need to load the rules in your BUILD file for use, like:
load("//third_party/grpc:build_defs.bzl", "java_grpc_library")
"""
load("@rules_cc//cc:defs.bzl", "cc_library")
load("@rules_java//java:defs.bzl", "java_library")
load("@rules_proto//proto:defs.bzl", "ProtoInfo")
def _path_ignoring_repository(f):
if (len(f.owner.workspace_root) == 0):
return f.short_path
virtual_imports = "/_virtual_imports/"
if virtual_imports in f.path:
return f.path.split(virtual_imports)[1].split("/", 1)[1]
else:
# If |f| is a generated file, it will have "bazel-out/*/genfiles" prefix
# before "external/workspace", so we need to add the starting index of "external/workspace"
return f.path[f.path.find(f.owner.workspace_root) + len(f.owner.workspace_root) + 1:]
def _gensource_impl(ctx):
if len(ctx.attr.srcs) > 1:
fail("Only one src value supported", "srcs")
for s in ctx.attr.srcs:
if s.label.package != ctx.label.package:
print(("in srcs attribute of {0}: Proto source with label {1} should be in " +
"same package as consuming rule").format(ctx.label, s.label))
srcdotjar = ctx.actions.declare_file(ctx.label.name + ".jar")
srcs = [f for dep in ctx.attr.srcs for f in dep[ProtoInfo].direct_sources]
includes = [f for dep in ctx.attr.srcs for f in dep[ProtoInfo].transitive_imports.to_list()]
ctx.actions.run_shell(
command = " ".join([
ctx.executable._protoc.path,
"--plugin=protoc-gen-grpc-java={0}".format(ctx.executable._java_plugin.path),
"--grpc-java_out=enable_deprecated={0}:{1}".format(str(ctx.attr.enable_deprecated).lower(), srcdotjar.path),
] +
["-I{0}={1}".format(_path_ignoring_repository(include), include.path) for include in includes] +
[src.path for src in srcs]),
inputs = srcs + includes,
tools = [ctx.executable._java_plugin, ctx.executable._protoc],
outputs = [srcdotjar],
use_default_shell_env = True,
)
ctx.actions.run_shell(
command = "cp '%s' '%s'" % (srcdotjar.path, ctx.outputs.srcjar.path),
inputs = [srcdotjar],
outputs = [ctx.outputs.srcjar],
)
_java_grpc_gensource = rule(
attrs = {
"srcs": attr.label_list(
mandatory = True,
allow_empty = False,
providers = [ProtoInfo],
),
"enable_deprecated": attr.bool(
default = False,
),
"_protoc": attr.label(
default = Label("@com_google_protobuf//:protoc"),
executable = True,
cfg = "host",
allow_single_file = True,
),
"_java_plugin": attr.label(
default = Label("@io_bazel//third_party/grpc:grpc-java-plugin"),
executable = True,
cfg = "host",
),
},
outputs = {
"srcjar": "%{name}.srcjar",
},
implementation = _gensource_impl,
)
def java_grpc_library(name, srcs, deps, enable_deprecated = None, visibility = None, constraints = None, **kwargs):
"""Generates and compiles gRPC Java sources for services defined in a proto
file. This rule is compatible with proto_library with java_api_version,
java_proto_library, and java_lite_proto_library.
Do note that this rule only scans through the proto file for RPC services. It
does not generate Java classes for proto messages. You will need a separate
proto_library with java_api_version, java_proto_library, or
java_lite_proto_library rule.
Args:
name: (str) A unique name for this rule. Required.
srcs: (list) a single proto_library target that contains the schema of the
service. Required.
deps: (list) a single java_proto_library target for the proto_library in
srcs. Required.
visibility: (list) the visibility list
**kwargs: Passed through to generated targets
"""
gensource_name = name + "_srcs"
_java_grpc_gensource(
name = gensource_name,
srcs = srcs,
enable_deprecated = enable_deprecated,
visibility = ["//visibility:private"],
tags = [
"avoid_dep",
],
**kwargs
)
java_library(
name = name,
srcs = [gensource_name],
visibility = visibility,
deps = [
"@io_bazel//third_party:javax_annotations",
"@io_bazel//third_party:jsr305",
"@io_bazel//third_party/grpc:grpc-jar",
"@io_bazel//third_party:guava",
"@com_google_protobuf//:protobuf_java",
] + deps,
**kwargs
)
def _get_external_deps(external_deps):
ret = []
for dep in external_deps:
ret += ["//third_party/" + dep]
return ret
# Simplified version of gRPC upstream's grpc_cc_library.
def grpc_cc_library(
name,
srcs = [],
public_hdrs = [],
hdrs = [],
external_deps = [],
deps = [],
standalone = False,
language = "C++",
testonly = False,
visibility = None,
alwayslink = 0,
data = []):
copts = []
if language.upper() == "C":
copts = select({
"//conditions:default": [
"-std=c99",
"-Wimplicit-function-declaration",
],
":windows": ["/we4013"],
})
cc_library(
name = name,
srcs = srcs,
defines = ["GRPC_ARES=0"], # Our use case doesn't need ares.
hdrs = hdrs + public_hdrs,
deps = deps + _get_external_deps(external_deps),
copts = copts,
visibility = visibility,
testonly = testonly,
linkopts = select({
"//conditions:default": ["-pthread"],
":windows": [],
}),
includes = [
".",
"include",
],
alwayslink = alwayslink,
data = data,
)