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