From 289e9c607b973e9526f103916df0bb534eda4473 Mon Sep 17 00:00:00 2001 From: Alix Date: Wed, 16 Aug 2023 15:06:31 +0000 Subject: [PATCH] support for multiple filegroups and resource_dirs Test: tests in bp2build and b build //external/emma:emma Change-Id: I57e60389aec926c55d01818a6a3b1ec33e9c53b8 --- android/allowlists/allowlists.go | 3 + bp2build/java_library_conversion_test.go | 100 ++++++++++++++++++++++- java/java.go | 74 +++++++++++++---- 3 files changed, 155 insertions(+), 22 deletions(-) diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go index f411026aa..4c1636c14 100644 --- a/android/allowlists/allowlists.go +++ b/android/allowlists/allowlists.go @@ -856,6 +856,9 @@ var ( "hal_unit_tests", "merge_annotation_zips_test", + + // java_resources with multiple resource_dirs + "emma", } Bp2buildModuleTypeAlwaysConvertList = []string{ diff --git a/bp2build/java_library_conversion_test.go b/bp2build/java_library_conversion_test.go index c501a7bcb..5c769a53c 100644 --- a/bp2build/java_library_conversion_test.go +++ b/bp2build/java_library_conversion_test.go @@ -391,18 +391,56 @@ func TestJavaLibraryResourcesExcludeFile(t *testing.T) { }) } -func TestJavaLibraryResourcesFailsWithMultipleDirs(t *testing.T) { +func TestJavaLibraryResourcesWithMultipleDirs(t *testing.T) { runJavaLibraryTestCase(t, Bp2buildTestCase{ Filesystem: map[string]string{ "res/a.res": "", - "res1/a.res": "", + "res1/b.res": "", }, Blueprint: `java_library { name: "java-lib-1", java_resource_dirs: ["res", "res1"], }`, - ExpectedErr: fmt.Errorf("bp2build does not support more than one directory in java_resource_dirs (b/226423379)"), - ExpectedBazelTargets: []string{}, + ExpectedBazelTargets: []string{ + MakeBazelTarget("java_resources", "java-lib-1_resource_dir_res1", AttrNameToString{ + "resource_strip_prefix": `"res1"`, + "resources": `["res1/b.res"]`, + }), + MakeBazelTarget("java_library", "java-lib-1", AttrNameToString{ + "additional_resources": `["java-lib-1_resource_dir_res1"]`, + "resources": `["res/a.res"]`, + "resource_strip_prefix": `"res"`, + }), + MakeNeverlinkDuplicateTarget("java_library", "java-lib-1"), + }, + }) +} + +func TestJavaLibraryJavaResourcesAndResourceDirs(t *testing.T) { + runJavaLibraryTestCase(t, Bp2buildTestCase{ + Filesystem: map[string]string{ + "resdir/a.res": "", + }, + Blueprint: `java_library { + name: "java-lib-1", + java_resources: ["res1", "res2"], + java_resource_dirs: ["resdir"], +}`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("java_resources", "java-lib-1_resource_dir_resdir", AttrNameToString{ + "resource_strip_prefix": `"resdir"`, + "resources": `["resdir/a.res"]`, + }), + MakeBazelTarget("java_library", "java-lib-1", AttrNameToString{ + "additional_resources": `["java-lib-1_resource_dir_resdir"]`, + "resource_strip_prefix": `"."`, + "resources": `[ + "res1", + "res2", + ]`, + }), + MakeNeverlinkDuplicateTarget("java_library", "java-lib-1"), + }, }) } @@ -878,3 +916,57 @@ filegroup { ctx.RegisterModuleType("filegroup", android.FileGroupFactory) }) } + +func TestJavaLibraryJavaResourcesMultipleFilegroup(t *testing.T) { + runJavaLibraryTestCaseWithRegistrationCtxFunc(t, Bp2buildTestCase{ + Filesystem: map[string]string{ + "a.res": "", + }, + Description: "with java_resources that has multiple filegroups", + Blueprint: `java_library { + name: "java-lib-1", + srcs: ["a.java"], + java_resources: ["a.res", ":filegroup1", ":filegroup2"], + bazel_module: { bp2build_available: true }, +} + +filegroup { + name: "filegroup1", + path: "foo", + srcs: ["foo/a"], +} + +filegroup { + name: "filegroup2", + path: "bar", + srcs: ["bar/a"], +} +`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("java_resources", "java-lib-1_filegroup_resources_filegroup1", AttrNameToString{ + "resource_strip_prefix": `"foo"`, + "resources": `[":filegroup1"]`, + }), + MakeBazelTarget("java_resources", "java-lib-1_filegroup_resources_filegroup2", AttrNameToString{ + "resource_strip_prefix": `"bar"`, + "resources": `[":filegroup2"]`, + }), + MakeBazelTarget("java_library", "java-lib-1", AttrNameToString{ + "srcs": `["a.java"]`, + "resources": `["a.res"]`, + "resource_strip_prefix": `"."`, + "additional_resources": `[ + "java-lib-1_filegroup_resources_filegroup1", + "java-lib-1_filegroup_resources_filegroup2", + ]`, + }), + MakeNeverlinkDuplicateTarget("java_library", "java-lib-1"), + MakeBazelTargetNoRestrictions("filegroup", "filegroup1", AttrNameToString{ + "srcs": `["foo/a"]`}), + MakeBazelTargetNoRestrictions("filegroup", "filegroup2", AttrNameToString{ + "srcs": `["bar/a"]`}), + }, + }, func(ctx android.RegistrationContext) { + ctx.RegisterModuleType("filegroup", android.FileGroupFactory) + }) +} diff --git a/java/java.go b/java/java.go index 5f59fe401..31ab485f9 100644 --- a/java/java.go +++ b/java/java.go @@ -21,6 +21,7 @@ package java import ( "fmt" "path/filepath" + "sort" "strings" "android/soong/bazel" @@ -2755,32 +2756,41 @@ func addCLCFromDep(ctx android.ModuleContext, depModule android.Module, type javaResourcesAttributes struct { Resources bazel.LabelListAttribute Resource_strip_prefix *string + Additional_resources bazel.LabelListAttribute } -func (m *Library) javaResourcesGetSingleFilegroupStripPrefix(ctx android.TopDownMutatorContext) (string, bool) { - if otherM, ok := ctx.ModuleFromName(m.properties.Java_resources[0]); ok && len(m.properties.Java_resources) == 1 { +func (m *Library) getResourceFilegroupStripPrefix(ctx android.TopDownMutatorContext, resourceFilegroup string) (*string, bool) { + if otherM, ok := ctx.ModuleFromName(resourceFilegroup); ok { if fg, isFilegroup := otherM.(android.FileGroupPath); isFilegroup { - return filepath.Join(ctx.OtherModuleDir(otherM), fg.GetPath(ctx)), true + return proptools.StringPtr(filepath.Join(ctx.OtherModuleDir(otherM), fg.GetPath(ctx))), true } } - return "", false + return proptools.StringPtr(""), false } func (m *Library) convertJavaResourcesAttributes(ctx android.TopDownMutatorContext) *javaResourcesAttributes { var resources bazel.LabelList var resourceStripPrefix *string - if m.properties.Java_resources != nil && len(m.properties.Java_resource_dirs) > 0 { - ctx.ModuleErrorf("bp2build doesn't support both java_resources and java_resource_dirs being set on the same module.") - } + additionalJavaResourcesMap := make(map[string]*javaResourcesAttributes) if m.properties.Java_resources != nil { - if prefix, ok := m.javaResourcesGetSingleFilegroupStripPrefix(ctx); ok { - resourceStripPrefix = proptools.StringPtr(prefix) - } else { + for _, res := range m.properties.Java_resources { + if prefix, isFilegroup := m.getResourceFilegroupStripPrefix(ctx, res); isFilegroup { + otherM, _ := ctx.ModuleFromName(res) + resourcesTargetName := ctx.ModuleName() + "_filegroup_resources_" + otherM.Name() + additionalJavaResourcesMap[resourcesTargetName] = &javaResourcesAttributes{ + Resources: bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, []string{res})), + Resource_strip_prefix: prefix, + } + } else { + resources.Append(android.BazelLabelForModuleSrc(ctx, []string{res})) + } + } + + if !resources.IsEmpty() { resourceStripPrefix = proptools.StringPtr(ctx.ModuleDir()) } - resources.Append(android.BazelLabelForModuleSrc(ctx, m.properties.Java_resources)) } //TODO(b/179889880) handle case where glob includes files outside package @@ -2791,23 +2801,51 @@ func (m *Library) convertJavaResourcesAttributes(ctx android.TopDownMutatorConte m.properties.Exclude_java_resources, ) - for i, resDep := range resDeps { + for _, resDep := range resDeps { dir, files := resDep.dir, resDep.files - resources.Append(bazel.MakeLabelList(android.RootToModuleRelativePaths(ctx, files))) - // Bazel includes the relative path from the WORKSPACE root when placing the resource // inside the JAR file, so we need to remove that prefix - resourceStripPrefix = proptools.StringPtr(dir.String()) - if i > 0 { - // TODO(b/226423379) allow multiple resource prefixes - ctx.ModuleErrorf("bp2build does not support more than one directory in java_resource_dirs (b/226423379)") + prefix := proptools.StringPtr(dir.String()) + resourcesTargetName := ctx.ModuleName() + "_resource_dir_" + dir.String() + additionalJavaResourcesMap[resourcesTargetName] = &javaResourcesAttributes{ + Resources: bazel.MakeLabelListAttribute(bazel.MakeLabelList(android.RootToModuleRelativePaths(ctx, files))), + Resource_strip_prefix: prefix, } } + var additionalResourceLabels bazel.LabelList + if len(additionalJavaResourcesMap) > 0 { + var additionalResources []string + for resName, _ := range additionalJavaResourcesMap { + additionalResources = append(additionalResources, resName) + } + sort.Strings(additionalResources) + + for i, resName := range additionalResources { + resAttr := additionalJavaResourcesMap[resName] + if resourceStripPrefix == nil && i == 0 { + resourceStripPrefix = resAttr.Resource_strip_prefix + resources = resAttr.Resources.Value + } else { + ctx.CreateBazelTargetModule( + bazel.BazelTargetModuleProperties{ + Rule_class: "java_resources", + Bzl_load_location: "//build/bazel/rules/java:java_resources.bzl", + }, + android.CommonAttributes{Name: resName}, + resAttr, + ) + additionalResourceLabels.Append(android.BazelLabelForModuleSrc(ctx, []string{resName})) + } + } + + } + return &javaResourcesAttributes{ Resources: bazel.MakeLabelListAttribute(resources), Resource_strip_prefix: resourceStripPrefix, + Additional_resources: bazel.MakeLabelListAttribute(additionalResourceLabels), } }