diff --git a/src/main/java/com/google/devtools/build/lib/packages/semantics/BuildLanguageOptions.java b/src/main/java/com/google/devtools/build/lib/packages/semantics/BuildLanguageOptions.java index 4f9d0885a27d63..f75c7bf3b03af6 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/semantics/BuildLanguageOptions.java +++ b/src/main/java/com/google/devtools/build/lib/packages/semantics/BuildLanguageOptions.java @@ -696,6 +696,18 @@ public final class BuildLanguageOptions extends OptionsBase { + " Label.relative) can be used.") public boolean enableDeprecatedLabelApis; + // Flip when dependencies to rules_* repos are upgraded and protobuf registers toolchains + @Option( + name = "incompatible_enable_proto_toolchain_resolution", + defaultValue = "false", + documentationCategory = OptionDocumentationCategory.TOOLCHAIN, + effectTags = {OptionEffectTag.LOADING_AND_ANALYSIS}, + metadataTags = {OptionMetadataTag.INCOMPATIBLE_CHANGE}, + help = + "If true, proto lang rules define toolchains from rules_proto, rules_java, rules_cc" + + " repositories.") + public boolean incompatibleEnableProtoToolchainResolution; + /** * An interner to reduce the number of StarlarkSemantics instances. A single Blaze instance should * never accumulate a large number of these and being able to shortcut on object identity makes a @@ -795,6 +807,9 @@ public StarlarkSemantics toStarlarkSemantics() { INCOMPATIBLE_DISABLE_OBJC_LIBRARY_TRANSITION, incompatibleDisableObjcLibraryTransition) .setBool(INCOMPATIBLE_ENABLE_DEPRECATED_LABEL_APIS, enableDeprecatedLabelApis) + .setBool( + INCOMPATIBLE_ENABLE_PROTO_TOOLCHAIN_RESOLUTION, + incompatibleEnableProtoToolchainResolution) .build(); return INTERNER.intern(semantics); } @@ -891,6 +906,8 @@ public StarlarkSemantics toStarlarkSemantics() { "-incompatible_disable_objc_library_transition"; public static final String INCOMPATIBLE_ENABLE_DEPRECATED_LABEL_APIS = "+incompatible_enable_deprecated_label_apis"; + public static final String INCOMPATIBLE_ENABLE_PROTO_TOOLCHAIN_RESOLUTION = + "-incompatible_enable_proto_toolchain_resolution"; // non-booleans public static final StarlarkSemantics.Key EXPERIMENTAL_BUILTINS_BZL_PATH = diff --git a/src/main/java/com/google/devtools/build/lib/rules/proto/BUILD b/src/main/java/com/google/devtools/build/lib/rules/proto/BUILD index af13958a45ed23..d79f08378391b4 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/proto/BUILD +++ b/src/main/java/com/google/devtools/build/lib/rules/proto/BUILD @@ -40,6 +40,7 @@ java_library( "//src/main/java/com/google/devtools/build/lib/collect/nestedset", "//src/main/java/com/google/devtools/build/lib/concurrent", "//src/main/java/com/google/devtools/build/lib/packages", + "//src/main/java/com/google/devtools/build/lib/packages/semantics", "//src/main/java/com/google/devtools/build/lib/starlarkbuildapi", "//src/main/java/com/google/devtools/build/lib/starlarkbuildapi/proto", "//src/main/java/com/google/devtools/build/lib/util:filetype", diff --git a/src/main/java/com/google/devtools/build/lib/rules/proto/BazelProtoCommon.java b/src/main/java/com/google/devtools/build/lib/rules/proto/BazelProtoCommon.java index e41380310763ba..77ac10a2292d3b 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/proto/BazelProtoCommon.java +++ b/src/main/java/com/google/devtools/build/lib/rules/proto/BazelProtoCommon.java @@ -22,6 +22,12 @@ import net.starlark.java.annot.StarlarkMethod; import net.starlark.java.eval.EvalException; import net.starlark.java.eval.StarlarkList; +import com.google.common.collect.ImmutableSet; +import com.google.devtools.build.lib.packages.BuiltinRestriction; +import com.google.devtools.build.lib.packages.semantics.BuildLanguageOptions; +import com.google.devtools.build.lib.starlarkbuildapi.proto.ProtoCommonApi; +import net.starlark.java.annot.StarlarkMethod; +import net.starlark.java.eval.EvalException; import net.starlark.java.eval.StarlarkThread; /** Protocol buffers support for Starlark. */ @@ -87,4 +93,15 @@ public ProtoInfo protoInfo( Depset.cast(transitiveDescriptorSets, Artifact.class, "transitive_descriptor_set"), Depset.cast(exportedSources, ProtoSource.class, "exported_sources")); } + + @StarlarkMethod( + name = "incompatible_enable_proto_toolchain_resolution", + useStarlarkThread = true, + documented = false) + public boolean getDefineProtoToolchains(StarlarkThread thread) throws EvalException { + ProtoCommon.checkPrivateStarlarkificationAllowlist(thread); + return thread + .getSemantics() + .getBool(BuildLanguageOptions.INCOMPATIBLE_ENABLE_PROTO_TOOLCHAIN_RESOLUTION); + } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoConfiguration.java index c9d77f3be17084..9582ed93be901e 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoConfiguration.java +++ b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoConfiguration.java @@ -31,6 +31,7 @@ import com.google.devtools.common.options.OptionEffectTag; import com.google.devtools.common.options.OptionMetadataTag; import java.util.List; +import javax.annotation.Nullable; import net.starlark.java.annot.StarlarkMethod; import net.starlark.java.eval.EvalException; import net.starlark.java.eval.StarlarkThread; @@ -65,13 +66,12 @@ public static class Options extends FragmentOptions { public List protocOpts; @Option( - name = "experimental_proto_extra_actions", - defaultValue = "false", - documentationCategory = OptionDocumentationCategory.OUTPUT_SELECTION, - effectTags = {OptionEffectTag.AFFECTS_OUTPUTS, OptionEffectTag.LOADING_AND_ANALYSIS}, - metadataTags = {OptionMetadataTag.EXPERIMENTAL}, - help = "Run extra actions for alternative Java api versions in a proto_library." - ) + name = "experimental_proto_extra_actions", + defaultValue = "false", + documentationCategory = OptionDocumentationCategory.OUTPUT_SELECTION, + effectTags = {OptionEffectTag.AFFECTS_OUTPUTS, OptionEffectTag.LOADING_AND_ANALYSIS}, + metadataTags = {OptionMetadataTag.EXPERIMENTAL}, + help = "Run extra actions for alternative Java api versions in a proto_library.") public boolean experimentalProtoExtraActions; @Option( @@ -240,8 +240,8 @@ public boolean experimentalProtoDescriptorSetsIncludeSourceInfo() { } /** - * Returns true if we will run extra actions for actions that are not run by default. If this - * is enabled, e.g. all extra_actions for alternative api-versions or language-flavours of a + * Returns true if we will run extra actions for actions that are not run by default. If this is + * enabled, e.g. all extra_actions for alternative api-versions or language-flavours of a * proto_library target are run. */ public boolean runExperimentalProtoExtraActions() { @@ -252,6 +252,7 @@ public boolean runExperimentalProtoExtraActions() { name = "proto_compiler", doc = "Label for the proto compiler.", defaultLabel = ProtoConstants.DEFAULT_PROTOC_LABEL) + @Nullable public Label protoCompiler() { return options.protoCompiler; } @@ -260,10 +261,12 @@ public Label protoCompiler() { name = "proto_toolchain_for_java", doc = "Label for the java proto toolchains.", defaultLabel = ProtoConstants.DEFAULT_JAVA_PROTO_LABEL) + @Nullable public Label protoToolchainForJava() { return options.protoToolchainForJava; } + @Nullable public Label protoToolchainForJ2objc() { return options.protoToolchainForJ2objc; } @@ -272,6 +275,7 @@ public Label protoToolchainForJ2objc() { name = "proto_toolchain_for_java_lite", doc = "Label for the java lite proto toolchains.", defaultLabel = ProtoConstants.DEFAULT_JAVA_LITE_PROTO_LABEL) + @Nullable public Label protoToolchainForJavaLite() { return options.protoToolchainForJavaLite; } @@ -280,6 +284,7 @@ public Label protoToolchainForJavaLite() { name = "proto_toolchain_for_cc", doc = "Label for the cc proto toolchains.", defaultLabel = ProtoConstants.DEFAULT_CC_PROTO_LABEL) + @Nullable public Label protoToolchainForCc() { return options.protoToolchainForCc; } diff --git a/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoConstants.java b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoConstants.java index 80ee27b6f3f5e0..e08307de3b0eac 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoConstants.java +++ b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoConstants.java @@ -17,7 +17,7 @@ /** Constants used in Proto rules. */ public final class ProtoConstants { /** Default label for proto compiler. */ - static final String DEFAULT_PROTOC_LABEL = "@bazel_tools//tools/proto:protoc"; + public static final String DEFAULT_PROTOC_LABEL = "@bazel_tools//tools/proto:protoc"; /** Default label for java proto toolchains. */ static final String DEFAULT_JAVA_PROTO_LABEL = "@bazel_tools//tools/proto:java_toolchain"; diff --git a/src/main/starlark/builtins_bzl/common/cc/cc_proto_library.bzl b/src/main/starlark/builtins_bzl/common/cc/cc_proto_library.bzl index fa7f896264c386..956b9750db9c01 100644 --- a/src/main/starlark/builtins_bzl/common/cc/cc_proto_library.bzl +++ b/src/main/starlark/builtins_bzl/common/cc/cc_proto_library.bzl @@ -15,7 +15,8 @@ """Starlark implementation of cc_proto_library""" load(":common/cc/cc_helper.bzl", "cc_helper") -load(":common/proto/proto_common.bzl", "ProtoLangToolchainInfo", proto_common = "proto_common_do_not_use") +load(":common/proto/proto_common.bzl", "toolchains", "ProtoLangToolchainInfo", proto_common = "proto_common_do_not_use") +load(":common/cc/semantics.bzl", "semantics") ProtoInfo = _builtins.toplevel.ProtoInfo CcInfo = _builtins.toplevel.CcInfo @@ -24,15 +25,15 @@ cc_common = _builtins.toplevel.cc_common ProtoCcFilesInfo = provider(fields = ["files"], doc = "Provide cc proto files.") ProtoCcHeaderInfo = provider(fields = ["headers"], doc = "Provide cc proto headers.") -def _are_srcs_excluded(ctx, target): - return not proto_common.experimental_should_generate_code(target[ProtoInfo], ctx.attr._aspect_cc_proto_toolchain[ProtoLangToolchainInfo], "cc_proto_library", target.label) +def _are_srcs_excluded(proto_toolchain, target): + return not proto_common.experimental_should_generate_code(target[ProtoInfo], proto_toolchain, "cc_proto_library", target.label) -def _get_feature_configuration(ctx, target, cc_toolchain, proto_info): +def _get_feature_configuration(ctx, target, cc_toolchain, proto_info, proto_toolchain): requested_features = list(ctx.features) unsupported_features = list(ctx.disabled_features) unsupported_features.append("parse_headers") unsupported_features.append("layering_check") - if not _are_srcs_excluded(ctx, target) and len(proto_info.direct_sources) != 0: + if not _are_srcs_excluded(proto_toolchain, target) and len(proto_info.direct_sources) != 0: requested_features.append("header_modules") else: unsupported_features.append("header_modules") @@ -78,12 +79,13 @@ def _get_strip_include_prefix(ctx, proto_info): def _aspect_impl(target, ctx): cc_toolchain = cc_helper.find_cpp_toolchain(ctx) + proto_toolchain = toolchains.find_toolchain(ctx, "_aspect_cc_proto_toolchain", semantics.CC_PROTO_TOOLCHAIN) proto_info = target[ProtoInfo] - feature_configuration = _get_feature_configuration(ctx, target, cc_toolchain, proto_info) + feature_configuration = _get_feature_configuration(ctx, target, cc_toolchain, proto_info, proto_toolchain) proto_configuration = ctx.fragments.proto deps = [] - runtime = ctx.attr._aspect_cc_proto_toolchain[ProtoLangToolchainInfo].runtime + runtime = proto_toolchain.runtime if runtime != None: deps.append(runtime) deps.extend(getattr(ctx.rule.attr, "deps", [])) @@ -100,7 +102,7 @@ def _aspect_impl(target, ctx): textual_hdrs = [] additional_exported_hdrs = [] - if _are_srcs_excluded(ctx, target): + if _are_srcs_excluded(proto_toolchain, target): header_provider = None # Hack: This is a proto_library for descriptor.proto or similar. @@ -155,7 +157,7 @@ def _aspect_impl(target, ctx): proto_common.compile( actions = ctx.actions, proto_info = proto_info, - proto_lang_toolchain_info = ctx.attr._aspect_cc_proto_toolchain[ProtoLangToolchainInfo], + proto_lang_toolchain_info = proto_toolchain, generated_files = outputs, experimental_output_files = "multiple", ) @@ -250,12 +252,11 @@ cc_proto_aspect = aspect( required_providers = [ProtoInfo], provides = [CcInfo], attrs = { - "_aspect_cc_proto_toolchain": attr.label( - default = configuration_field(fragment = "proto", name = "proto_toolchain_for_cc"), - ), "_cc_toolchain": attr.label(default = "@bazel_tools//tools/cpp:current_cc_toolchain"), - }, - toolchains = cc_helper.use_cpp_toolchain(), + } | toolchains.if_legacy_toolchain({"_aspect_cc_proto_toolchain": attr.label( + default = configuration_field(fragment = "proto", name = "proto_toolchain_for_cc"), + )}), + toolchains = cc_helper.use_cpp_toolchain() + toolchains.use_toolchain(semantics.CC_PROTO_TOOLCHAIN), ) def _impl(ctx): @@ -283,4 +284,5 @@ cc_proto_library = rule( ), }, provides = [CcInfo], + toolchains = toolchains.use_toolchain(semantics.CC_PROTO_TOOLCHAIN), ) diff --git a/src/main/starlark/builtins_bzl/common/cc/semantics.bzl b/src/main/starlark/builtins_bzl/common/cc/semantics.bzl index 14cb4f4c422404..9f8e8334e98f88 100644 --- a/src/main/starlark/builtins_bzl/common/cc/semantics.bzl +++ b/src/main/starlark/builtins_bzl/common/cc/semantics.bzl @@ -198,4 +198,5 @@ semantics = struct( get_coverage_env = _get_coverage_env, get_proto_aspects = _get_proto_aspects, incompatible_disable_objc_library_transition = _incompatible_disable_objc_library_transition, + CC_PROTO_TOOLCHAIN = "@rules_cc//cc/proto:toolchain_type", ) diff --git a/src/main/starlark/builtins_bzl/common/exports.bzl b/src/main/starlark/builtins_bzl/common/exports.bzl index 42ab66757ad684..a2db972f3a5556 100755 --- a/src/main/starlark/builtins_bzl/common/exports.bzl +++ b/src/main/starlark/builtins_bzl/common/exports.bzl @@ -24,7 +24,7 @@ load("@_builtins//:common/objc/compilation_support.bzl", "compilation_support") load("@_builtins//:common/objc/linking_support.bzl", "linking_support") load("@_builtins//:common/proto/proto_common.bzl", "proto_common_do_not_use") load("@_builtins//:common/proto/proto_library.bzl", "proto_library") -load("@_builtins//:common/proto/proto_lang_toolchain_wrapper.bzl", "proto_lang_toolchain") +load("@_builtins//:common/proto/proto_lang_toolchain.bzl", "proto_lang_toolchain") load("@_builtins//:common/python/py_runtime_macro.bzl", "py_runtime") load("@_builtins//:common/python/providers.bzl", "PyInfo", "PyRuntimeInfo") load("@_builtins//:common/java/proto/java_lite_proto_library.bzl", "java_lite_proto_library") diff --git a/src/main/starlark/builtins_bzl/common/java/java_semantics.bzl b/src/main/starlark/builtins_bzl/common/java/java_semantics.bzl index 923af60a0eed50..f86cf31714f78b 100644 --- a/src/main/starlark/builtins_bzl/common/java/java_semantics.bzl +++ b/src/main/starlark/builtins_bzl/common/java/java_semantics.bzl @@ -73,4 +73,6 @@ semantics = struct( check_proto_registry_collision = _check_proto_registry_collision, get_coverage_runner = _get_coverage_runner, add_constraints = _add_constraints, + JAVA_PROTO_TOOLCHAIN = "@rules_java//java/proto:toolchain_type", + JAVA_LITE_PROTO_TOOLCHAIN = "@rules_java//java/proto:lite_toolchain_type", ) diff --git a/src/main/starlark/builtins_bzl/common/java/proto/java_lite_proto_library.bzl b/src/main/starlark/builtins_bzl/common/java/proto/java_lite_proto_library.bzl index 56afa3f41c0dca..6f08afdc6b3c40 100644 --- a/src/main/starlark/builtins_bzl/common/java/proto/java_lite_proto_library.bzl +++ b/src/main/starlark/builtins_bzl/common/java/proto/java_lite_proto_library.bzl @@ -15,8 +15,8 @@ """A Starlark implementation of the java_lite_proto_library rule.""" load(":common/java/java_semantics.bzl", "semantics") -load(":common/proto/proto_common.bzl", "ProtoLangToolchainInfo", proto_common = "proto_common_do_not_use") -load(":common/java/proto/java_proto_library.bzl", "JavaProtoAspectInfo", "bazel_java_proto_library_rule", "java_compile_for_protos") +load(":common/java/proto/java_proto_library.bzl", "JavaProtoAspectInfo", "java_compile_for_protos") +load(":common/proto/proto_common.bzl", "toolchains", "ProtoLangToolchainInfo", proto_common = "proto_common_do_not_use") PROTO_TOOLCHAIN_ATTR = "_aspect_proto_toolchain_for_javalite" @@ -40,7 +40,11 @@ def _aspect_impl(target, ctx): deps = [dep[JavaInfo] for dep in ctx.rule.attr.deps] exports = [exp[JavaInfo] for exp in ctx.rule.attr.exports] - proto_toolchain_info = ctx.attr._aspect_proto_toolchain_for_javalite[ProtoLangToolchainInfo] + proto_toolchain_info = toolchains.find_toolchain( + ctx, + "_aspect_proto_toolchain_for_javalite", + semantics.JAVA_LITE_PROTO_TOOLCHAIN, + ) source_jar = None if proto_common.experimental_should_generate_code(target[ProtoInfo], proto_toolchain_info, "java_lite_proto_library", target.label): @@ -74,15 +78,16 @@ def _aspect_impl(target, ctx): java_lite_proto_aspect = aspect( implementation = _aspect_impl, attr_aspects = ["deps", "exports"], - attrs = { + attrs = toolchains.if_legacy_toolchain({ PROTO_TOOLCHAIN_ATTR: attr.label( default = configuration_field(fragment = "proto", name = "proto_toolchain_for_java_lite"), ), - }, + }), fragments = ["java"], required_providers = [ProtoInfo], provides = [JavaInfo, JavaProtoAspectInfo], - toolchains = [semantics.JAVA_TOOLCHAIN], + toolchains = [semantics.JAVA_TOOLCHAIN] + + toolchains.use_toolchain(semantics.JAVA_LITE_PROTO_TOOLCHAIN), ) def _rule_impl(ctx): @@ -98,7 +103,11 @@ def _rule_impl(ctx): ([JavaInfo, DefaultInfo, OutputGroupInfo, ProguardSpecProvider]) """ - proto_toolchain_info = ctx.attr._aspect_proto_toolchain_for_javalite[ProtoLangToolchainInfo] + proto_toolchain_info = toolchains.find_toolchain( + ctx, + "_aspect_proto_toolchain_for_javalite", + semantics.JAVA_LITE_PROTO_TOOLCHAIN, + ) runtime = proto_toolchain_info.runtime if runtime: @@ -106,13 +115,20 @@ def _rule_impl(ctx): else: proguard_provider_specs = ProguardSpecProvider(depset()) - java_info, DefaultInfo, OutputGroupInfo = bazel_java_proto_library_rule(ctx) + java_info = java_common.merge([dep[JavaInfo] for dep in ctx.attr.deps], merge_java_outputs = False) + + transitive_src_and_runtime_jars = depset(transitive = [dep[JavaProtoAspectInfo].jars for dep in ctx.attr.deps]) + transitive_runtime_jars = depset(transitive = [java_info.transitive_runtime_jars]) + java_info = semantics.add_constraints(java_info, ["android"]) return [ java_info, - DefaultInfo, - OutputGroupInfo, + DefaultInfo( + files = transitive_src_and_runtime_jars, + runfiles = ctx.runfiles(transitive_files = transitive_runtime_jars), + ), + OutputGroupInfo(default = depset()), proguard_provider_specs, ] @@ -120,9 +136,11 @@ java_lite_proto_library = rule( implementation = _rule_impl, attrs = { "deps": attr.label_list(providers = [ProtoInfo], aspects = [java_lite_proto_aspect]), + } | toolchains.if_legacy_toolchain({ PROTO_TOOLCHAIN_ATTR: attr.label( default = configuration_field(fragment = "proto", name = "proto_toolchain_for_java_lite"), ), - }, + }), provides = [JavaInfo], + toolchains = toolchains.use_toolchain(semantics.JAVA_LITE_PROTO_TOOLCHAIN), ) diff --git a/src/main/starlark/builtins_bzl/common/java/proto/java_proto_library.bzl b/src/main/starlark/builtins_bzl/common/java/proto/java_proto_library.bzl index 09690f027282ce..f2634ec99fa8f0 100644 --- a/src/main/starlark/builtins_bzl/common/java/proto/java_proto_library.bzl +++ b/src/main/starlark/builtins_bzl/common/java/proto/java_proto_library.bzl @@ -15,7 +15,7 @@ """The implementation of the `java_proto_library` rule and its aspect.""" load(":common/java/java_semantics.bzl", "semantics") -load(":common/proto/proto_common.bzl", "ProtoLangToolchainInfo", proto_common = "proto_common_do_not_use") +load(":common/proto/proto_common.bzl", "toolchains", "ProtoLangToolchainInfo", proto_common = "proto_common_do_not_use") java_common = _builtins.toplevel.java_common JavaInfo = _builtins.toplevel.JavaInfo @@ -47,7 +47,7 @@ def _bazel_java_proto_aspect_impl(target, ctx): runtime jars. """ - proto_toolchain_info = ctx.attr._aspect_java_proto_toolchain[ProtoLangToolchainInfo] + proto_toolchain_info = toolchains.find_toolchain(ctx, "_aspect_java_proto_toolchain", semantics.JAVA_PROTO_TOOLCHAIN) source_jar = None if proto_common.experimental_should_generate_code(target[ProtoInfo], proto_toolchain_info, "java_proto_library", target.label): # Generate source jar using proto compiler. @@ -129,12 +129,12 @@ def java_compile_for_protos(ctx, output_jar_suffix, source_jar = None, deps = [] bazel_java_proto_aspect = aspect( implementation = _bazel_java_proto_aspect_impl, - attrs = { + attrs = toolchains.if_legacy_toolchain({ "_aspect_java_proto_toolchain": attr.label( default = configuration_field(fragment = "proto", name = "proto_toolchain_for_java"), ), - }, - toolchains = [semantics.JAVA_TOOLCHAIN], + }), + toolchains = [semantics.JAVA_TOOLCHAIN] + toolchains.use_toolchain(semantics.JAVA_PROTO_TOOLCHAIN), attr_aspects = ["deps", "exports"], required_providers = [ProtoInfo], provides = [JavaInfo, JavaProtoAspectInfo], @@ -149,7 +149,6 @@ def bazel_java_proto_library_rule(ctx): Returns: ([JavaInfo, DefaultInfo, OutputGroupInfo]) """ - java_info = java_common.merge([dep[JavaInfo] for dep in ctx.attr.deps], merge_java_outputs = False) transitive_src_and_runtime_jars = depset(transitive = [dep[JavaProtoAspectInfo].jars for dep in ctx.attr.deps]) @@ -172,4 +171,5 @@ java_proto_library = rule( "distribs": attr.string_list(), }, provides = [JavaInfo], + toolchains = toolchains.use_toolchain(semantics.JAVA_PROTO_TOOLCHAIN), ) diff --git a/src/main/starlark/builtins_bzl/common/proto/proto_common.bzl b/src/main/starlark/builtins_bzl/common/proto/proto_common.bzl index 64036dd964b63a..062dad34e3d351 100644 --- a/src/main/starlark/builtins_bzl/common/proto/proto_common.bzl +++ b/src/main/starlark/builtins_bzl/common/proto/proto_common.bzl @@ -30,6 +30,7 @@ ProtoLangToolchainInfo = provider( protoc_opts = "(list[str]) Options to pass to proto compiler.", progress_message = "(str) Progress message to set on the proto compiler action.", mnemonic = "(str) Mnemonic to set on the proto compiler action.", + toolchain_type = """(Label) Toolchain type that was used to obtain this info""", ), ) @@ -154,6 +155,7 @@ def _compile( use_default_shell_env = True, resource_set = resource_set, exec_group = experimental_exec_group, + toolchain = getattr(proto_lang_toolchain_info, "toolchain_type", None), ) _BAZEL_TOOLS_PREFIX = "external/bazel_tools/" @@ -265,10 +267,39 @@ def _declare_generated_files( return outputs +def _find_toolchain(ctx, legacy_attr, toolchain_type): + if _builtins.toplevel.proto_common.incompatible_enable_proto_toolchain_resolution(): + toolchain = ctx.toolchains[toolchain_type] + if not toolchain: + fail("No toolchains registered for '%s'." % toolchain_type) + return toolchain.proto + else: + return getattr(ctx.attr, legacy_attr)[ProtoLangToolchainInfo] + +def _use_toolchain(toolchain_type): + if _builtins.toplevel.proto_common.incompatible_enable_proto_toolchain_resolution(): + return [_builtins.toplevel.config_common.toolchain_type(toolchain_type, mandatory = False)] + else: + return [] + +def _if_legacy_toolchain(legacy_attr_dict): + if _builtins.toplevel.proto_common.incompatible_enable_proto_toolchain_resolution(): + return {} + else: + return legacy_attr_dict + +toolchains = struct( + use_toolchain = _use_toolchain, + find_toolchain = _find_toolchain, + if_legacy_toolchain = _if_legacy_toolchain, +) + proto_common_do_not_use = struct( compile = _compile, declare_generated_files = _declare_generated_files, experimental_should_generate_code = _experimental_should_generate_code, experimental_filter_sources = _experimental_filter_sources, ProtoLangToolchainInfo = ProtoLangToolchainInfo, + INCOMPATIBLE_ENABLE_PROTO_TOOLCHAIN_RESOLUTION = _builtins.toplevel.proto_common.incompatible_enable_proto_toolchain_resolution(), + INCOMPATIBLE_PASS_TOOLCHAIN_TYPE = True, ) diff --git a/src/main/starlark/builtins_bzl/common/proto/proto_lang_toolchain.bzl b/src/main/starlark/builtins_bzl/common/proto/proto_lang_toolchain.bzl index 3d2a9d00cd6bdb..699636983d60f4 100644 --- a/src/main/starlark/builtins_bzl/common/proto/proto_lang_toolchain.bzl +++ b/src/main/starlark/builtins_bzl/common/proto/proto_lang_toolchain.bzl @@ -14,7 +14,7 @@ """A Starlark implementation of the proto_lang_toolchain rule.""" -load(":common/proto/proto_common.bzl", "ProtoLangToolchainInfo") +load(":common/proto/proto_common.bzl", "ProtoLangToolchainInfo", "toolchains", proto_common = "proto_common_do_not_use") load(":common/proto/proto_semantics.bzl", "semantics") ProtoInfo = _builtins.toplevel.ProtoInfo @@ -31,61 +31,60 @@ def _rule_impl(ctx): if ctx.attr.plugin != None: plugin = ctx.attr.plugin[DefaultInfo].files_to_run - proto_compiler = getattr(ctx.attr, "proto_compiler", None) - proto_compiler = getattr(ctx.attr, "_proto_compiler", proto_compiler) + if proto_common.INCOMPATIBLE_ENABLE_PROTO_TOOLCHAIN_RESOLUTION: + proto_compiler = ctx.toolchains[semantics.PROTO_TOOLCHAIN].proto.proto_compiler + protoc_opts = ctx.toolchains[semantics.PROTO_TOOLCHAIN].proto.protoc_opts + else: + proto_compiler = ctx.attr._proto_compiler.files_to_run + protoc_opts = ctx.fragments.proto.experimental_protoc_opts + proto_lang_toolchain_info = ProtoLangToolchainInfo( + out_replacement_format_flag = flag, + output_files = ctx.attr.output_files, + plugin_format_flag = ctx.attr.plugin_format_flag, + plugin = plugin, + runtime = ctx.attr.runtime, + provided_proto_sources = provided_proto_sources, + proto_compiler = proto_compiler, + protoc_opts = protoc_opts, + progress_message = ctx.attr.progress_message, + mnemonic = ctx.attr.mnemonic, + toolchain_type = ctx.attr.toolchain_type.label if ctx.attr.toolchain_type else None, + ) return [ - DefaultInfo( - files = depset(), - runfiles = ctx.runfiles(), - ), - ProtoLangToolchainInfo( - out_replacement_format_flag = flag, - output_files = ctx.attr.output_files, - plugin_format_flag = ctx.attr.plugin_format_flag, - plugin = plugin, - runtime = ctx.attr.runtime, - provided_proto_sources = provided_proto_sources, - proto_compiler = proto_compiler.files_to_run, - protoc_opts = ctx.fragments.proto.experimental_protoc_opts, - progress_message = ctx.attr.progress_message, - mnemonic = ctx.attr.mnemonic, - ), + DefaultInfo(files = depset(), runfiles = ctx.runfiles()), + _builtins.toplevel.platform_common.ToolchainInfo(proto = proto_lang_toolchain_info), + # TODO(b/300592942): remove when --incompatible_enable_proto_toolchains is flipped and removed + proto_lang_toolchain_info, ] -def make_proto_lang_toolchain(custom_proto_compiler): - return rule( - _rule_impl, - attrs = dict( - { - "progress_message": attr.string(default = "Generating proto_library %{label}"), - "mnemonic": attr.string(default = "GenProto"), - "command_line": attr.string(mandatory = True), - "output_files": attr.string(values = ["single", "multiple", "legacy"], default = "legacy"), - "plugin_format_flag": attr.string(), - "plugin": attr.label( - executable = True, - cfg = "exec", - ), - "runtime": attr.label(), - "blacklisted_protos": attr.label_list( - providers = [ProtoInfo], - ), - }, - **({ - "proto_compiler": attr.label( - cfg = "exec", - executable = True, - ), - } if custom_proto_compiler else { - "_proto_compiler": attr.label( - cfg = "exec", - executable = True, - allow_files = True, - default = configuration_field("proto", "proto_compiler"), - ), - }) - ), - provides = [ProtoLangToolchainInfo], - fragments = ["proto"] + semantics.EXTRA_FRAGMENTS, - ) +proto_lang_toolchain = rule( + _rule_impl, + attrs = + { + "progress_message": attr.string(default = "Generating proto_library %{label}"), + "mnemonic": attr.string(default = "GenProto"), + "command_line": attr.string(mandatory = True), + "output_files": attr.string(values = ["single", "multiple", "legacy"], default = "legacy"), + "plugin_format_flag": attr.string(), + "plugin": attr.label( + executable = True, + cfg = "exec", + ), + "runtime": attr.label(), + "blacklisted_protos": attr.label_list( + providers = [ProtoInfo], + ), + "toolchain_type": attr.label(), + } | ({} if proto_common.INCOMPATIBLE_ENABLE_PROTO_TOOLCHAIN_RESOLUTION else { + "_proto_compiler": attr.label( + cfg = "exec", + executable = True, + allow_files = True, + default = configuration_field("proto", "proto_compiler"), + ), + }), + provides = [ProtoLangToolchainInfo], + fragments = ["proto"], + toolchains = toolchains.use_toolchain(semantics.PROTO_TOOLCHAIN), # Used to obtain protoc +) diff --git a/src/main/starlark/builtins_bzl/common/proto/proto_lang_toolchain_custom_protoc.bzl b/src/main/starlark/builtins_bzl/common/proto/proto_lang_toolchain_custom_protoc.bzl deleted file mode 100644 index b4157f6aef66ad..00000000000000 --- a/src/main/starlark/builtins_bzl/common/proto/proto_lang_toolchain_custom_protoc.bzl +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright 2021 The Bazel Authors. All rights reserved. -# -# 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. - -"""Defines a proto_lang_toolchain rule class with custom proto compiler. - -There are two physical rule classes for proto_lang_toolchain and we want both of them -to have a name string of "proto_lang_toolchain". -""" - -load(":common/proto/proto_lang_toolchain.bzl", "make_proto_lang_toolchain") - -proto_lang_toolchain = make_proto_lang_toolchain(custom_proto_compiler = True) diff --git a/src/main/starlark/builtins_bzl/common/proto/proto_lang_toolchain_default_protoc.bzl b/src/main/starlark/builtins_bzl/common/proto/proto_lang_toolchain_default_protoc.bzl deleted file mode 100644 index 7345bc37fc0013..00000000000000 --- a/src/main/starlark/builtins_bzl/common/proto/proto_lang_toolchain_default_protoc.bzl +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright 2021 The Bazel Authors. All rights reserved. -# -# 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. - -"""Defines a proto_lang_toolchain rule class with default proto compiler. - -There are two physical rule classes for proto_lang_toolchain and we want both of them -to have a name string of "proto_lang_toolchain". -""" - -load(":common/proto/proto_lang_toolchain.bzl", "make_proto_lang_toolchain") - -proto_lang_toolchain = make_proto_lang_toolchain(custom_proto_compiler = False) diff --git a/src/main/starlark/builtins_bzl/common/proto/proto_lang_toolchain_wrapper.bzl b/src/main/starlark/builtins_bzl/common/proto/proto_lang_toolchain_wrapper.bzl deleted file mode 100644 index 075e6d73c1c2c0..00000000000000 --- a/src/main/starlark/builtins_bzl/common/proto/proto_lang_toolchain_wrapper.bzl +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright 2021 The Bazel Authors. All rights reserved. -# -# 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. - -"""Macro encapsulating the proto_lang_toolchain implementation. - -This is needed since proto compiler can be defined, or used as a default one. -There are two implementations of proto_lang_toolchain - one with public proto_compiler attribute, and the other one with private compiler. -""" - -load(":common/proto/proto_lang_toolchain_default_protoc.bzl", toolchain_default_protoc = "proto_lang_toolchain") -load(":common/proto/proto_lang_toolchain_custom_protoc.bzl", toolchain_custom_protoc = "proto_lang_toolchain") - -def proto_lang_toolchain( - proto_compiler = None, - **kwargs): - if proto_compiler != None: - toolchain_custom_protoc( - proto_compiler = proto_compiler, - **kwargs - ) - else: - toolchain_default_protoc( - **kwargs - ) diff --git a/src/main/starlark/builtins_bzl/common/proto/proto_library.bzl b/src/main/starlark/builtins_bzl/common/proto/proto_library.bzl index 5ce86c3bfc4ba5..d9943d7a1ea755 100644 --- a/src/main/starlark/builtins_bzl/common/proto/proto_library.bzl +++ b/src/main/starlark/builtins_bzl/common/proto/proto_library.bzl @@ -16,8 +16,8 @@ Definition of proto_library rule. """ +load(":common/proto/proto_common.bzl", "toolchains", proto_common = "proto_common_do_not_use") load(":common/proto/proto_semantics.bzl", "semantics") -load(":common/proto/proto_common.bzl", proto_common = "proto_common_do_not_use") load(":common/paths.bzl", "paths") ProtoInfo = _builtins.toplevel.ProtoInfo @@ -251,15 +251,22 @@ def _write_descriptor_set(ctx, direct_sources, deps, exports, proto_info, descri args.add("--allowed_public_imports=") else: args.add_joined("--allowed_public_imports", public_import_protos, map_each = _get_import_path, join_with = ":") - proto_lang_toolchain_info = proto_common.ProtoLangToolchainInfo( - out_replacement_format_flag = "--descriptor_set_out=%s", - output_files = "single", - mnemonic = "GenProtoDescriptorSet", - progress_message = "Generating Descriptor Set proto_library %{label}", - proto_compiler = ctx.executable._proto_compiler, - protoc_opts = ctx.fragments.proto.experimental_protoc_opts, - plugin = None, - ) + if proto_common.INCOMPATIBLE_ENABLE_PROTO_TOOLCHAIN_RESOLUTION: + toolchain = ctx.toolchains[semantics.PROTO_TOOLCHAIN] + if not toolchain: + fail("Protocol compiler toolchain could not be resolved.") + proto_lang_toolchain_info = toolchain.proto + else: + proto_lang_toolchain_info = proto_common.ProtoLangToolchainInfo( + out_replacement_format_flag = "--descriptor_set_out=%s", + output_files = "single", + mnemonic = "GenProtoDescriptorSet", + progress_message = "Generating Descriptor Set proto_library %{label}", + proto_compiler = ctx.executable._proto_compiler, + protoc_opts = ctx.fragments.proto.experimental_protoc_opts, + plugin = None, + ) + proto_common.compile( ctx.actions, proto_info, @@ -271,7 +278,7 @@ def _write_descriptor_set(ctx, direct_sources, deps, exports, proto_info, descri proto_library = rule( _proto_library_impl, - attrs = dict({ + attrs = { "srcs": attr.label_list( allow_files = [".proto", ".protodevel"], flags = ["DIRECT_COMPILE_TIME_INPUT"], @@ -288,14 +295,16 @@ proto_library = rule( flags = ["SKIP_CONSTRAINTS_OVERRIDE"], ), "licenses": attr.license() if hasattr(attr, "license") else attr.string_list(), + } | toolchains.if_legacy_toolchain({ "_proto_compiler": attr.label( cfg = "exec", executable = True, allow_files = True, default = configuration_field("proto", "proto_compiler"), ), - }, **semantics.EXTRA_ATTRIBUTES), + }) | semantics.EXTRA_ATTRIBUTES, fragments = ["proto"] + semantics.EXTRA_FRAGMENTS, provides = [ProtoInfo], output_to_genfiles = True, # TODO(b/204266604) move to bin dir + toolchains = toolchains.use_toolchain(semantics.PROTO_TOOLCHAIN), ) diff --git a/src/main/starlark/builtins_bzl/common/proto/proto_semantics.bzl b/src/main/starlark/builtins_bzl/common/proto/proto_semantics.bzl index 8634dd6dcb7963..88ef1317a0c016 100644 --- a/src/main/starlark/builtins_bzl/common/proto/proto_semantics.bzl +++ b/src/main/starlark/builtins_bzl/common/proto/proto_semantics.bzl @@ -20,6 +20,7 @@ def _preprocess(ctx): pass semantics = struct( + PROTO_TOOLCHAIN = "@rules_proto//proto:toolchain_type", PROTO_COMPILER_LABEL = "@bazel_tools//tools/proto:protoc", EXTRA_ATTRIBUTES = { "import_prefix": attr.string(), diff --git a/src/test/java/com/google/devtools/build/lib/packages/util/MockProtoSupport.java b/src/test/java/com/google/devtools/build/lib/packages/util/MockProtoSupport.java index c78e740690b52d..6b6d717807c86d 100644 --- a/src/test/java/com/google/devtools/build/lib/packages/util/MockProtoSupport.java +++ b/src/test/java/com/google/devtools/build/lib/packages/util/MockProtoSupport.java @@ -16,6 +16,7 @@ import com.google.devtools.build.lib.rules.proto.ProtoCommon; import com.google.devtools.build.lib.testutil.Scratch; +import com.google.devtools.build.lib.rules.proto.ProtoConstants; import com.google.devtools.build.lib.testutil.TestConstants; import java.io.IOException; @@ -39,12 +40,23 @@ private MockProtoSupport() { */ public static void setup(MockToolsConfig config) throws IOException { createNetProto2(config); + setupWorkspace(config); + registerProtoToolchain(config); } - /** - * Create a dummy "net/proto2 compiler and proto APIs for all languages - * and versions. - */ + private static void registerProtoToolchain(MockToolsConfig config) throws IOException { + config.append("WORKSPACE", "register_toolchains('tools/proto/toolchains:all')"); + config.create( + "tools/proto/toolchains/BUILD", + TestConstants.LOAD_PROTO_TOOLCHAIN, + TestConstants.LOAD_PROTO_LANG_TOOLCHAIN, + "proto_toolchain(name = 'protoc_sources'," + + "proto_compiler = '" + + ProtoConstants.DEFAULT_PROTOC_LABEL + + "')"); + } + + /** Create a dummy "net/proto2 compiler and proto APIs for all languages and versions. */ private static void createNetProto2(MockToolsConfig config) throws IOException { config.create( "net/proto2/compiler/public/BUILD", @@ -198,17 +210,24 @@ private static void createNetProto2(MockToolsConfig config) throws IOException { " srcs = [ 'metadata.go' ])"); } - public static void setupWorkspace(Scratch scratch) throws Exception { - scratch.appendFile( - "WORKSPACE", - "local_repository(", - " name = 'rules_proto',", - " path = 'third_party/rules_proto',", - ")"); - scratch.file("third_party/rules_proto/WORKSPACE"); - scratch.file("third_party/rules_proto/proto/BUILD", "licenses(['notice'])"); - scratch.file( - "third_party/rules_proto/proto/defs.bzl", + public static void setupWorkspace(MockToolsConfig config) throws IOException { + if (TestConstants.PRODUCT_NAME.equals("bazel")) { + config.append( + "WORKSPACE", + "local_repository(", + " name = 'rules_proto',", + " path = 'third_party/bazel_rules/rules_proto',", + ")"); + } + + config.create("third_party/bazel_rules/rules_proto/WORKSPACE"); + config.create( + "third_party/bazel_rules/rules_proto/proto/BUILD", + "licenses(['notice'])", + "toolchain_type(name = 'toolchain_type', visibility = ['//visibility:public'])"); + config.create( + "third_party/bazel_rules/rules_proto/proto/defs.bzl", + "load(':proto_lang_toolchain.bzl', _proto_lang_toolchain = 'proto_lang_toolchain')", "def _add_tags(kargs):", " if 'tags' in kargs:", " kargs['tags'] += ['__PROTO_RULES_MIGRATION_DO_NOT_USE_WILL_BREAK__']", @@ -217,6 +236,71 @@ public static void setupWorkspace(Scratch scratch) throws Exception { " return kargs", "", "def proto_library(**kargs): native.proto_library(**_add_tags(kargs))", - "def proto_lang_toolchain(**kargs): native.proto_lang_toolchain(**_add_tags(kargs))"); + "def proto_lang_toolchain(**kargs): _proto_lang_toolchain(**_add_tags(kargs))"); + config.create( + "third_party/bazel_rules/rules_proto/proto/proto_toolchain.bzl", + "load(':proto_toolchain_rule.bzl', _proto_toolchain_rule = 'proto_toolchain')", + "def proto_toolchain(*, name, proto_compiler, exec_compatible_with = []):", + " _proto_toolchain_rule(name = name, proto_compiler = proto_compiler)", + " native.toolchain(", + " name = name + '_toolchain',", + " toolchain_type = '" + TestConstants.PROTO_TOOLCHAIN + "',", + " exec_compatible_with = exec_compatible_with,", + " target_compatible_with = [],", + " toolchain = name,", + " )"); + config.create( + "third_party/bazel_rules/rules_proto/proto/proto_toolchain_rule.bzl", + "ProtoLangToolchainInfo = proto_common_do_not_use.ProtoLangToolchainInfo", + "def _impl(ctx):", + " return [", + " DefaultInfo(", + " files = depset(),", + " runfiles = ctx.runfiles(),", + " ),", + " platform_common.ToolchainInfo(", + " proto = ProtoLangToolchainInfo(", + " out_replacement_format_flag = ctx.attr.command_line,", + " output_files = ctx.attr.output_files,", + " plugin = None,", + " runtime = None,", + " proto_compiler = ctx.attr.proto_compiler.files_to_run,", + " protoc_opts = ctx.fragments.proto.experimental_protoc_opts,", + " progress_message = ctx.attr.progress_message,", + " mnemonic = ctx.attr.mnemonic,", + " toolchain_type = '//third_party/bazel_rules/rules_proto/proto:toolchain_type'", + " ),", + " ),", + " ]", + "proto_toolchain = rule(", + " _impl,", + " attrs = {", + " 'progress_message': attr.string(default = ", + " 'Generating Descriptor Set proto_library %{label}'),", + " 'mnemonic': attr.string(default = 'GenProtoDescriptorSet'),", + " 'command_line': attr.string(default = '--descriptor_set_out=%s'),", + " 'output_files': attr.string(values = ['single', 'multiple', 'legacy'],", + " default = 'single'),", + " 'proto_compiler': attr.label(", + " cfg = 'exec',", + " executable = True,", + " allow_files = True,", + " ),", + " },", + " provides = [platform_common.ToolchainInfo],", + " fragments = ['proto'],", + ")"); + config.create( + "third_party/bazel_rules/rules_proto/proto/proto_lang_toolchain.bzl", + "def proto_lang_toolchain(*, name, toolchain_type = None, exec_compatible_with = [],", + " target_compatible_with = [], **attrs):", + " native.proto_lang_toolchain(name = name, toolchain_type = toolchain_type, **attrs)", + " if toolchain_type:", + " native.toolchain(", + " name = name + '_toolchain',", + " toolchain_type = toolchain_type,", + " exec_compatible_with = exec_compatible_with,", + " target_compatible_with = target_compatible_with,", + " toolchain = name)"); } } diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/CcStarlarkApiProviderTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/CcStarlarkApiProviderTest.java index 18401afcc7f04d..4c2d5c8dd56bfa 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/cpp/CcStarlarkApiProviderTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/CcStarlarkApiProviderTest.java @@ -41,7 +41,7 @@ private CcStarlarkApiInfo getApiForBuiltin(String label) throws Exception { @Before public void setUp() throws Exception { - MockProtoSupport.setupWorkspace(scratch); + MockProtoSupport.setupWorkspace(mockToolsConfig); invalidatePackages(); } diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoLibraryTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoLibraryTest.java index 271b591d538e2f..2511c8d2868b8f 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoLibraryTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoLibraryTest.java @@ -55,6 +55,10 @@ public class CcProtoLibraryTest extends BuildViewTestCase { @Before public void setUp() throws Exception { + MockProtoSupport.setup(mockToolsConfig); + scratch.file( + "third_party/bazel_rules/rules_cc/cc/proto/BUILD", + "toolchain_type(name = 'toolchain_type', visibility = ['//visibility:public'])"); scratch.file("protobuf/WORKSPACE"); scratch.overwriteFile( "protobuf/BUILD", @@ -78,10 +82,34 @@ public void setUp() throws Exception { " name = 'com_google_protobuf',", " path = 'protobuf',", ")"); - MockProtoSupport.setupWorkspace(scratch); invalidatePackages(); // A dash of magic to re-evaluate the WORKSPACE file. } + @Test + public void protoToolchainResolution_enabled() throws Exception { + setBuildLanguageOptions("--incompatible_enable_proto_toolchain_resolution"); + getAnalysisMock() + .ccSupport() + .setupCcToolchainConfig( + mockToolsConfig, + CcToolchainConfig.builder() + .withFeatures( + CppRuleClasses.SUPPORTS_DYNAMIC_LINKER, + CppRuleClasses.SUPPORTS_INTERFACE_SHARED_LIBRARIES)); + scratch.file( + "x/BUILD", + TestConstants.LOAD_PROTO_LIBRARY, + "cc_proto_library(name = 'foo_cc_proto', deps = ['foo_proto'])", + "proto_library(name = 'foo_proto', srcs = ['foo.proto'])"); + assertThat(prettyArtifactNames(getFilesToBuild(getConfiguredTarget("//x:foo_cc_proto")))) + .containsExactly( + "x/foo.pb.h", + "x/foo.pb.cc", + "x/libfoo_proto.a", + "x/libfoo_proto.ifso", + "x/libfoo_proto.so"); + } + @Test public void basic() throws Exception { getAnalysisMock() diff --git a/src/test/java/com/google/devtools/build/lib/rules/java/proto/BUILD b/src/test/java/com/google/devtools/build/lib/rules/java/proto/BUILD index 530babc5920a01..c77b322ab05a70 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/java/proto/BUILD +++ b/src/test/java/com/google/devtools/build/lib/rules/java/proto/BUILD @@ -27,6 +27,7 @@ java_test( "//src/main/java/com/google/devtools/build/lib/rules/java:java-rules", "//src/test/java/com/google/devtools/build/lib/actions/util", "//src/test/java/com/google/devtools/build/lib/analysis/util", + "//src/test/java/com/google/devtools/build/lib/packages:testutil", "//src/test/java/com/google/devtools/build/lib/rules/java:java_compile_action_test_helper", "//src/test/java/com/google/devtools/build/lib/testutil:JunitUtils", "//third_party:guava", diff --git a/src/test/java/com/google/devtools/build/lib/rules/java/proto/StarlarkJavaLiteProtoLibraryTest.java b/src/test/java/com/google/devtools/build/lib/rules/java/proto/StarlarkJavaLiteProtoLibraryTest.java index 45cb965c456051..1767b8cf7cb158 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/java/proto/StarlarkJavaLiteProtoLibraryTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/java/proto/StarlarkJavaLiteProtoLibraryTest.java @@ -35,6 +35,7 @@ import com.google.devtools.build.lib.packages.Provider; import com.google.devtools.build.lib.packages.StarlarkProvider; import com.google.devtools.build.lib.packages.StructImpl; +import com.google.devtools.build.lib.packages.util.MockProtoSupport; import com.google.devtools.build.lib.rules.java.JavaCompilationArgsProvider; import com.google.devtools.build.lib.rules.java.JavaCompileAction; import com.google.devtools.build.lib.rules.java.JavaInfo; @@ -59,25 +60,20 @@ public final void setUpMocks() throws Exception { useConfiguration( "--proto_compiler=//proto:compiler", "--proto_toolchain_for_javalite=//tools/proto/toolchains:javalite"); + MockProtoSupport.setup(mockToolsConfig); scratch.file("proto/BUILD", "licenses(['notice'])", "exports_files(['compiler'])"); mockToolchains(); + invalidatePackages(); actionsTestUtil = actionsTestUtil(); } - @Before - public final void setupStarlarkRule() throws Exception { - setBuildLanguageOptions( - "--experimental_builtins_injection_override=+java_lite_proto_library", - "--experimental_google_legacy_api"); - } - private void mockToolchains() throws IOException { mockRuntimes(); - scratch.file( + scratch.appendFile( "tools/proto/toolchains/BUILD", "package(default_visibility=['//visibility:public'])", "proto_lang_toolchain(", diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/J2ObjcLibraryTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/J2ObjcLibraryTest.java index 754e22fb144524..91556b3429aa9c 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/objc/J2ObjcLibraryTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/objc/J2ObjcLibraryTest.java @@ -76,7 +76,7 @@ public final void setup() throws Exception { useConfiguration("--proto_toolchain_for_java=//tools/proto/toolchains:java"); - mockToolsConfig.create( + mockToolsConfig.append( "tools/proto/toolchains/BUILD", TestConstants.LOAD_PROTO_LANG_TOOLCHAIN, "package(default_visibility=['//visibility:public'])", @@ -86,7 +86,6 @@ public final void setup() throws Exception { "proto_lang_toolchain(name='java_stubby_compatible13_immutable', " + "command_line = 'dont_care')"); - MockProtoSupport.setupWorkspace(scratch); invalidatePackages(); } } diff --git a/src/test/java/com/google/devtools/build/lib/rules/proto/BazelProtoCommonTest.java b/src/test/java/com/google/devtools/build/lib/rules/proto/BazelProtoCommonTest.java index 39dc3310d2ad06..e4b15301732538 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/proto/BazelProtoCommonTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/proto/BazelProtoCommonTest.java @@ -51,10 +51,8 @@ public class BazelProtoCommonTest extends BuildViewTestCase { @Before public final void setup() throws Exception { - MockProtoSupport.setupWorkspace(scratch); - invalidatePackages(); - MockProtoSupport.setup(mockToolsConfig); + invalidatePackages(); scratch.file( "third_party/x/BUILD", diff --git a/src/test/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibraryTest.java b/src/test/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibraryTest.java index 6fecb443298399..42e5e5662bfc39 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibraryTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/proto/BazelProtoLibraryTest.java @@ -31,6 +31,7 @@ import com.google.devtools.build.lib.packages.util.MockProtoSupport; import com.google.devtools.build.lib.testutil.TestConstants; import com.google.devtools.build.lib.vfs.FileSystemUtils; +import com.google.errorprone.annotations.CanIgnoreReturnValue; import java.util.List; import org.junit.Before; import org.junit.Ignore; @@ -48,12 +49,25 @@ private boolean isThisBazel() { @Before public void setUp() throws Exception { useConfiguration("--proto_compiler=//proto:compiler"); + MockProtoSupport.setup(mockToolsConfig); scratch.file("proto/BUILD", "licenses(['notice'])", "exports_files(['compiler'])"); - MockProtoSupport.setupWorkspace(scratch); invalidatePackages(); } + @Test + public void protoToolchainResolution_enabled() throws Exception { + setBuildLanguageOptions("--incompatible_enable_proto_toolchain_resolution"); + scratch.file( + "x/BUILD", + TestConstants.LOAD_PROTO_LIBRARY, + "proto_library(name='foo', srcs=['foo.proto'])"); + + getDescriptorOutput("//x:foo"); + + assertNoEvents(); + } + @Test public void createsDescriptorSets() throws Exception { scratch.file( @@ -1011,6 +1025,7 @@ public void testStripImportPrefixForExternalRepositories() throws Exception { .contains("-Iy/z/q.proto=" + genfiles + "/external/foo/x/y/_virtual_imports/q/y/z/q.proto"); } + @CanIgnoreReturnValue private Artifact getDescriptorOutput(String label) throws Exception { return getFirstArtifactEndingWith(getFilesToBuild(getConfiguredTarget(label)), ".proto.bin"); } diff --git a/src/test/java/com/google/devtools/build/lib/rules/proto/ProtoInfoStarlarkApiTest.java b/src/test/java/com/google/devtools/build/lib/rules/proto/ProtoInfoStarlarkApiTest.java index 9c4c4bcb2f2872..77796f73fd3ca6 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/proto/ProtoInfoStarlarkApiTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/proto/ProtoInfoStarlarkApiTest.java @@ -42,8 +42,6 @@ public void setUp() throws Exception { scratch.file("myinfo/myinfo.bzl", "MyInfo = provider()"); scratch.file("myinfo/BUILD"); MockProtoSupport.setup(mockToolsConfig); - - MockProtoSupport.setupWorkspace(scratch); invalidatePackages(); } diff --git a/src/test/java/com/google/devtools/build/lib/rules/proto/ProtoLangToolchainTest.java b/src/test/java/com/google/devtools/build/lib/rules/proto/ProtoLangToolchainTest.java index 23daa19494d566..8374ed89a8c5fd 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/proto/ProtoLangToolchainTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/proto/ProtoLangToolchainTest.java @@ -36,7 +36,6 @@ public class ProtoLangToolchainTest extends BuildViewTestCase { @Before public void setUp() throws Exception { - MockProtoSupport.setupWorkspace(scratch); MockProtoSupport.setup(mockToolsConfig); useConfiguration("--protocopt=--myflag"); invalidatePackages(); @@ -98,7 +97,8 @@ public void protoToolchain() throws Exception { } @Test - public void protoToolchain_setProtoCompiler() throws Exception { + public void protoToolchainResolution_enabled() throws Exception { + setBuildLanguageOptions("--incompatible_enable_proto_toolchain_resolution"); scratch.file( "third_party/x/BUILD", "licenses(['unencumbered'])", @@ -106,9 +106,7 @@ public void protoToolchain_setProtoCompiler() throws Exception { "cc_library(name = 'runtime', srcs = ['runtime.cc'])", "filegroup(name = 'descriptors', srcs = ['metadata.proto', 'descriptor.proto'])", "filegroup(name = 'any', srcs = ['any.proto'])", - "proto_library(name = 'denied', srcs = [':descriptors', ':any'])", - "cc_binary(name = 'compiler')"); - + "proto_library(name = 'denied', srcs = [':descriptors', ':any'])"); scratch.file( "foo/BUILD", TestConstants.LOAD_PROTO_LANG_TOOLCHAIN, @@ -121,14 +119,14 @@ public void protoToolchain_setProtoCompiler() throws Exception { " runtime = '//third_party/x:runtime',", " progress_message = 'Progress Message %{label}',", " mnemonic = 'MyMnemonic',", - " proto_compiler = '//third_party/x:compiler',", ")"); + update(ImmutableList.of("//foo:toolchain"), false, 1, true, new EventBus()); ProtoLangToolchainProvider toolchain = ProtoLangToolchainProvider.get(getConfiguredTarget("//foo:toolchain")); validateProtoLangToolchain(toolchain); - validateProtoCompiler(toolchain, "//third_party/x:compiler"); + validateProtoCompiler(toolchain, ProtoConstants.DEFAULT_PROTOC_LABEL); } @Test diff --git a/src/test/java/com/google/devtools/build/lib/testutil/TestConstants.java b/src/test/java/com/google/devtools/build/lib/testutil/TestConstants.java index c2061065eede90..60443846d6b585 100644 --- a/src/test/java/com/google/devtools/build/lib/testutil/TestConstants.java +++ b/src/test/java/com/google/devtools/build/lib/testutil/TestConstants.java @@ -26,6 +26,9 @@ public class TestConstants { public static final String LOAD_PROTO_LIBRARY = "load('@rules_proto//proto:defs.bzl', 'proto_library')"; + public static final String PROTO_TOOLCHAIN = "@rules_proto//proto:toolchain_type"; + public static final String LOAD_PROTO_TOOLCHAIN = + "load('@rules_proto//proto:proto_toolchain.bzl', 'proto_toolchain')"; public static final String LOAD_PROTO_LANG_TOOLCHAIN = "load('@rules_proto//proto:defs.bzl', 'proto_lang_toolchain')";