From 745aa0a2f570d74e7d7fe0c72334c24e21b8ab17 Mon Sep 17 00:00:00 2001 From: Eric Anderson Date: Fri, 19 Apr 2019 11:15:38 -0700 Subject: [PATCH] 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. --- compiler/BUILD.bazel | 43 ++++++++++- java_grpc_library.bzl | 175 +++++++++++++++++++++++++----------------- 2 files changed, 146 insertions(+), 72 deletions(-) diff --git a/compiler/BUILD.bazel b/compiler/BUILD.bazel index 1a2f2f3826..ef940741da 100644 --- a/compiler/BUILD.bazel +++ b/compiler/BUILD.bazel @@ -1,3 +1,5 @@ +load("//:java_grpc_library.bzl", "java_rpc_toolchain") + cc_binary( name = "grpc_java_plugin", srcs = [ @@ -5,8 +7,47 @@ cc_binary( "src/java_plugin/cpp/java_generator.h", "src/java_plugin/cpp/java_plugin.cpp", ], - visibility = ["//visibility:public"], deps = [ "@com_google_protobuf//:protoc_lib", ], ) + +java_library( + name = "java_grpc_library_deps__do_not_reference", + exports = [ + "//api", + "//protobuf", + "//stub", + "//stub:javax_annotation", + "@com_google_code_findbugs_jsr305//jar", + "@com_google_guava_guava//jar", + "@com_google_protobuf//:protobuf_java", + ], +) + +java_library( + name = "java_lite_grpc_library_deps__do_not_reference", + exports = [ + "//api", + "//protobuf-lite", + "//stub", + "//stub:javax_annotation", + "@com_google_code_findbugs_jsr305//jar", + "@com_google_guava_guava//jar", + ], +) + +java_rpc_toolchain( + name = "java_grpc_library_toolchain", + plugin = "//compiler:grpc_java_plugin", + runtime = [":java_grpc_library_deps__do_not_reference"], + visibility = ["//visibility:public"], +) + +java_rpc_toolchain( + name = "java_lite_grpc_library_toolchain", + plugin = "//compiler:grpc_java_plugin", + plugin_arg = "lite", + runtime = [":java_lite_grpc_library_deps__do_not_reference"], + visibility = ["//visibility:public"], +) diff --git a/java_grpc_library.bzl b/java_grpc_library.bzl index 98f91a3222..60ae970f50 100644 --- a/java_grpc_library.bzl +++ b/java_grpc_library.bzl @@ -2,6 +2,62 @@ load("@bazel_tools//tools/jdk:toolchain_utils.bzl", "find_java_runtime_toolchain", "find_java_toolchain") +_JavaRpcToolchainInfo = provider( + fields = [ + "host_javabase", + "java_toolchain", + "plugin", + "plugin_arg", + "protoc", + "runtime", + ], +) + +def _java_rpc_toolchain_impl(ctx): + return [ + _JavaRpcToolchainInfo( + host_javabase = ctx.attr._host_javabase, + java_toolchain = ctx.attr._java_toolchain, + plugin = ctx.executable.plugin, + plugin_arg = ctx.attr.plugin_arg, + protoc = ctx.executable._protoc, + runtime = ctx.attr.runtime, + ), + platform_common.ToolchainInfo(), # Magic for b/78647825 + ] + +java_rpc_toolchain = rule( + attrs = { + # This attribute has a "magic" name recognized by the native DexArchiveAspect (b/78647825). + "runtime": attr.label_list( + cfg = "target", + providers = [JavaInfo], + ), + "plugin": attr.label( + cfg = "host", + executable = True, + ), + "plugin_arg": attr.string(), + "_protoc": attr.label( + cfg = "host", + default = Label("@com_google_protobuf//:protoc"), + executable = True, + ), + "_java_toolchain": attr.label( + default = Label("@bazel_tools//tools/jdk:toolchain"), + ), + "_host_javabase": attr.label( + cfg = "host", + default = Label("@bazel_tools//tools/jdk:current_java_runtime"), + ), + }, + provides = [ + _JavaRpcToolchainInfo, + platform_common.ToolchainInfo, + ], + implementation = _java_rpc_toolchain_impl, +) + # "repository" here is for Bazel builds that span multiple WORKSPACES. def _path_ignoring_repository(f): if len(f.owner.workspace_root) == 0: @@ -18,25 +74,22 @@ def _java_rpc_library_impl(ctx): print(("in srcs attribute of {0}: Proto source with label {1} should be in " + "same package as consuming rule").format(ctx.label, ctx.attr.srcs[0].label)) + toolchain = ctx.attr._toolchain[_JavaRpcToolchainInfo] srcs = ctx.attr.srcs[0][ProtoInfo].direct_sources includes = ctx.attr.srcs[0][ProtoInfo].transitive_imports - flavor = ctx.attr.flavor - if flavor == "normal": - flavor = "" srcjar = ctx.actions.declare_file("%s-proto-gensrc.jar" % ctx.label.name) args = ctx.actions.args() - args.add(ctx.executable._java_plugin.path, format = "--plugin=protoc-gen-grpc-java=%s") - args.add("--grpc-java_out={0}:{1}".format(flavor, srcjar.path)) + args.add(toolchain.plugin, format = "--plugin=protoc-gen-rpc-plugin=%s") + args.add("--rpc-plugin_out={0}:{1}".format(toolchain.plugin_arg, srcjar.path)) args.add_all(includes, map_each = _create_include_path) args.add_all(srcs, map_each = _path_ignoring_repository) ctx.actions.run( - inputs = depset(srcs, transitive = [includes]), + inputs = depset([toolchain.plugin] + srcs, transitive = [includes]), outputs = [srcjar], - tools = [ctx.executable._java_plugin], - executable = ctx.executable._protoc, + executable = toolchain.protoc, arguments = [args], ) @@ -44,19 +97,19 @@ def _java_rpc_library_impl(ctx): java_info = java_common.compile( ctx, - java_toolchain = find_java_toolchain(ctx, ctx.attr._java_toolchain), - host_javabase = find_java_runtime_toolchain(ctx, ctx.attr._host_javabase), + java_toolchain = find_java_toolchain(ctx, toolchain.java_toolchain), + host_javabase = find_java_runtime_toolchain(ctx, toolchain.host_javabase), source_jars = [srcjar], - output_source_jar = ctx.outputs.srcjar, output = ctx.outputs.jar, + output_source_jar = ctx.outputs.srcjar, deps = [ java_common.make_non_strict(deps_java_info), - ctx.attr.runtime[JavaInfo], - ], + ] + [dep[JavaInfo] for dep in toolchain.runtime], ) + return [java_info] -_java_rpc_library = rule( +_java_grpc_library = rule( attrs = { "srcs": attr.label_list( mandatory = True, @@ -68,32 +121,34 @@ _java_rpc_library = rule( allow_empty = False, providers = [JavaInfo], ), - "flavor": attr.string( - values = [ - "normal", - "lite", - ], - default = "normal", + "_toolchain": attr.label( + default = Label("//compiler:java_grpc_library_toolchain"), ), - "runtime": attr.label( + }, + fragments = ["java"], + outputs = { + "jar": "lib%{name}.jar", + "srcjar": "lib%{name}-src.jar", + }, + provides = [JavaInfo], + implementation = _java_rpc_library_impl, +) + +_java_lite_grpc_library = rule( + attrs = { + "srcs": attr.label_list( mandatory = True, + allow_empty = False, + providers = ["proto"], ), - "_protoc": attr.label( - default = Label("@com_google_protobuf//:protoc"), - executable = True, - cfg = "host", + "deps": attr.label_list( + mandatory = True, + allow_empty = False, + providers = [JavaInfo], ), - "_java_plugin": attr.label( - default = Label("//compiler:grpc_java_plugin"), - executable = True, - cfg = "host", - ), - "_java_toolchain": attr.label( - default = Label("@bazel_tools//tools/jdk:current_java_toolchain"), - ), - "_host_javabase": attr.label( - cfg = "host", - default = Label("@bazel_tools//tools/jdk:current_host_java_runtime"), + # This attribute has a "magic" name recognized by the native DexArchiveAspect (b/78647825). + "_toolchain": attr.label( + default = Label("//compiler:java_lite_grpc_library_toolchain"), ), }, fragments = ["java"], @@ -110,8 +165,6 @@ def java_grpc_library( srcs, deps, flavor = None, - tags = None, - visibility = 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, @@ -130,45 +183,25 @@ def java_grpc_library( srcs. Required. flavor: (str) "normal" (default) for normal proto runtime. "lite" for the lite runtime. - visibility: (list) the visibility list **kwargs: Passed through to generated targets """ if len(deps) > 1: print("Multiple values in 'deps' is deprecated in " + name) - if flavor == "lite": - inner_name = name + "__do_not_reference" - inner_visibility = ["//visibility:private"] - inner_tags = ["avoid_dep"] - runtime = "@io_grpc_grpc_java//:java_lite_grpc_library_deps__do_not_reference" - else: - inner_name = name - inner_visibility = visibility - inner_tags = tags - runtime = "@io_grpc_grpc_java//:java_grpc_library_deps__do_not_reference" - - _java_rpc_library( - name = inner_name, - srcs = srcs, - deps = deps, - flavor = flavor, - runtime = runtime, - visibility = inner_visibility, - tags = inner_tags, - **kwargs - ) - - if flavor == "lite": - # Use java_import to work around error with android_binary: - # Dependencies on .jar artifacts are not allowed in Android binaries, - # please use a java_import to depend on... - native.java_import( + if flavor == None or flavor == "normal": + _java_grpc_library( name = name, - deps = deps + [runtime], - jars = [":lib{}.jar".format(inner_name)], - srcjar = ":lib{}-src.jar".format(inner_name), - visibility = visibility, - tags = tags, + srcs = srcs, + deps = deps, **kwargs ) + elif flavor == "lite": + _java_lite_grpc_library( + name = name, + srcs = srcs, + deps = deps, + **kwargs + ) + else: + fail("Flavor must be normal or lite")