Loading aconfig/aconfig_declarations.go +109 −49 Original line number Diff line number Diff line Loading @@ -15,6 +15,8 @@ package aconfig import ( "path/filepath" "slices" "strings" "android/soong/android" Loading @@ -22,6 +24,11 @@ import ( "github.com/google/blueprint" ) type AconfigReleaseConfigValue struct { ReleaseConfig string Values []string `blueprint:"mutated"` } type DeclarationsModule struct { android.ModuleBase android.DefaultableModuleBase Loading @@ -34,8 +41,10 @@ type DeclarationsModule struct { // Release config flag package Package string // Values from TARGET_RELEASE / RELEASE_ACONFIG_VALUE_SETS Values []string `blueprint:"mutated"` // Values for release configs / RELEASE_ACONFIG_VALUE_SETS // The current release config is `ReleaseConfig: ""`, others // are from RELEASE_ACONFIG_EXTRA_RELEASE_CONFIGS. ReleaseConfigValues []AconfigReleaseConfigValue // Container(system/vendor/apex) that this module belongs to Container string Loading @@ -57,6 +66,10 @@ func DeclarationsFactory() android.Module { type implicitValuesTagType struct { blueprint.BaseDependencyTag // The release config name for these values. // Empty string for the actual current release config. ReleaseConfig string } var implicitValuesTag = implicitValuesTagType{} Loading @@ -81,6 +94,11 @@ func (module *DeclarationsModule) DepsMutator(ctx android.BottomUpMutatorContext if len(valuesFromConfig) > 0 { ctx.AddDependency(ctx.Module(), implicitValuesTag, valuesFromConfig...) } for rcName, valueSets := range ctx.Config().ReleaseAconfigExtraReleaseConfigsValueSets() { if len(valueSets) > 0 { ctx.AddDependency(ctx.Module(), implicitValuesTagType{ReleaseConfig: rcName}, valueSets...) } } } func joinAndPrefix(prefix string, values []string) string { Loading @@ -101,33 +119,72 @@ func optionalVariable(prefix string, value string) string { return sb.String() } // Assemble the actual filename. // If `rcName` is not empty, then insert "-{rcName}" into the path before the // file extension. func assembleFileName(rcName, path string) string { if rcName == "" { return path } dir, file := filepath.Split(path) rcName = "-" + rcName ext := filepath.Ext(file) base := file[:len(file)-len(ext)] return dir + base + rcName + ext } func (module *DeclarationsModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { // Get the values that came from the global RELEASE_ACONFIG_VALUE_SETS flag valuesFiles := make([]android.Path, 0) // Determine which release configs we are processing. // // We always process the current release config (empty string). // We may have been told to also create artifacts for some others. configs := append([]string{""}, ctx.Config().ReleaseAconfigExtraReleaseConfigs()...) slices.Sort(configs) values := make(map[string][]string) valuesFiles := make(map[string][]android.Path, 0) providerData := android.AconfigReleaseDeclarationsProviderData{} ctx.VisitDirectDeps(func(dep android.Module) { if depData, ok := android.OtherModuleProvider(ctx, dep, valueSetProviderKey); ok { depTag := ctx.OtherModuleDependencyTag(dep) for _, config := range configs { tag := implicitValuesTagType{ReleaseConfig: config} if depTag == tag { paths, ok := depData.AvailablePackages[module.properties.Package] if ok { valuesFiles = append(valuesFiles, paths...) valuesFiles[config] = append(valuesFiles[config], paths...) for _, path := range paths { module.properties.Values = append(module.properties.Values, path.String()) values[config] = append(values[config], path.String()) } } } } } }) for _, config := range configs { module.properties.ReleaseConfigValues = append(module.properties.ReleaseConfigValues, AconfigReleaseConfigValue{ ReleaseConfig: config, Values: values[config], }) // Intermediate format declarationFiles := android.PathsForModuleSrc(ctx, module.properties.Srcs) intermediateCacheFilePath := android.PathForModuleOut(ctx, "intermediate.pb") defaultPermission := ctx.Config().ReleaseAconfigFlagDefaultPermission() intermediateCacheFilePath := android.PathForModuleOut(ctx, assembleFileName(config, "intermediate.pb")) var defaultPermission string defaultPermission = ctx.Config().ReleaseAconfigFlagDefaultPermission() if config != "" { if confPerm, ok := ctx.Config().GetBuildFlag("RELEASE_ACONFIG_FLAG_DEFAULT_PERMISSION_" + config); ok { defaultPermission = confPerm } } inputFiles := make([]android.Path, len(declarationFiles)) copy(inputFiles, declarationFiles) inputFiles = append(inputFiles, valuesFiles...) inputFiles = append(inputFiles, valuesFiles[config]...) args := map[string]string{ "release_version": ctx.Config().ReleaseVersion(), "package": module.properties.Package, "declarations": android.JoinPathsWithPrefix(declarationFiles, "--declarations "), "values": joinAndPrefix(" --values ", module.properties.Values), "values": joinAndPrefix(" --values ", values[config]), "default-permission": optionalVariable(" --default-permission ", defaultPermission), } if len(module.properties.Container) > 0 { Loading @@ -141,7 +198,7 @@ func (module *DeclarationsModule) GenerateAndroidBuildActions(ctx android.Module Args: args, }) intermediateDumpFilePath := android.PathForModuleOut(ctx, "intermediate.txt") intermediateDumpFilePath := android.PathForModuleOut(ctx, assembleFileName(config, "intermediate.txt")) ctx.Build(pctx, android.BuildParams{ Rule: aconfigTextRule, Output: intermediateDumpFilePath, Loading @@ -149,11 +206,14 @@ func (module *DeclarationsModule) GenerateAndroidBuildActions(ctx android.Module Description: "aconfig_text", }) android.SetProvider(ctx, android.AconfigDeclarationsProviderKey, android.AconfigDeclarationsProviderData{ providerData[config] = android.AconfigDeclarationsProviderData{ Package: module.properties.Package, Container: module.properties.Container, Exportable: module.properties.Exportable, IntermediateCacheOutputPath: intermediateCacheFilePath, IntermediateDumpOutputPath: intermediateDumpFilePath, }) } } android.SetProvider(ctx, android.AconfigDeclarationsProviderKey, providerData[""]) android.SetProvider(ctx, android.AconfigReleaseDeclarationsProviderKey, providerData) } aconfig/aconfig_declarations_test.go +93 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ package aconfig import ( "slices" "strings" "testing" Loading Loading @@ -134,3 +135,95 @@ func TestMandatoryProperties(t *testing.T) { }) } } func TestAssembleFileName(t *testing.T) { testCases := []struct { name string releaseConfig string path string expectedValue string }{ { name: "active release config", path: "file.path", expectedValue: "file.path", }, { name: "release config FOO", releaseConfig: "FOO", path: "file.path", expectedValue: "file-FOO.path", }, } for _, test := range testCases { actualValue := assembleFileName(test.releaseConfig, test.path) if actualValue != test.expectedValue { t.Errorf("Expected %q found %q", test.expectedValue, actualValue) } } } func TestGenerateAndroidBuildActions(t *testing.T) { testCases := []struct { name string buildFlags map[string]string bp string errorHandler android.FixtureErrorHandler }{ { name: "generate extra", buildFlags: map[string]string{ "RELEASE_ACONFIG_EXTRA_RELEASE_CONFIGS": "config2", "RELEASE_ACONFIG_VALUE_SETS": "aconfig_value_set-config1", "RELEASE_ACONFIG_VALUE_SETS_config2": "aconfig_value_set-config2", }, bp: ` aconfig_declarations { name: "module_name", package: "com.example.package", container: "com.android.foo", srcs: [ "foo.aconfig", "bar.aconfig", ], } aconfig_value_set { name: "aconfig_value_set-config1", values: [] } aconfig_value_set { name: "aconfig_value_set-config2", values: [] } `, }, } for _, test := range testCases { fixture := PrepareForTest(t, addBuildFlagsForTest(test.buildFlags)) if test.errorHandler != nil { fixture = fixture.ExtendWithErrorHandler(test.errorHandler) } result := fixture.RunTestWithBp(t, test.bp) module := result.ModuleForTests("module_name", "").Module().(*DeclarationsModule) depData, _ := android.SingletonModuleProvider(result, module, android.AconfigReleaseDeclarationsProviderKey) expectedKeys := []string{""} for _, rc := range strings.Split(test.buildFlags["RELEASE_ACONFIG_EXTRA_RELEASE_CONFIGS"], " ") { expectedKeys = append(expectedKeys, rc) } slices.Sort(expectedKeys) actualKeys := []string{} for rc := range depData { actualKeys = append(actualKeys, rc) } slices.Sort(actualKeys) android.AssertStringEquals(t, "provider keys", strings.Join(expectedKeys, " "), strings.Join(actualKeys, " ")) for _, rc := range actualKeys { if !strings.HasSuffix(depData[rc].IntermediateCacheOutputPath.String(), assembleFileName(rc, "/intermediate.pb")) { t.Errorf("Incorrect intermediates proto path in provider for release config %s: %s", rc, depData[rc].IntermediateCacheOutputPath.String()) } if !strings.HasSuffix(depData[rc].IntermediateDumpOutputPath.String(), assembleFileName(rc, "/intermediate.txt")) { t.Errorf("Incorrect intermediates text path in provider for release config %s: %s", rc, depData[rc].IntermediateDumpOutputPath.String()) } } } } aconfig/all_aconfig_declarations.go +71 −50 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package aconfig import ( "android/soong/android" "fmt" "slices" ) // A singleton module that collects all of the aconfig flags declared in the Loading @@ -27,25 +28,39 @@ import ( // ones that are relevant to the product currently being built, so that that infra // doesn't need to pull from multiple builds and merge them. func AllAconfigDeclarationsFactory() android.Singleton { return &allAconfigDeclarationsSingleton{} return &allAconfigDeclarationsSingleton{releaseMap: make(map[string]allAconfigReleaseDeclarationsSingleton)} } type allAconfigDeclarationsSingleton struct { type allAconfigReleaseDeclarationsSingleton struct { intermediateBinaryProtoPath android.OutputPath intermediateTextProtoPath android.OutputPath } type allAconfigDeclarationsSingleton struct { releaseMap map[string]allAconfigReleaseDeclarationsSingleton } func (this *allAconfigDeclarationsSingleton) sortedConfigNames() []string { var names []string for k := range this.releaseMap { names = append(names, k) } slices.Sort(names) return names } func (this *allAconfigDeclarationsSingleton) GenerateBuildActions(ctx android.SingletonContext) { for _, rcName := range append([]string{""}, ctx.Config().ReleaseAconfigExtraReleaseConfigs()...) { // Find all of the aconfig_declarations modules var packages = make(map[string]int) var cacheFiles android.Paths ctx.VisitAllModules(func(module android.Module) { decl, ok := android.SingletonModuleProvider(ctx, module, android.AconfigDeclarationsProviderKey) decl, ok := android.SingletonModuleProvider(ctx, module, android.AconfigReleaseDeclarationsProviderKey) if !ok { return } cacheFiles = append(cacheFiles, decl.IntermediateCacheOutputPath) packages[decl.Package]++ cacheFiles = append(cacheFiles, decl[rcName].IntermediateCacheOutputPath) packages[decl[rcName].Package]++ }) var numOffendingPkg = 0 Loading @@ -61,36 +76,42 @@ func (this *allAconfigDeclarationsSingleton) GenerateBuildActions(ctx android.Si } // Generate build action for aconfig (binary proto output) this.intermediateBinaryProtoPath = android.PathForIntermediates(ctx, "all_aconfig_declarations.pb") paths := allAconfigReleaseDeclarationsSingleton{ intermediateBinaryProtoPath: android.PathForIntermediates(ctx, assembleFileName(rcName, "all_aconfig_declarations.pb")), intermediateTextProtoPath: android.PathForIntermediates(ctx, assembleFileName(rcName, "all_aconfig_declarations.textproto")), } this.releaseMap[rcName] = paths ctx.Build(pctx, android.BuildParams{ Rule: AllDeclarationsRule, Inputs: cacheFiles, Output: this.intermediateBinaryProtoPath, Output: this.releaseMap[rcName].intermediateBinaryProtoPath, Description: "all_aconfig_declarations", Args: map[string]string{ "cache_files": android.JoinPathsWithPrefix(cacheFiles, "--cache "), }, }) ctx.Phony("all_aconfig_declarations", this.intermediateBinaryProtoPath) ctx.Phony("all_aconfig_declarations", this.releaseMap[rcName].intermediateBinaryProtoPath) // Generate build action for aconfig (text proto output) this.intermediateTextProtoPath = android.PathForIntermediates(ctx, "all_aconfig_declarations.textproto") ctx.Build(pctx, android.BuildParams{ Rule: AllDeclarationsRuleTextProto, Inputs: cacheFiles, Output: this.intermediateTextProtoPath, Output: this.releaseMap[rcName].intermediateTextProtoPath, Description: "all_aconfig_declarations_textproto", Args: map[string]string{ "cache_files": android.JoinPathsWithPrefix(cacheFiles, "--cache "), }, }) ctx.Phony("all_aconfig_declarations_textproto", this.intermediateTextProtoPath) ctx.Phony("all_aconfig_declarations_textproto", this.releaseMap[rcName].intermediateTextProtoPath) } } func (this *allAconfigDeclarationsSingleton) MakeVars(ctx android.MakeVarsContext) { ctx.DistForGoal("droid", this.intermediateBinaryProtoPath) for _, rcName := range this.sortedConfigNames() { ctx.DistForGoal("droid", this.releaseMap[rcName].intermediateBinaryProtoPath) for _, goal := range []string{"docs", "droid", "sdk"} { ctx.DistForGoalWithFilename(goal, this.intermediateBinaryProtoPath, "flags.pb") ctx.DistForGoalWithFilename(goal, this.intermediateTextProtoPath, "flags.textproto") ctx.DistForGoalWithFilename(goal, this.releaseMap[rcName].intermediateBinaryProtoPath, assembleFileName(rcName, "flags.pb")) ctx.DistForGoalWithFilename(goal, this.releaseMap[rcName].intermediateTextProtoPath, assembleFileName(rcName, "flags.textproto")) } } } aconfig/testing.go +19 −1 Original line number Diff line number Diff line Loading @@ -23,7 +23,25 @@ import ( var PrepareForTestWithAconfigBuildComponents = android.FixtureRegisterWithContext(RegisterBuildComponents) func runTest(t *testing.T, errorHandler android.FixtureErrorHandler, bp string) *android.TestResult { return android.GroupFixturePreparers(PrepareForTestWithAconfigBuildComponents). return PrepareForTest(t). ExtendWithErrorHandler(errorHandler). RunTestWithBp(t, bp) } func PrepareForTest(t *testing.T, preparers ...android.FixturePreparer) android.FixturePreparer { preparers = append([]android.FixturePreparer{PrepareForTestWithAconfigBuildComponents}, preparers...) return android.GroupFixturePreparers(preparers...) } func addBuildFlagsForTest(buildFlags map[string]string) android.FixturePreparer { return android.GroupFixturePreparers( android.FixtureModifyProductVariables(func(vars android.FixtureProductVariables) { if vars.BuildFlags == nil { vars.BuildFlags = make(map[string]string) } for k, v := range buildFlags { vars.BuildFlags[k] = v } }), ) } android/aconfig_providers.go +6 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,10 @@ type AconfigDeclarationsProviderData struct { var AconfigDeclarationsProviderKey = blueprint.NewProvider[AconfigDeclarationsProviderData]() type AconfigReleaseDeclarationsProviderData map[string]AconfigDeclarationsProviderData var AconfigReleaseDeclarationsProviderKey = blueprint.NewProvider[AconfigReleaseDeclarationsProviderData]() type ModeInfo struct { Container string Mode string Loading Loading @@ -112,6 +116,8 @@ func aconfigUpdateAndroidBuildActions(ctx ModuleContext) { if dep, ok := OtherModuleProvider(ctx, module, AconfigDeclarationsProviderKey); ok { mergedAconfigFiles[dep.Container] = append(mergedAconfigFiles[dep.Container], dep.IntermediateCacheOutputPath) } // If we were generating on-device artifacts for other release configs, we would need to add code here to propagate // those artifacts as well. See also b/298444886. if dep, ok := OtherModuleProvider(ctx, module, AconfigPropagatingProviderKey); ok { for container, v := range dep.AconfigFiles { mergedAconfigFiles[container] = append(mergedAconfigFiles[container], v...) Loading Loading
aconfig/aconfig_declarations.go +109 −49 Original line number Diff line number Diff line Loading @@ -15,6 +15,8 @@ package aconfig import ( "path/filepath" "slices" "strings" "android/soong/android" Loading @@ -22,6 +24,11 @@ import ( "github.com/google/blueprint" ) type AconfigReleaseConfigValue struct { ReleaseConfig string Values []string `blueprint:"mutated"` } type DeclarationsModule struct { android.ModuleBase android.DefaultableModuleBase Loading @@ -34,8 +41,10 @@ type DeclarationsModule struct { // Release config flag package Package string // Values from TARGET_RELEASE / RELEASE_ACONFIG_VALUE_SETS Values []string `blueprint:"mutated"` // Values for release configs / RELEASE_ACONFIG_VALUE_SETS // The current release config is `ReleaseConfig: ""`, others // are from RELEASE_ACONFIG_EXTRA_RELEASE_CONFIGS. ReleaseConfigValues []AconfigReleaseConfigValue // Container(system/vendor/apex) that this module belongs to Container string Loading @@ -57,6 +66,10 @@ func DeclarationsFactory() android.Module { type implicitValuesTagType struct { blueprint.BaseDependencyTag // The release config name for these values. // Empty string for the actual current release config. ReleaseConfig string } var implicitValuesTag = implicitValuesTagType{} Loading @@ -81,6 +94,11 @@ func (module *DeclarationsModule) DepsMutator(ctx android.BottomUpMutatorContext if len(valuesFromConfig) > 0 { ctx.AddDependency(ctx.Module(), implicitValuesTag, valuesFromConfig...) } for rcName, valueSets := range ctx.Config().ReleaseAconfigExtraReleaseConfigsValueSets() { if len(valueSets) > 0 { ctx.AddDependency(ctx.Module(), implicitValuesTagType{ReleaseConfig: rcName}, valueSets...) } } } func joinAndPrefix(prefix string, values []string) string { Loading @@ -101,33 +119,72 @@ func optionalVariable(prefix string, value string) string { return sb.String() } // Assemble the actual filename. // If `rcName` is not empty, then insert "-{rcName}" into the path before the // file extension. func assembleFileName(rcName, path string) string { if rcName == "" { return path } dir, file := filepath.Split(path) rcName = "-" + rcName ext := filepath.Ext(file) base := file[:len(file)-len(ext)] return dir + base + rcName + ext } func (module *DeclarationsModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { // Get the values that came from the global RELEASE_ACONFIG_VALUE_SETS flag valuesFiles := make([]android.Path, 0) // Determine which release configs we are processing. // // We always process the current release config (empty string). // We may have been told to also create artifacts for some others. configs := append([]string{""}, ctx.Config().ReleaseAconfigExtraReleaseConfigs()...) slices.Sort(configs) values := make(map[string][]string) valuesFiles := make(map[string][]android.Path, 0) providerData := android.AconfigReleaseDeclarationsProviderData{} ctx.VisitDirectDeps(func(dep android.Module) { if depData, ok := android.OtherModuleProvider(ctx, dep, valueSetProviderKey); ok { depTag := ctx.OtherModuleDependencyTag(dep) for _, config := range configs { tag := implicitValuesTagType{ReleaseConfig: config} if depTag == tag { paths, ok := depData.AvailablePackages[module.properties.Package] if ok { valuesFiles = append(valuesFiles, paths...) valuesFiles[config] = append(valuesFiles[config], paths...) for _, path := range paths { module.properties.Values = append(module.properties.Values, path.String()) values[config] = append(values[config], path.String()) } } } } } }) for _, config := range configs { module.properties.ReleaseConfigValues = append(module.properties.ReleaseConfigValues, AconfigReleaseConfigValue{ ReleaseConfig: config, Values: values[config], }) // Intermediate format declarationFiles := android.PathsForModuleSrc(ctx, module.properties.Srcs) intermediateCacheFilePath := android.PathForModuleOut(ctx, "intermediate.pb") defaultPermission := ctx.Config().ReleaseAconfigFlagDefaultPermission() intermediateCacheFilePath := android.PathForModuleOut(ctx, assembleFileName(config, "intermediate.pb")) var defaultPermission string defaultPermission = ctx.Config().ReleaseAconfigFlagDefaultPermission() if config != "" { if confPerm, ok := ctx.Config().GetBuildFlag("RELEASE_ACONFIG_FLAG_DEFAULT_PERMISSION_" + config); ok { defaultPermission = confPerm } } inputFiles := make([]android.Path, len(declarationFiles)) copy(inputFiles, declarationFiles) inputFiles = append(inputFiles, valuesFiles...) inputFiles = append(inputFiles, valuesFiles[config]...) args := map[string]string{ "release_version": ctx.Config().ReleaseVersion(), "package": module.properties.Package, "declarations": android.JoinPathsWithPrefix(declarationFiles, "--declarations "), "values": joinAndPrefix(" --values ", module.properties.Values), "values": joinAndPrefix(" --values ", values[config]), "default-permission": optionalVariable(" --default-permission ", defaultPermission), } if len(module.properties.Container) > 0 { Loading @@ -141,7 +198,7 @@ func (module *DeclarationsModule) GenerateAndroidBuildActions(ctx android.Module Args: args, }) intermediateDumpFilePath := android.PathForModuleOut(ctx, "intermediate.txt") intermediateDumpFilePath := android.PathForModuleOut(ctx, assembleFileName(config, "intermediate.txt")) ctx.Build(pctx, android.BuildParams{ Rule: aconfigTextRule, Output: intermediateDumpFilePath, Loading @@ -149,11 +206,14 @@ func (module *DeclarationsModule) GenerateAndroidBuildActions(ctx android.Module Description: "aconfig_text", }) android.SetProvider(ctx, android.AconfigDeclarationsProviderKey, android.AconfigDeclarationsProviderData{ providerData[config] = android.AconfigDeclarationsProviderData{ Package: module.properties.Package, Container: module.properties.Container, Exportable: module.properties.Exportable, IntermediateCacheOutputPath: intermediateCacheFilePath, IntermediateDumpOutputPath: intermediateDumpFilePath, }) } } android.SetProvider(ctx, android.AconfigDeclarationsProviderKey, providerData[""]) android.SetProvider(ctx, android.AconfigReleaseDeclarationsProviderKey, providerData) }
aconfig/aconfig_declarations_test.go +93 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ package aconfig import ( "slices" "strings" "testing" Loading Loading @@ -134,3 +135,95 @@ func TestMandatoryProperties(t *testing.T) { }) } } func TestAssembleFileName(t *testing.T) { testCases := []struct { name string releaseConfig string path string expectedValue string }{ { name: "active release config", path: "file.path", expectedValue: "file.path", }, { name: "release config FOO", releaseConfig: "FOO", path: "file.path", expectedValue: "file-FOO.path", }, } for _, test := range testCases { actualValue := assembleFileName(test.releaseConfig, test.path) if actualValue != test.expectedValue { t.Errorf("Expected %q found %q", test.expectedValue, actualValue) } } } func TestGenerateAndroidBuildActions(t *testing.T) { testCases := []struct { name string buildFlags map[string]string bp string errorHandler android.FixtureErrorHandler }{ { name: "generate extra", buildFlags: map[string]string{ "RELEASE_ACONFIG_EXTRA_RELEASE_CONFIGS": "config2", "RELEASE_ACONFIG_VALUE_SETS": "aconfig_value_set-config1", "RELEASE_ACONFIG_VALUE_SETS_config2": "aconfig_value_set-config2", }, bp: ` aconfig_declarations { name: "module_name", package: "com.example.package", container: "com.android.foo", srcs: [ "foo.aconfig", "bar.aconfig", ], } aconfig_value_set { name: "aconfig_value_set-config1", values: [] } aconfig_value_set { name: "aconfig_value_set-config2", values: [] } `, }, } for _, test := range testCases { fixture := PrepareForTest(t, addBuildFlagsForTest(test.buildFlags)) if test.errorHandler != nil { fixture = fixture.ExtendWithErrorHandler(test.errorHandler) } result := fixture.RunTestWithBp(t, test.bp) module := result.ModuleForTests("module_name", "").Module().(*DeclarationsModule) depData, _ := android.SingletonModuleProvider(result, module, android.AconfigReleaseDeclarationsProviderKey) expectedKeys := []string{""} for _, rc := range strings.Split(test.buildFlags["RELEASE_ACONFIG_EXTRA_RELEASE_CONFIGS"], " ") { expectedKeys = append(expectedKeys, rc) } slices.Sort(expectedKeys) actualKeys := []string{} for rc := range depData { actualKeys = append(actualKeys, rc) } slices.Sort(actualKeys) android.AssertStringEquals(t, "provider keys", strings.Join(expectedKeys, " "), strings.Join(actualKeys, " ")) for _, rc := range actualKeys { if !strings.HasSuffix(depData[rc].IntermediateCacheOutputPath.String(), assembleFileName(rc, "/intermediate.pb")) { t.Errorf("Incorrect intermediates proto path in provider for release config %s: %s", rc, depData[rc].IntermediateCacheOutputPath.String()) } if !strings.HasSuffix(depData[rc].IntermediateDumpOutputPath.String(), assembleFileName(rc, "/intermediate.txt")) { t.Errorf("Incorrect intermediates text path in provider for release config %s: %s", rc, depData[rc].IntermediateDumpOutputPath.String()) } } } }
aconfig/all_aconfig_declarations.go +71 −50 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package aconfig import ( "android/soong/android" "fmt" "slices" ) // A singleton module that collects all of the aconfig flags declared in the Loading @@ -27,25 +28,39 @@ import ( // ones that are relevant to the product currently being built, so that that infra // doesn't need to pull from multiple builds and merge them. func AllAconfigDeclarationsFactory() android.Singleton { return &allAconfigDeclarationsSingleton{} return &allAconfigDeclarationsSingleton{releaseMap: make(map[string]allAconfigReleaseDeclarationsSingleton)} } type allAconfigDeclarationsSingleton struct { type allAconfigReleaseDeclarationsSingleton struct { intermediateBinaryProtoPath android.OutputPath intermediateTextProtoPath android.OutputPath } type allAconfigDeclarationsSingleton struct { releaseMap map[string]allAconfigReleaseDeclarationsSingleton } func (this *allAconfigDeclarationsSingleton) sortedConfigNames() []string { var names []string for k := range this.releaseMap { names = append(names, k) } slices.Sort(names) return names } func (this *allAconfigDeclarationsSingleton) GenerateBuildActions(ctx android.SingletonContext) { for _, rcName := range append([]string{""}, ctx.Config().ReleaseAconfigExtraReleaseConfigs()...) { // Find all of the aconfig_declarations modules var packages = make(map[string]int) var cacheFiles android.Paths ctx.VisitAllModules(func(module android.Module) { decl, ok := android.SingletonModuleProvider(ctx, module, android.AconfigDeclarationsProviderKey) decl, ok := android.SingletonModuleProvider(ctx, module, android.AconfigReleaseDeclarationsProviderKey) if !ok { return } cacheFiles = append(cacheFiles, decl.IntermediateCacheOutputPath) packages[decl.Package]++ cacheFiles = append(cacheFiles, decl[rcName].IntermediateCacheOutputPath) packages[decl[rcName].Package]++ }) var numOffendingPkg = 0 Loading @@ -61,36 +76,42 @@ func (this *allAconfigDeclarationsSingleton) GenerateBuildActions(ctx android.Si } // Generate build action for aconfig (binary proto output) this.intermediateBinaryProtoPath = android.PathForIntermediates(ctx, "all_aconfig_declarations.pb") paths := allAconfigReleaseDeclarationsSingleton{ intermediateBinaryProtoPath: android.PathForIntermediates(ctx, assembleFileName(rcName, "all_aconfig_declarations.pb")), intermediateTextProtoPath: android.PathForIntermediates(ctx, assembleFileName(rcName, "all_aconfig_declarations.textproto")), } this.releaseMap[rcName] = paths ctx.Build(pctx, android.BuildParams{ Rule: AllDeclarationsRule, Inputs: cacheFiles, Output: this.intermediateBinaryProtoPath, Output: this.releaseMap[rcName].intermediateBinaryProtoPath, Description: "all_aconfig_declarations", Args: map[string]string{ "cache_files": android.JoinPathsWithPrefix(cacheFiles, "--cache "), }, }) ctx.Phony("all_aconfig_declarations", this.intermediateBinaryProtoPath) ctx.Phony("all_aconfig_declarations", this.releaseMap[rcName].intermediateBinaryProtoPath) // Generate build action for aconfig (text proto output) this.intermediateTextProtoPath = android.PathForIntermediates(ctx, "all_aconfig_declarations.textproto") ctx.Build(pctx, android.BuildParams{ Rule: AllDeclarationsRuleTextProto, Inputs: cacheFiles, Output: this.intermediateTextProtoPath, Output: this.releaseMap[rcName].intermediateTextProtoPath, Description: "all_aconfig_declarations_textproto", Args: map[string]string{ "cache_files": android.JoinPathsWithPrefix(cacheFiles, "--cache "), }, }) ctx.Phony("all_aconfig_declarations_textproto", this.intermediateTextProtoPath) ctx.Phony("all_aconfig_declarations_textproto", this.releaseMap[rcName].intermediateTextProtoPath) } } func (this *allAconfigDeclarationsSingleton) MakeVars(ctx android.MakeVarsContext) { ctx.DistForGoal("droid", this.intermediateBinaryProtoPath) for _, rcName := range this.sortedConfigNames() { ctx.DistForGoal("droid", this.releaseMap[rcName].intermediateBinaryProtoPath) for _, goal := range []string{"docs", "droid", "sdk"} { ctx.DistForGoalWithFilename(goal, this.intermediateBinaryProtoPath, "flags.pb") ctx.DistForGoalWithFilename(goal, this.intermediateTextProtoPath, "flags.textproto") ctx.DistForGoalWithFilename(goal, this.releaseMap[rcName].intermediateBinaryProtoPath, assembleFileName(rcName, "flags.pb")) ctx.DistForGoalWithFilename(goal, this.releaseMap[rcName].intermediateTextProtoPath, assembleFileName(rcName, "flags.textproto")) } } }
aconfig/testing.go +19 −1 Original line number Diff line number Diff line Loading @@ -23,7 +23,25 @@ import ( var PrepareForTestWithAconfigBuildComponents = android.FixtureRegisterWithContext(RegisterBuildComponents) func runTest(t *testing.T, errorHandler android.FixtureErrorHandler, bp string) *android.TestResult { return android.GroupFixturePreparers(PrepareForTestWithAconfigBuildComponents). return PrepareForTest(t). ExtendWithErrorHandler(errorHandler). RunTestWithBp(t, bp) } func PrepareForTest(t *testing.T, preparers ...android.FixturePreparer) android.FixturePreparer { preparers = append([]android.FixturePreparer{PrepareForTestWithAconfigBuildComponents}, preparers...) return android.GroupFixturePreparers(preparers...) } func addBuildFlagsForTest(buildFlags map[string]string) android.FixturePreparer { return android.GroupFixturePreparers( android.FixtureModifyProductVariables(func(vars android.FixtureProductVariables) { if vars.BuildFlags == nil { vars.BuildFlags = make(map[string]string) } for k, v := range buildFlags { vars.BuildFlags[k] = v } }), ) }
android/aconfig_providers.go +6 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,10 @@ type AconfigDeclarationsProviderData struct { var AconfigDeclarationsProviderKey = blueprint.NewProvider[AconfigDeclarationsProviderData]() type AconfigReleaseDeclarationsProviderData map[string]AconfigDeclarationsProviderData var AconfigReleaseDeclarationsProviderKey = blueprint.NewProvider[AconfigReleaseDeclarationsProviderData]() type ModeInfo struct { Container string Mode string Loading Loading @@ -112,6 +116,8 @@ func aconfigUpdateAndroidBuildActions(ctx ModuleContext) { if dep, ok := OtherModuleProvider(ctx, module, AconfigDeclarationsProviderKey); ok { mergedAconfigFiles[dep.Container] = append(mergedAconfigFiles[dep.Container], dep.IntermediateCacheOutputPath) } // If we were generating on-device artifacts for other release configs, we would need to add code here to propagate // those artifacts as well. See also b/298444886. if dep, ok := OtherModuleProvider(ctx, module, AconfigPropagatingProviderKey); ok { for container, v := range dep.AconfigFiles { mergedAconfigFiles[container] = append(mergedAconfigFiles[container], v...) Loading