From 2a43e56b5f520c8ac4516f8a312a596dee4444d6 Mon Sep 17 00:00:00 2001 From: Jihoon Kang Date: Mon, 12 Feb 2024 19:05:12 +0000 Subject: [PATCH 1/2] Introduce module type aconfig_declarations_group In order to easily manage aconfig_declarations modules and their corresponding codegen modules, this change introduces a new module type `aconfig_declarations_group`. The module enables listing codegen modules by language, and correctly depend on the desired output files using appropriate tags. e.g. for an aconfig_declarations_group module "some_group", the rdeps of the module can: - gather all intermediates cache files of the aconfig_declarations with ":some_group" tag. - gather generated srcjar files of the listed java_aconfig_library modules with ":some_group{.srcjars}" tag. Output tag support for cc modules and rust modules will be added in future changes. Test: m nothing --no-skip-soong-tests Bug: 320492079 Change-Id: I93d737577f8d00198ed91048dd6e81ef238193cb --- aconfig/codegen/Android.bp | 2 + aconfig/codegen/aconfig_declarations_group.go | 129 ++++++++++++++++++ .../aconfig_declarations_group_test.go | 79 +++++++++++ aconfig/codegen/init.go | 1 + aconfig/codegen/java_aconfig_library.go | 7 + aconfig/init.go | 14 ++ 6 files changed, 232 insertions(+) create mode 100644 aconfig/codegen/aconfig_declarations_group.go create mode 100644 aconfig/codegen/aconfig_declarations_group_test.go diff --git a/aconfig/codegen/Android.bp b/aconfig/codegen/Android.bp index 494f7e693..0c78b946b 100644 --- a/aconfig/codegen/Android.bp +++ b/aconfig/codegen/Android.bp @@ -17,6 +17,7 @@ bootstrap_go_package { "soong-rust", ], srcs: [ + "aconfig_declarations_group.go", "cc_aconfig_library.go", "init.go", "java_aconfig_library.go", @@ -24,6 +25,7 @@ bootstrap_go_package { "testing.go", ], testSrcs: [ + "aconfig_declarations_group_test.go", "java_aconfig_library_test.go", "cc_aconfig_library_test.go", "rust_aconfig_library_test.go", diff --git a/aconfig/codegen/aconfig_declarations_group.go b/aconfig/codegen/aconfig_declarations_group.go new file mode 100644 index 000000000..203b6be6f --- /dev/null +++ b/aconfig/codegen/aconfig_declarations_group.go @@ -0,0 +1,129 @@ +// Copyright 2024 Google Inc. 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. + +package codegen + +import ( + "android/soong/aconfig" + "android/soong/android" + "fmt" + + "github.com/google/blueprint" +) + +type dependencyTag struct { + blueprint.BaseDependencyTag + name string +} + +var ( + aconfigDeclarationsGroupTag = dependencyTag{name: "aconfigDeclarationsGroup"} + javaAconfigLibraryTag = dependencyTag{name: "javaAconfigLibrary"} + ccAconfigLibraryTag = dependencyTag{name: "ccAconfigLibrary"} + rustAconfigLibraryTag = dependencyTag{name: "rustAconfigLibrary"} +) + +type AconfigDeclarationsGroup struct { + android.ModuleBase + android.DefaultableModuleBase + + properties AconfigDeclarationsGroupProperties + + aconfigDeclarationNames []string + intermediateCacheOutputPaths android.Paths + javaSrcjars android.Paths +} + +type AconfigDeclarationsGroupProperties struct { + + // Name of the aconfig_declarations_group modules + Aconfig_declarations_groups []string + + // Name of the java_aconfig_library modules + Java_aconfig_libraries []string + + // Name of the cc_aconfig_library modules + Cc_aconfig_libraries []string + + // Name of the rust_aconfig_library modules + Rust_aconfig_libraries []string +} + +func AconfigDeclarationsGroupFactory() android.Module { + module := &AconfigDeclarationsGroup{} + module.AddProperties(&module.properties) + android.InitAndroidModule(module) + android.InitDefaultableModule(module) + return module +} + +func (adg *AconfigDeclarationsGroup) DepsMutator(ctx android.BottomUpMutatorContext) { + ctx.AddDependency(ctx.Module(), aconfigDeclarationsGroupTag, adg.properties.Aconfig_declarations_groups...) + ctx.AddDependency(ctx.Module(), javaAconfigLibraryTag, adg.properties.Java_aconfig_libraries...) + ctx.AddDependency(ctx.Module(), ccAconfigLibraryTag, adg.properties.Cc_aconfig_libraries...) + ctx.AddDependency(ctx.Module(), rustAconfigLibraryTag, adg.properties.Rust_aconfig_libraries...) +} + +func (adg *AconfigDeclarationsGroup) VisitDeps(ctx android.ModuleContext) { + ctx.VisitDirectDeps(func(dep android.Module) { + tag := ctx.OtherModuleDependencyTag(dep) + if provider, ok := android.OtherModuleProvider(ctx, dep, aconfig.CodegenInfoProvider); ok { + + // aconfig declaration names and cache files are collected for all aconfig library dependencies + adg.aconfigDeclarationNames = append(adg.aconfigDeclarationNames, provider.AconfigDeclarations...) + adg.intermediateCacheOutputPaths = append(adg.intermediateCacheOutputPaths, provider.IntermediateCacheOutputPaths...) + + switch tag { + case aconfigDeclarationsGroupTag: + // Will retrieve outputs from another language codegen modules when support is added + adg.javaSrcjars = append(adg.javaSrcjars, provider.Srcjars...) + case javaAconfigLibraryTag: + adg.javaSrcjars = append(adg.javaSrcjars, provider.Srcjars...) + } + } + }) +} + +func (adg *AconfigDeclarationsGroup) GenerateAndroidBuildActions(ctx android.ModuleContext) { + adg.VisitDeps(ctx) + adg.aconfigDeclarationNames = android.FirstUniqueStrings(adg.aconfigDeclarationNames) + adg.intermediateCacheOutputPaths = android.FirstUniquePaths(adg.intermediateCacheOutputPaths) + + android.SetProvider(ctx, aconfig.CodegenInfoProvider, aconfig.CodegenInfo{ + AconfigDeclarations: adg.aconfigDeclarationNames, + IntermediateCacheOutputPaths: adg.intermediateCacheOutputPaths, + Srcjars: adg.javaSrcjars, + }) +} + +var _ android.OutputFileProducer = (*AconfigDeclarationsGroup)(nil) + +func (adg *AconfigDeclarationsGroup) OutputFiles(tag string) (android.Paths, error) { + switch tag { + case "": + return adg.intermediateCacheOutputPaths, nil + case ".srcjars": + return adg.javaSrcjars, nil + default: + return nil, fmt.Errorf("unsupported module reference tag %s", tag) + } +} + +func (adg *AconfigDeclarationsGroup) Srcjars() android.Paths { + return adg.javaSrcjars +} + +func (adg *AconfigDeclarationsGroup) AconfigDeclarations() []string { + return adg.aconfigDeclarationNames +} diff --git a/aconfig/codegen/aconfig_declarations_group_test.go b/aconfig/codegen/aconfig_declarations_group_test.go new file mode 100644 index 000000000..ec7cea383 --- /dev/null +++ b/aconfig/codegen/aconfig_declarations_group_test.go @@ -0,0 +1,79 @@ +// Copyright 2024 Google Inc. 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. + +package codegen + +import ( + "android/soong/android" + "android/soong/java" + "testing" +) + +func TestAconfigDeclarationsGroup(t *testing.T) { + result := android.GroupFixturePreparers( + PrepareForTestWithAconfigBuildComponents, + java.PrepareForTestWithJavaDefaultModules, + ).RunTestWithBp(t, ` + aconfig_declarations { + name: "foo-aconfig", + package: "com.example.package", + srcs: ["foo.aconfig"], + } + + java_aconfig_library { + name: "foo-java", + aconfig_declarations: "foo-aconfig", + } + + aconfig_declarations { + name: "bar-aconfig", + package: "com.example.package", + srcs: ["foo.aconfig"], + } + + java_aconfig_library { + name: "bar-java", + aconfig_declarations: "bar-aconfig", + } + + aconfig_declarations_group { + name: "my_group", + java_aconfig_libraries: [ + "foo-java", + "bar-java", + ], + } + + java_library { + name: "baz", + srcs: [ + ":my_group{.srcjars}", + ], + } + `) + + // Check if aconfig_declarations_group module depends on the aconfig_library modules + java.CheckModuleDependencies(t, result.TestContext, "my_group", "", []string{ + `bar-java`, + `foo-java`, + }) + + // Check if srcjar files are correctly passed to the reverse dependency of + // aconfig_declarations_group module + bazModule := result.ModuleForTests("baz", "android_common") + bazJavacSrcjars := bazModule.Rule("javac").Args["srcJars"] + errorMessage := "baz javac argument expected to contain srcjar provided by aconfig_declrations_group" + android.AssertStringDoesContain(t, errorMessage, bazJavacSrcjars, "foo-java.srcjar") + android.AssertStringDoesContain(t, errorMessage, bazJavacSrcjars, "bar-java.srcjar") +} diff --git a/aconfig/codegen/init.go b/aconfig/codegen/init.go index 0bff9d2af..73a89514d 100644 --- a/aconfig/codegen/init.go +++ b/aconfig/codegen/init.go @@ -77,6 +77,7 @@ func init() { } func RegisterBuildComponents(ctx android.RegistrationContext) { + ctx.RegisterModuleType("aconfig_declarations_group", AconfigDeclarationsGroupFactory) ctx.RegisterModuleType("cc_aconfig_library", CcAconfigLibraryFactory) ctx.RegisterModuleType("java_aconfig_library", JavaDeclarationsLibraryFactory) ctx.RegisterModuleType("rust_aconfig_library", RustAconfigLibraryFactory) diff --git a/aconfig/codegen/java_aconfig_library.go b/aconfig/codegen/java_aconfig_library.go index d4c6da574..7d7296e6a 100644 --- a/aconfig/codegen/java_aconfig_library.go +++ b/aconfig/codegen/java_aconfig_library.go @@ -17,6 +17,7 @@ package codegen import ( "fmt" + "android/soong/aconfig" "android/soong/android" "android/soong/java" @@ -118,6 +119,12 @@ func (callbacks *JavaAconfigDeclarationsLibraryCallbacks) GenerateSourceJarBuild module.AddJarJarRenameRule(declarations.Package+".FakeFeatureFlagsImpl", "") } + android.SetProvider(ctx, aconfig.CodegenInfoProvider, aconfig.CodegenInfo{ + AconfigDeclarations: []string{declarationsModules[0].Name()}, + IntermediateCacheOutputPaths: android.Paths{declarations.IntermediateCacheOutputPath}, + Srcjars: android.Paths{srcJarPath}, + }) + return srcJarPath } diff --git a/aconfig/init.go b/aconfig/init.go index 77f5ed363..16fb0cd9b 100644 --- a/aconfig/init.go +++ b/aconfig/init.go @@ -20,6 +20,20 @@ import ( "github.com/google/blueprint" ) +type CodegenInfo struct { + // AconfigDeclarations is the name of the aconfig_declarations modules that + // the codegen module is associated with + AconfigDeclarations []string + + // Paths to the cache files of the associated aconfig_declaration modules + IntermediateCacheOutputPaths android.Paths + + // Paths to the srcjar files generated from the java_aconfig_library modules + Srcjars android.Paths +} + +var CodegenInfoProvider = blueprint.NewProvider[CodegenInfo]() + var ( pctx = android.NewPackageContext("android/soong/aconfig") From 38e4f258f7431e12cc578d192c15e7410c35ce1d Mon Sep 17 00:00:00 2001 From: Jihoon Kang Date: Tue, 13 Feb 2024 20:49:47 +0000 Subject: [PATCH 2/2] Enable droidstubs to depend on aconfig_declarations_group module type This change enabled aconfig_declarations_group module type to be added as `aconfig_declarations` property of droidstubs module. Similar to aconfig_declrations module, the aconfig_declarations_group module provides the intermediate cache files of the aconfig_declarations modules of the listed codegen modules to droidstubs module. Test: m nothing --no-skip-soong-tests Change-Id: I42eb64d3ab65e679ea733c5bb98833971e49a8e8 --- java/droiddoc.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/java/droiddoc.go b/java/droiddoc.go index cfbf2b49c..6a66f45ec 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -21,6 +21,7 @@ import ( "github.com/google/blueprint/proptools" + "android/soong/aconfig" "android/soong/android" "android/soong/java/config" ) @@ -413,9 +414,12 @@ func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps { case aconfigDeclarationTag: if dep, ok := android.OtherModuleProvider(ctx, module, android.AconfigDeclarationsProviderKey); ok { deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.IntermediateCacheOutputPath) + } else if dep, ok := android.OtherModuleProvider(ctx, module, aconfig.CodegenInfoProvider); ok { + deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.IntermediateCacheOutputPaths...) } else { - ctx.ModuleErrorf("Only aconfig_declarations module type is allowed for "+ - "flags_packages property, but %s is not aconfig_declarations module type", + ctx.ModuleErrorf("Only aconfig_declarations and aconfig_declarations_group "+ + "module type is allowed for flags_packages property, but %s is neither "+ + "of these supported module types", module.Name(), ) }