From 774c6eaf103c3ffd4db54470bd044b621d5a3904 Mon Sep 17 00:00:00 2001 From: Zi Wang Date: Tue, 12 Sep 2023 10:24:35 -0700 Subject: [PATCH] Bp2build: handle the case where java_library has only proto srcs java_library doesn't accept deps when there are no srcs because no compilation happens, but it accepts exports. The deps from the module are not necessary for compiling the protos, in which case they are unnecessary as deps on the java_library as well since they are not be propagated to any dependencies. So we can put the deps to exports and drop deps here. Test: CI and added unit test Bug: 285952385 Change-Id: Ie54a4ac0db592fb96fede64f0e67df309dca9c1d --- bp2build/java_proto_conversion_test.go | 47 ++++++++++++++++++++++++++ java/java.go | 32 ++++++++++++++---- 2 files changed, 72 insertions(+), 7 deletions(-) diff --git a/bp2build/java_proto_conversion_test.go b/bp2build/java_proto_conversion_test.go index 5d6b08814..dfef6973c 100644 --- a/bp2build/java_proto_conversion_test.go +++ b/bp2build/java_proto_conversion_test.go @@ -137,3 +137,50 @@ func TestJavaProtoDefault(t *testing.T) { }, }) } + +func TestJavaLibsAndOnlyProtoSrcs(t *testing.T) { + runJavaProtoTestCase(t, Bp2buildTestCase{ + Description: "java_library that has only proto srcs", + Blueprint: `java_library_static { + name: "java-protos", + srcs: ["a.proto"], + libs: ["java-lib"], + java_version: "7", + sdk_version: "current", +} + +java_library_static { + name: "java-lib", + bazel_module: { bp2build_available: false }, +} +`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("proto_library", "java-protos_proto", AttrNameToString{ + "srcs": `["a.proto"]`, + }), + MakeBazelTarget( + "java_lite_proto_library", + "java-protos_java_proto_lite", + AttrNameToString{ + "deps": `[":java-protos_proto"]`, + "java_version": `"7"`, + "sdk_version": `"current"`, + }), + MakeBazelTarget("java_library", "java-protos", AttrNameToString{ + "exports": `[ + ":java-protos_java_proto_lite", + ":java-lib-neverlink", + ]`, + "java_version": `"7"`, + "sdk_version": `"current"`, + }), + MakeNeverlinkDuplicateTargetWithAttrs( + "java_library", + "java-protos", + AttrNameToString{ + "java_version": `"7"`, + "sdk_version": `"current"`, + }), + }, + }) +} diff --git a/java/java.go b/java/java.go index 99bb1b3ee..a81abe61c 100644 --- a/java/java.go +++ b/java/java.go @@ -2885,8 +2885,9 @@ type javaAidlLibraryAttributes struct { // depending on the module type. type bp2BuildJavaInfo struct { // separates dependencies into dynamic dependencies and static dependencies. - DepLabels *javaDependencyLabels - hasKotlin bool + DepLabels *javaDependencyLabels + hasKotlin bool + onlyProtoInSrcs bool } func javaXsdTargetName(xsd android.XsdConfigBp2buildTargets) string { @@ -2949,6 +2950,9 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) staticDeps.Append(srcPartitions[xsdSrcPartition]) + _, protoInSrcs := srcPartitions[protoSrcPartition] + onlyProtoInSrcs := protoInSrcs && len(srcPartitions) == 1 + if !srcPartitions[logtagSrcPartition].IsEmpty() { logtagsLibName := m.Name() + "_logtags" ctx.CreateBazelTargetModule( @@ -3086,8 +3090,9 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) } bp2BuildInfo := &bp2BuildJavaInfo{ - DepLabels: depLabels, - hasKotlin: hasKotlin, + DepLabels: depLabels, + hasKotlin: hasKotlin, + onlyProtoInSrcs: onlyProtoInSrcs, } return commonAttrs, bp2BuildInfo, true @@ -3127,16 +3132,29 @@ func javaLibraryBp2Build(ctx android.TopDownMutatorContext, m *Library) { depLabels := bp2BuildInfo.DepLabels deps := depLabels.Deps + exports := depLabels.StaticDeps if !commonAttrs.Srcs.IsEmpty() { - deps.Append(depLabels.StaticDeps) // we should only append these if there are sources to use them + deps.Append(exports) // we should only append these if there are sources to use them } else if !deps.IsEmpty() { - ctx.ModuleErrorf("Module has direct dependencies but no sources. Bazel will not allow this.") + if bp2BuildInfo.onlyProtoInSrcs { + // java_library does not accept deps when there are no srcs because + // there is no compilation happening, but it accepts exports. + // bp2build converts this module to 2 java_libraries + java_xx_proto_library + proto_library + // the non-empty deps here are not necessary for compiling the protos, in which case + // they're unnecessary as deps on the java_library as well since they aren't + // being propagated to any dependencies. + // so we can put the deps to exports and drop deps here. + exports.Append(deps) + deps = bazel.LabelListAttribute{} + } else { + ctx.ModuleErrorf("Module has direct dependencies but no sources. Bazel will not allow this.") + } } var props bazel.BazelTargetModuleProperties attrs := &javaLibraryAttributes{ javaCommonAttributes: commonAttrs, Deps: deps, - Exports: depLabels.StaticDeps, + Exports: exports, } name := m.Name()