diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go index 5c79fa2a2..0bc746296 100644 --- a/android/allowlists/allowlists.go +++ b/android/allowlists/allowlists.go @@ -157,6 +157,7 @@ var ( "frameworks/av/media/liberror": Bp2BuildDefaultTrueRecursively, "frameworks/av/services/minijail": Bp2BuildDefaultTrueRecursively, "frameworks/base/media/tests/MediaDump": Bp2BuildDefaultTrue, + "frameworks/base/services/tests/servicestests/aidl": Bp2BuildDefaultTrue, "frameworks/base/startop/apps/test": Bp2BuildDefaultTrue, "frameworks/base/tests/appwidgets/AppWidgetHostTest": Bp2BuildDefaultTrueRecursively, "frameworks/native/libs/adbd_auth": Bp2BuildDefaultTrueRecursively, @@ -408,6 +409,7 @@ var ( "linker_config", "java_import", "java_import_host", + "aidl_interface_headers", } Bp2buildModuleDoNotConvertList = []string{ diff --git a/android/filegroup.go b/android/filegroup.go index 7d3923814..e609f6362 100644 --- a/android/filegroup.go +++ b/android/filegroup.go @@ -16,6 +16,7 @@ package android import ( "path/filepath" + "regexp" "strings" "android/soong/bazel" @@ -37,6 +38,34 @@ func IsFilegroup(ctx bazel.OtherModuleContext, m blueprint.Module) bool { return ctx.OtherModuleType(m) == "filegroup" } +var ( + // ignoring case, checks for proto or protos as an independent word in the name, whether at the + // beginning, end, or middle. e.g. "proto.foo", "bar-protos", "baz_proto_srcs" would all match + filegroupLikelyProtoPattern = regexp.MustCompile("(?i)(^|[^a-z])proto(s)?([^a-z]|$)") + filegroupLikelyAidlPattern = regexp.MustCompile("(?i)(^|[^a-z])aidl([^a-z]|$)") + + ProtoSrcLabelPartition = bazel.LabelPartition{ + Extensions: []string{".proto"}, + LabelMapper: isFilegroupWithPattern(filegroupLikelyProtoPattern), + } + AidlSrcLabelPartition = bazel.LabelPartition{ + Extensions: []string{".aidl"}, + LabelMapper: isFilegroupWithPattern(filegroupLikelyAidlPattern), + } +) + +func isFilegroupWithPattern(pattern *regexp.Regexp) bazel.LabelMapper { + return func(ctx bazel.OtherModuleContext, label bazel.Label) (string, bool) { + m, exists := ctx.ModuleFromName(label.OriginalModuleName) + labelStr := label.Label + if !exists || !IsFilegroup(ctx, m) { + return labelStr, false + } + likelyMatched := pattern.MatchString(label.OriginalModuleName) + return labelStr, likelyMatched + } +} + // https://docs.bazel.build/versions/master/be/general.html#filegroup type bazelFilegroupAttributes struct { Srcs bazel.LabelListAttribute @@ -232,3 +261,16 @@ func (fg *fileGroup) GetAidlLibraryLabel(ctx BazelConversionPathContext) string return fg.GetBazelLabel(ctx, fg) } } + +// Given a name in srcs prop, check to see if the name references a filegroup +// and the filegroup is converted to aidl_library +func IsConvertedToAidlLibrary(ctx BazelConversionPathContext, name string) bool { + if module, ok := ctx.ModuleFromName(name); ok { + if IsFilegroup(ctx, module) { + if fg, ok := module.(Bp2buildAidlLibrary); ok { + return fg.ShouldConvertToAidlLibrary(ctx) + } + } + } + return false +} diff --git a/android/proto.go b/android/proto.go index c3759f8ad..8ad16a6a3 100644 --- a/android/proto.go +++ b/android/proto.go @@ -16,7 +16,6 @@ package android import ( "android/soong/bazel" - "regexp" "strings" "github.com/google/blueprint" @@ -27,14 +26,6 @@ const ( canonicalPathFromRootDefault = true ) -var ( - // ignoring case, checks for proto or protos as an independent word in the name, whether at the - // beginning, end, or middle. e.g. "proto.foo", "bar-protos", "baz_proto_srcs" would all match - filegroupLikelyProtoPattern = regexp.MustCompile("(?i)(^|[^a-z])proto(s)?([^a-z]|$)") - - ProtoSrcLabelPartition = bazel.LabelPartition{Extensions: []string{".proto"}, LabelMapper: isProtoFilegroup} -) - // TODO(ccross): protos are often used to communicate between multiple modules. If the only // way to convert a proto to source is to reference it as a source file, and external modules cannot // reference source files in other modules, then every module that owns a proto file will need to @@ -213,13 +204,3 @@ func Bp2buildProtoProperties(ctx Bp2buildMutatorContext, m *ModuleBase, srcs baz return info, true } - -func isProtoFilegroup(ctx bazel.OtherModuleContext, label bazel.Label) (string, bool) { - m, exists := ctx.ModuleFromName(label.OriginalModuleName) - labelStr := label.Label - if !exists || !IsFilegroup(ctx, m) { - return labelStr, false - } - likelyProtos := filegroupLikelyProtoPattern.MatchString(label.OriginalModuleName) - return labelStr, likelyProtos -} diff --git a/bp2build/java_library_conversion_test.go b/bp2build/java_library_conversion_test.go index 7fa19d950..f5a59382c 100644 --- a/bp2build/java_library_conversion_test.go +++ b/bp2build/java_library_conversion_test.go @@ -372,3 +372,132 @@ func TestJavaLibraryResourcesFailsWithMultipleDirs(t *testing.T) { ExpectedBazelTargets: []string{}, }) } + +func TestJavaLibraryAidl(t *testing.T) { + runJavaLibraryTestCase(t, Bp2buildTestCase{ + Description: "Java library - aidl creates separate dependency", + ModuleTypeUnderTest: "java_library", + ModuleTypeUnderTestFactory: java.LibraryFactory, + Blueprint: `java_library { + name: "example_lib", + srcs: [ + "a.java", + "b.java", + "a.aidl", + "b.aidl", + ], + bazel_module: { bp2build_available: true }, +}`, + ExpectedBazelTargets: []string{ + makeBazelTarget("aidl_library", "example_lib_aidl_library", AttrNameToString{ + "srcs": `[ + "a.aidl", + "b.aidl", + ]`, + }), + makeBazelTarget("java_aidl_library", "example_lib_java_aidl_library", AttrNameToString{ + "deps": `[":example_lib_aidl_library"]`, + }), + makeBazelTarget("java_library", "example_lib", AttrNameToString{ + "deps": `[":example_lib_java_aidl_library"]`, + "exports": `[":example_lib_java_aidl_library"]`, + "srcs": `[ + "a.java", + "b.java", + ]`, + }), + }}) +} + +func TestJavaLibraryAidlSrcsNoFileGroup(t *testing.T) { + runJavaLibraryTestCaseWithRegistrationCtxFunc(t, Bp2buildTestCase{ + Description: "Java library - aidl filegroup is parsed", + ModuleTypeUnderTest: "java_library", + ModuleTypeUnderTestFactory: java.LibraryFactory, + Blueprint: ` +java_library { + name: "example_lib", + srcs: [ + "a.java", + "b.aidl", + ], + bazel_module: { bp2build_available: true }, +}`, + ExpectedBazelTargets: []string{ + makeBazelTarget("aidl_library", "example_lib_aidl_library", AttrNameToString{ + "srcs": `["b.aidl"]`, + }), + makeBazelTarget("java_aidl_library", "example_lib_java_aidl_library", AttrNameToString{ + "deps": `[":example_lib_aidl_library"]`, + }), + makeBazelTarget("java_library", "example_lib", AttrNameToString{ + "deps": `[":example_lib_java_aidl_library"]`, + "exports": `[":example_lib_java_aidl_library"]`, + "srcs": `["a.java"]`, + }), + }, + }, func(ctx android.RegistrationContext) { + ctx.RegisterModuleType("filegroup", android.FileGroupFactory) + }) +} + +func TestJavaLibraryAidlFilegroup(t *testing.T) { + runJavaLibraryTestCaseWithRegistrationCtxFunc(t, Bp2buildTestCase{ + Description: "Java library - aidl filegroup is parsed", + ModuleTypeUnderTest: "java_library", + ModuleTypeUnderTestFactory: java.LibraryFactory, + Blueprint: ` +filegroup { + name: "random_other_files", + srcs: [ + "a.java", + "b.java", + ], +} +filegroup { + name: "aidl_files", + srcs: [ + "a.aidl", + "b.aidl", + ], +} +java_library { + name: "example_lib", + srcs: [ + "a.java", + "b.java", + ":aidl_files", + ":random_other_files", + ], + bazel_module: { bp2build_available: true }, +}`, + ExpectedBazelTargets: []string{ + MakeBazelTargetNoRestrictions("aidl_library", "aidl_files", AttrNameToString{ + "srcs": `[ + "a.aidl", + "b.aidl", + ]`, + }), + makeBazelTarget("java_aidl_library", "example_lib_java_aidl_library", AttrNameToString{ + "deps": `[":aidl_files"]`, + }), + makeBazelTarget("java_library", "example_lib", AttrNameToString{ + "deps": `[":example_lib_java_aidl_library"]`, + "exports": `[":example_lib_java_aidl_library"]`, + "srcs": `[ + "a.java", + "b.java", + ":random_other_files", + ]`, + }), + MakeBazelTargetNoRestrictions("filegroup", "random_other_files", AttrNameToString{ + "srcs": `[ + "a.java", + "b.java", + ]`, + }), + }, + }, func(ctx android.RegistrationContext) { + ctx.RegisterModuleType("filegroup", android.FileGroupFactory) + }) +} diff --git a/java/java.go b/java/java.go index 210b883e1..0251b5754 100644 --- a/java/java.go +++ b/java/java.go @@ -2259,16 +2259,27 @@ type javaDependencyLabels struct { StaticDeps bazel.LabelListAttribute } -// convertLibraryAttrsBp2Build converts a few shared attributes from java_* modules -// and also separates dependencies into dynamic dependencies and static dependencies. -// Each corresponding Bazel target type, can have a different method for handling -// dynamic vs. static dependencies, and so these are returned to the calling function. type eventLogTagsAttributes struct { Srcs bazel.LabelListAttribute } +type aidlLibraryAttributes struct { + Srcs bazel.LabelListAttribute +} + +type javaAidlLibraryAttributes struct { + Deps bazel.LabelListAttribute +} + +// convertLibraryAttrsBp2Build converts a few shared attributes from java_* modules +// and also separates dependencies into dynamic dependencies and static dependencies. +// Each corresponding Bazel target type, can have a different method for handling +// dynamic vs. static dependencies, and so these are returned to the calling function. func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) (*javaCommonAttributes, *javaDependencyLabels) { var srcs bazel.LabelListAttribute + var deps bazel.LabelList + var staticDeps bazel.LabelList + archVariantProps := m.GetArchVariantProperties(ctx, &CommonProperties{}) for axis, configToProps := range archVariantProps { for config, _props := range configToProps { @@ -2282,18 +2293,18 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) javaSrcPartition := "java" protoSrcPartition := "proto" logtagSrcPartition := "logtag" + aidlSrcPartition := "aidl" srcPartitions := bazel.PartitionLabelListAttribute(ctx, &srcs, bazel.LabelPartitions{ javaSrcPartition: bazel.LabelPartition{Extensions: []string{".java"}, Keep_remainder: true}, logtagSrcPartition: bazel.LabelPartition{Extensions: []string{".logtags", ".logtag"}}, protoSrcPartition: android.ProtoSrcLabelPartition, + aidlSrcPartition: android.AidlSrcLabelPartition, }) javaSrcs := srcPartitions[javaSrcPartition] - var logtagsSrcs bazel.LabelList if !srcPartitions[logtagSrcPartition].IsEmpty() { logtagsLibName := m.Name() + "_logtags" - logtagsSrcs = bazel.MakeLabelList([]bazel.Label{{Label: ":" + logtagsLibName}}) ctx.CreateBazelTargetModule( bazel.BazelTargetModuleProperties{ Rule_class: "event_log_tags", @@ -2304,8 +2315,45 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) Srcs: srcPartitions[logtagSrcPartition], }, ) + + logtagsSrcs := bazel.MakeLabelList([]bazel.Label{{Label: ":" + logtagsLibName}}) + javaSrcs.Append(bazel.MakeLabelListAttribute(logtagsSrcs)) + } + + if !srcPartitions[aidlSrcPartition].IsEmpty() { + aidlLibs, aidlSrcs := srcPartitions[aidlSrcPartition].Partition(func(src bazel.Label) bool { + return android.IsConvertedToAidlLibrary(ctx, src.OriginalModuleName) + }) + + if !aidlSrcs.IsEmpty() { + aidlLibName := m.Name() + "_aidl_library" + ctx.CreateBazelTargetModule( + bazel.BazelTargetModuleProperties{ + Rule_class: "aidl_library", + Bzl_load_location: "//build/bazel/rules/aidl:library.bzl", + }, + android.CommonAttributes{Name: aidlLibName}, + &aidlLibraryAttributes{ + Srcs: aidlSrcs, + }, + ) + aidlLibs.Add(&bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + aidlLibName}}) + } + + javaAidlLibName := m.Name() + "_java_aidl_library" + ctx.CreateBazelTargetModule( + bazel.BazelTargetModuleProperties{ + Rule_class: "java_aidl_library", + Bzl_load_location: "//build/bazel/rules/java:aidl_library.bzl", + }, + android.CommonAttributes{Name: javaAidlLibName}, + &javaAidlLibraryAttributes{ + Deps: aidlLibs, + }, + ) + + staticDeps.Add(&bazel.Label{Label: ":" + javaAidlLibName}) } - javaSrcs.Append(bazel.MakeLabelListAttribute(logtagsSrcs)) var javacopts []string if m.properties.Javacflags != nil { @@ -2331,14 +2379,10 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) Javacopts: bazel.MakeStringListAttribute(javacopts), } - depLabels := &javaDependencyLabels{} - - var deps bazel.LabelList if m.properties.Libs != nil { deps.Append(android.BazelLabelForModuleDeps(ctx, android.LastUniqueStrings(android.CopyOf(m.properties.Libs)))) } - var staticDeps bazel.LabelList if m.properties.Static_libs != nil { staticDeps.Append(android.BazelLabelForModuleDeps(ctx, android.LastUniqueStrings(android.CopyOf(m.properties.Static_libs)))) } @@ -2352,6 +2396,7 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) // and so this should be a static dependency. staticDeps.Add(protoDepLabel) + depLabels := &javaDependencyLabels{} depLabels.Deps = bazel.MakeLabelListAttribute(deps) depLabels.StaticDeps = bazel.MakeLabelListAttribute(staticDeps) @@ -2376,7 +2421,7 @@ func javaLibraryBp2Build(ctx android.TopDownMutatorContext, m *Library) { // TODO(b/220869005) remove forced dependency on current public android.jar deps.Add(bazel.MakeLabelAttribute("//prebuilts/sdk:public_current_android_sdk_java_import")) } - } else if !depLabels.Deps.IsEmpty() { + } else if !deps.IsEmpty() { ctx.ModuleErrorf("Module has direct dependencies but no sources. Bazel will not allow this.") }