1// Copyright 2023 Google Inc. All rights reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package aconfig 16 17import ( 18 "android/soong/android" 19 "fmt" 20) 21 22// A singleton module that collects all of the aconfig flags declared in the 23// tree into a single combined file for export to the external flag setting 24// server (inside Google it's Gantry). 25// 26// Note that this is ALL aconfig_declarations modules present in the tree, not just 27// ones that are relevant to the product currently being built, so that that infra 28// doesn't need to pull from multiple builds and merge them. 29func AllAconfigDeclarationsFactory() android.Singleton { 30 return &allAconfigDeclarationsSingleton{} 31} 32 33type allAconfigDeclarationsSingleton struct { 34 intermediateBinaryProtoPath android.OutputPath 35 intermediateTextProtoPath android.OutputPath 36} 37 38func (this *allAconfigDeclarationsSingleton) GenerateBuildActions(ctx android.SingletonContext) { 39 // Find all of the aconfig_declarations modules 40 var packages = make(map[string]int) 41 var cacheFiles android.Paths 42 ctx.VisitAllModules(func(module android.Module) { 43 decl, ok := android.SingletonModuleProvider(ctx, module, android.AconfigDeclarationsProviderKey) 44 if !ok { 45 return 46 } 47 cacheFiles = append(cacheFiles, decl.IntermediateCacheOutputPath) 48 packages[decl.Package]++ 49 }) 50 51 var numOffendingPkg = 0 52 for pkg, cnt := range packages { 53 if cnt > 1 { 54 fmt.Printf("%d aconfig_declarations found for package %s\n", cnt, pkg) 55 numOffendingPkg++ 56 } 57 } 58 59 if numOffendingPkg > 0 { 60 panic(fmt.Errorf("Only one aconfig_declarations allowed for each package.")) 61 } 62 63 // Generate build action for aconfig (binary proto output) 64 this.intermediateBinaryProtoPath = android.PathForIntermediates(ctx, "all_aconfig_declarations.pb") 65 ctx.Build(pctx, android.BuildParams{ 66 Rule: AllDeclarationsRule, 67 Inputs: cacheFiles, 68 Output: this.intermediateBinaryProtoPath, 69 Description: "all_aconfig_declarations", 70 Args: map[string]string{ 71 "cache_files": android.JoinPathsWithPrefix(cacheFiles, "--cache "), 72 }, 73 }) 74 ctx.Phony("all_aconfig_declarations", this.intermediateBinaryProtoPath) 75 76 // Generate build action for aconfig (text proto output) 77 this.intermediateTextProtoPath = android.PathForIntermediates(ctx, "all_aconfig_declarations.textproto") 78 ctx.Build(pctx, android.BuildParams{ 79 Rule: AllDeclarationsRuleTextProto, 80 Inputs: cacheFiles, 81 Output: this.intermediateTextProtoPath, 82 Description: "all_aconfig_declarations_textproto", 83 Args: map[string]string{ 84 "cache_files": android.JoinPathsWithPrefix(cacheFiles, "--cache "), 85 }, 86 }) 87 ctx.Phony("all_aconfig_declarations_textproto", this.intermediateTextProtoPath) 88} 89 90func (this *allAconfigDeclarationsSingleton) MakeVars(ctx android.MakeVarsContext) { 91 ctx.DistForGoal("droid", this.intermediateBinaryProtoPath) 92 for _, goal := range []string{"docs", "droid", "sdk"} { 93 ctx.DistForGoalWithFilename(goal, this.intermediateBinaryProtoPath, "flags.pb") 94 ctx.DistForGoalWithFilename(goal, this.intermediateTextProtoPath, "flags.textproto") 95 } 96} 97