Skip to content

Commit 745aa0a

Browse files
committed
java_grpc_library: Use toolchain to enable DexArchiveAspect
This removes the "java_import to work around error with android_binary" hack; see the b/78647825 references to see the really important parts. But in general using a toolchain cleans up the code considerably and allows us to reduce the visibility of our protoc plugin. It also is useful to enable using aspects in the future to avoid using make_non_strict() which would improve compilation speed avoid avoid many unnecessary rebuilds. This is an export of cl/229763103 and brings external up-to-sync with internal.
1 parent 6d44f46 commit 745aa0a

2 files changed

Lines changed: 146 additions & 72 deletions

File tree

compiler/BUILD.bazel

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,53 @@
1+
load("//:java_grpc_library.bzl", "java_rpc_toolchain")
2+
13
cc_binary(
24
name = "grpc_java_plugin",
35
srcs = [
46
"src/java_plugin/cpp/java_generator.cpp",
57
"src/java_plugin/cpp/java_generator.h",
68
"src/java_plugin/cpp/java_plugin.cpp",
79
],
8-
visibility = ["//visibility:public"],
910
deps = [
1011
"@com_google_protobuf//:protoc_lib",
1112
],
1213
)
14+
15+
java_library(
16+
name = "java_grpc_library_deps__do_not_reference",
17+
exports = [
18+
"//api",
19+
"//protobuf",
20+
"//stub",
21+
"//stub:javax_annotation",
22+
"@com_google_code_findbugs_jsr305//jar",
23+
"@com_google_guava_guava//jar",
24+
"@com_google_protobuf//:protobuf_java",
25+
],
26+
)
27+
28+
java_library(
29+
name = "java_lite_grpc_library_deps__do_not_reference",
30+
exports = [
31+
"//api",
32+
"//protobuf-lite",
33+
"//stub",
34+
"//stub:javax_annotation",
35+
"@com_google_code_findbugs_jsr305//jar",
36+
"@com_google_guava_guava//jar",
37+
],
38+
)
39+
40+
java_rpc_toolchain(
41+
name = "java_grpc_library_toolchain",
42+
plugin = "//compiler:grpc_java_plugin",
43+
runtime = [":java_grpc_library_deps__do_not_reference"],
44+
visibility = ["//visibility:public"],
45+
)
46+
47+
java_rpc_toolchain(
48+
name = "java_lite_grpc_library_toolchain",
49+
plugin = "//compiler:grpc_java_plugin",
50+
plugin_arg = "lite",
51+
runtime = [":java_lite_grpc_library_deps__do_not_reference"],
52+
visibility = ["//visibility:public"],
53+
)

java_grpc_library.bzl

Lines changed: 104 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,62 @@
22

33
load("@bazel_tools//tools/jdk:toolchain_utils.bzl", "find_java_runtime_toolchain", "find_java_toolchain")
44

5+
_JavaRpcToolchainInfo = provider(
6+
fields = [
7+
"host_javabase",
8+
"java_toolchain",
9+
"plugin",
10+
"plugin_arg",
11+
"protoc",
12+
"runtime",
13+
],
14+
)
15+
16+
def _java_rpc_toolchain_impl(ctx):
17+
return [
18+
_JavaRpcToolchainInfo(
19+
host_javabase = ctx.attr._host_javabase,
20+
java_toolchain = ctx.attr._java_toolchain,
21+
plugin = ctx.executable.plugin,
22+
plugin_arg = ctx.attr.plugin_arg,
23+
protoc = ctx.executable._protoc,
24+
runtime = ctx.attr.runtime,
25+
),
26+
platform_common.ToolchainInfo(), # Magic for b/78647825
27+
]
28+
29+
java_rpc_toolchain = rule(
30+
attrs = {
31+
# This attribute has a "magic" name recognized by the native DexArchiveAspect (b/78647825).
32+
"runtime": attr.label_list(
33+
cfg = "target",
34+
providers = [JavaInfo],
35+
),
36+
"plugin": attr.label(
37+
cfg = "host",
38+
executable = True,
39+
),
40+
"plugin_arg": attr.string(),
41+
"_protoc": attr.label(
42+
cfg = "host",
43+
default = Label("@com_google_protobuf//:protoc"),
44+
executable = True,
45+
),
46+
"_java_toolchain": attr.label(
47+
default = Label("@bazel_tools//tools/jdk:toolchain"),
48+
),
49+
"_host_javabase": attr.label(
50+
cfg = "host",
51+
default = Label("@bazel_tools//tools/jdk:current_java_runtime"),
52+
),
53+
},
54+
provides = [
55+
_JavaRpcToolchainInfo,
56+
platform_common.ToolchainInfo,
57+
],
58+
implementation = _java_rpc_toolchain_impl,
59+
)
60+
561
# "repository" here is for Bazel builds that span multiple WORKSPACES.
662
def _path_ignoring_repository(f):
763
if len(f.owner.workspace_root) == 0:
@@ -18,45 +74,42 @@ def _java_rpc_library_impl(ctx):
1874
print(("in srcs attribute of {0}: Proto source with label {1} should be in " +
1975
"same package as consuming rule").format(ctx.label, ctx.attr.srcs[0].label))
2076

77+
toolchain = ctx.attr._toolchain[_JavaRpcToolchainInfo]
2178
srcs = ctx.attr.srcs[0][ProtoInfo].direct_sources
2279
includes = ctx.attr.srcs[0][ProtoInfo].transitive_imports
23-
flavor = ctx.attr.flavor
24-
if flavor == "normal":
25-
flavor = ""
2680

2781
srcjar = ctx.actions.declare_file("%s-proto-gensrc.jar" % ctx.label.name)
2882

2983
args = ctx.actions.args()
30-
args.add(ctx.executable._java_plugin.path, format = "--plugin=protoc-gen-grpc-java=%s")
31-
args.add("--grpc-java_out={0}:{1}".format(flavor, srcjar.path))
84+
args.add(toolchain.plugin, format = "--plugin=protoc-gen-rpc-plugin=%s")
85+
args.add("--rpc-plugin_out={0}:{1}".format(toolchain.plugin_arg, srcjar.path))
3286
args.add_all(includes, map_each = _create_include_path)
3387
args.add_all(srcs, map_each = _path_ignoring_repository)
3488

3589
ctx.actions.run(
36-
inputs = depset(srcs, transitive = [includes]),
90+
inputs = depset([toolchain.plugin] + srcs, transitive = [includes]),
3791
outputs = [srcjar],
38-
tools = [ctx.executable._java_plugin],
39-
executable = ctx.executable._protoc,
92+
executable = toolchain.protoc,
4093
arguments = [args],
4194
)
4295

4396
deps_java_info = java_common.merge([dep[JavaInfo] for dep in ctx.attr.deps])
4497

4598
java_info = java_common.compile(
4699
ctx,
47-
java_toolchain = find_java_toolchain(ctx, ctx.attr._java_toolchain),
48-
host_javabase = find_java_runtime_toolchain(ctx, ctx.attr._host_javabase),
100+
java_toolchain = find_java_toolchain(ctx, toolchain.java_toolchain),
101+
host_javabase = find_java_runtime_toolchain(ctx, toolchain.host_javabase),
49102
source_jars = [srcjar],
50-
output_source_jar = ctx.outputs.srcjar,
51103
output = ctx.outputs.jar,
104+
output_source_jar = ctx.outputs.srcjar,
52105
deps = [
53106
java_common.make_non_strict(deps_java_info),
54-
ctx.attr.runtime[JavaInfo],
55-
],
107+
] + [dep[JavaInfo] for dep in toolchain.runtime],
56108
)
109+
57110
return [java_info]
58111

59-
_java_rpc_library = rule(
112+
_java_grpc_library = rule(
60113
attrs = {
61114
"srcs": attr.label_list(
62115
mandatory = True,
@@ -68,32 +121,34 @@ _java_rpc_library = rule(
68121
allow_empty = False,
69122
providers = [JavaInfo],
70123
),
71-
"flavor": attr.string(
72-
values = [
73-
"normal",
74-
"lite",
75-
],
76-
default = "normal",
124+
"_toolchain": attr.label(
125+
default = Label("//compiler:java_grpc_library_toolchain"),
77126
),
78-
"runtime": attr.label(
127+
},
128+
fragments = ["java"],
129+
outputs = {
130+
"jar": "lib%{name}.jar",
131+
"srcjar": "lib%{name}-src.jar",
132+
},
133+
provides = [JavaInfo],
134+
implementation = _java_rpc_library_impl,
135+
)
136+
137+
_java_lite_grpc_library = rule(
138+
attrs = {
139+
"srcs": attr.label_list(
79140
mandatory = True,
141+
allow_empty = False,
142+
providers = ["proto"],
80143
),
81-
"_protoc": attr.label(
82-
default = Label("@com_google_protobuf//:protoc"),
83-
executable = True,
84-
cfg = "host",
85-
),
86-
"_java_plugin": attr.label(
87-
default = Label("//compiler:grpc_java_plugin"),
88-
executable = True,
89-
cfg = "host",
90-
),
91-
"_java_toolchain": attr.label(
92-
default = Label("@bazel_tools//tools/jdk:current_java_toolchain"),
144+
"deps": attr.label_list(
145+
mandatory = True,
146+
allow_empty = False,
147+
providers = [JavaInfo],
93148
),
94-
"_host_javabase": attr.label(
95-
cfg = "host",
96-
default = Label("@bazel_tools//tools/jdk:current_host_java_runtime"),
149+
# This attribute has a "magic" name recognized by the native DexArchiveAspect (b/78647825).
150+
"_toolchain": attr.label(
151+
default = Label("//compiler:java_lite_grpc_library_toolchain"),
97152
),
98153
},
99154
fragments = ["java"],
@@ -110,8 +165,6 @@ def java_grpc_library(
110165
srcs,
111166
deps,
112167
flavor = None,
113-
tags = None,
114-
visibility = None,
115168
**kwargs):
116169
"""Generates and compiles gRPC Java sources for services defined in a proto
117170
file. This rule is compatible with proto_library with java_api_version,
@@ -130,45 +183,25 @@ def java_grpc_library(
130183
srcs. Required.
131184
flavor: (str) "normal" (default) for normal proto runtime. "lite"
132185
for the lite runtime.
133-
visibility: (list) the visibility list
134186
**kwargs: Passed through to generated targets
135187
"""
136188

137189
if len(deps) > 1:
138190
print("Multiple values in 'deps' is deprecated in " + name)
139191

140-
if flavor == "lite":
141-
inner_name = name + "__do_not_reference"
142-
inner_visibility = ["//visibility:private"]
143-
inner_tags = ["avoid_dep"]
144-
runtime = "@io_grpc_grpc_java//:java_lite_grpc_library_deps__do_not_reference"
145-
else:
146-
inner_name = name
147-
inner_visibility = visibility
148-
inner_tags = tags
149-
runtime = "@io_grpc_grpc_java//:java_grpc_library_deps__do_not_reference"
150-
151-
_java_rpc_library(
152-
name = inner_name,
153-
srcs = srcs,
154-
deps = deps,
155-
flavor = flavor,
156-
runtime = runtime,
157-
visibility = inner_visibility,
158-
tags = inner_tags,
159-
**kwargs
160-
)
161-
162-
if flavor == "lite":
163-
# Use java_import to work around error with android_binary:
164-
# Dependencies on .jar artifacts are not allowed in Android binaries,
165-
# please use a java_import to depend on...
166-
native.java_import(
192+
if flavor == None or flavor == "normal":
193+
_java_grpc_library(
167194
name = name,
168-
deps = deps + [runtime],
169-
jars = [":lib{}.jar".format(inner_name)],
170-
srcjar = ":lib{}-src.jar".format(inner_name),
171-
visibility = visibility,
172-
tags = tags,
195+
srcs = srcs,
196+
deps = deps,
173197
**kwargs
174198
)
199+
elif flavor == "lite":
200+
_java_lite_grpc_library(
201+
name = name,
202+
srcs = srcs,
203+
deps = deps,
204+
**kwargs
205+
)
206+
else:
207+
fail("Flavor must be normal or lite")

0 commit comments

Comments
 (0)