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 codegen 16*333d2b36SAndroid Build Coastguard Worker 17*333d2b36SAndroid Build Coastguard Workerimport ( 18*333d2b36SAndroid Build Coastguard Worker "android/soong/android" 19*333d2b36SAndroid Build Coastguard Worker "android/soong/cc" 20*333d2b36SAndroid Build Coastguard Worker 21*333d2b36SAndroid Build Coastguard Worker "github.com/google/blueprint" 22*333d2b36SAndroid Build Coastguard Worker "github.com/google/blueprint/proptools" 23*333d2b36SAndroid Build Coastguard Worker 24*333d2b36SAndroid Build Coastguard Worker "fmt" 25*333d2b36SAndroid Build Coastguard Worker "strconv" 26*333d2b36SAndroid Build Coastguard Worker "strings" 27*333d2b36SAndroid Build Coastguard Worker) 28*333d2b36SAndroid Build Coastguard Worker 29*333d2b36SAndroid Build Coastguard Workertype ccDeclarationsTagType struct { 30*333d2b36SAndroid Build Coastguard Worker blueprint.BaseDependencyTag 31*333d2b36SAndroid Build Coastguard Worker} 32*333d2b36SAndroid Build Coastguard Worker 33*333d2b36SAndroid Build Coastguard Workervar ccDeclarationsTag = ccDeclarationsTagType{} 34*333d2b36SAndroid Build Coastguard Worker 35*333d2b36SAndroid Build Coastguard Workerconst baseLibDep = "server_configurable_flags" 36*333d2b36SAndroid Build Coastguard Worker 37*333d2b36SAndroid Build Coastguard Workerconst libBaseDep = "libbase" 38*333d2b36SAndroid Build Coastguard Workerconst libLogDep = "liblog" 39*333d2b36SAndroid Build Coastguard Workerconst libAconfigStorageReadApiCcDep = "libaconfig_storage_read_api_cc" 40*333d2b36SAndroid Build Coastguard Worker 41*333d2b36SAndroid Build Coastguard Workertype CcAconfigLibraryProperties struct { 42*333d2b36SAndroid Build Coastguard Worker // name of the aconfig_declarations module to generate a library for 43*333d2b36SAndroid Build Coastguard Worker Aconfig_declarations string 44*333d2b36SAndroid Build Coastguard Worker 45*333d2b36SAndroid Build Coastguard Worker // default mode is "production", the other accepted modes are: 46*333d2b36SAndroid Build Coastguard Worker // "test": to generate test mode version of the library 47*333d2b36SAndroid Build Coastguard Worker // "exported": to generate exported mode version of the library 48*333d2b36SAndroid Build Coastguard Worker // "force-read-only": to generate force-read-only mode version of the library 49*333d2b36SAndroid Build Coastguard Worker // an error will be thrown if the mode is not supported 50*333d2b36SAndroid Build Coastguard Worker Mode *string 51*333d2b36SAndroid Build Coastguard Worker} 52*333d2b36SAndroid Build Coastguard Worker 53*333d2b36SAndroid Build Coastguard Workertype CcAconfigLibraryCallbacks struct { 54*333d2b36SAndroid Build Coastguard Worker properties *CcAconfigLibraryProperties 55*333d2b36SAndroid Build Coastguard Worker 56*333d2b36SAndroid Build Coastguard Worker generatedDir android.WritablePath 57*333d2b36SAndroid Build Coastguard Worker headerDir android.WritablePath 58*333d2b36SAndroid Build Coastguard Worker generatedCpp android.WritablePath 59*333d2b36SAndroid Build Coastguard Worker generatedH android.WritablePath 60*333d2b36SAndroid Build Coastguard Worker} 61*333d2b36SAndroid Build Coastguard Worker 62*333d2b36SAndroid Build Coastguard Workerfunc CcAconfigLibraryFactory() android.Module { 63*333d2b36SAndroid Build Coastguard Worker callbacks := &CcAconfigLibraryCallbacks{ 64*333d2b36SAndroid Build Coastguard Worker properties: &CcAconfigLibraryProperties{}, 65*333d2b36SAndroid Build Coastguard Worker } 66*333d2b36SAndroid Build Coastguard Worker return cc.GeneratedCcLibraryModuleFactory(callbacks) 67*333d2b36SAndroid Build Coastguard Worker} 68*333d2b36SAndroid Build Coastguard Worker 69*333d2b36SAndroid Build Coastguard Workerfunc (this *CcAconfigLibraryCallbacks) GeneratorInit(ctx cc.BaseModuleContext) { 70*333d2b36SAndroid Build Coastguard Worker} 71*333d2b36SAndroid Build Coastguard Worker 72*333d2b36SAndroid Build Coastguard Workerfunc (this *CcAconfigLibraryCallbacks) GeneratorProps() []interface{} { 73*333d2b36SAndroid Build Coastguard Worker return []interface{}{this.properties} 74*333d2b36SAndroid Build Coastguard Worker} 75*333d2b36SAndroid Build Coastguard Worker 76*333d2b36SAndroid Build Coastguard Workerfunc (this *CcAconfigLibraryCallbacks) GeneratorDeps(ctx cc.DepsContext, deps cc.Deps) cc.Deps { 77*333d2b36SAndroid Build Coastguard Worker // Add a dependency for the declarations module 78*333d2b36SAndroid Build Coastguard Worker declarations := this.properties.Aconfig_declarations 79*333d2b36SAndroid Build Coastguard Worker if len(declarations) == 0 { 80*333d2b36SAndroid Build Coastguard Worker ctx.PropertyErrorf("aconfig_declarations", "aconfig_declarations property required") 81*333d2b36SAndroid Build Coastguard Worker } else { 82*333d2b36SAndroid Build Coastguard Worker ctx.AddDependency(ctx.Module(), ccDeclarationsTag, declarations) 83*333d2b36SAndroid Build Coastguard Worker } 84*333d2b36SAndroid Build Coastguard Worker 85*333d2b36SAndroid Build Coastguard Worker mode := proptools.StringDefault(this.properties.Mode, "production") 86*333d2b36SAndroid Build Coastguard Worker 87*333d2b36SAndroid Build Coastguard Worker // Add a dependency for the aconfig flags base library if it is not forced read only 88*333d2b36SAndroid Build Coastguard Worker if mode != "force-read-only" { 89*333d2b36SAndroid Build Coastguard Worker deps.SharedLibs = append(deps.SharedLibs, baseLibDep) 90*333d2b36SAndroid Build Coastguard Worker 91*333d2b36SAndroid Build Coastguard Worker } 92*333d2b36SAndroid Build Coastguard Worker 93*333d2b36SAndroid Build Coastguard Worker // TODO: after storage migration is over, don't add these in force-read-only-mode. 94*333d2b36SAndroid Build Coastguard Worker deps.SharedLibs = append(deps.SharedLibs, libAconfigStorageReadApiCcDep) 95*333d2b36SAndroid Build Coastguard Worker deps.SharedLibs = append(deps.SharedLibs, libBaseDep) 96*333d2b36SAndroid Build Coastguard Worker deps.SharedLibs = append(deps.SharedLibs, libLogDep) 97*333d2b36SAndroid Build Coastguard Worker 98*333d2b36SAndroid Build Coastguard Worker // TODO: It'd be really nice if we could reexport this library and not make everyone do it. 99*333d2b36SAndroid Build Coastguard Worker 100*333d2b36SAndroid Build Coastguard Worker return deps 101*333d2b36SAndroid Build Coastguard Worker} 102*333d2b36SAndroid Build Coastguard Worker 103*333d2b36SAndroid Build Coastguard Workerfunc (this *CcAconfigLibraryCallbacks) GeneratorSources(ctx cc.ModuleContext) cc.GeneratedSource { 104*333d2b36SAndroid Build Coastguard Worker result := cc.GeneratedSource{} 105*333d2b36SAndroid Build Coastguard Worker 106*333d2b36SAndroid Build Coastguard Worker // Get the values that came from the global RELEASE_ACONFIG_VALUE_SETS flag 107*333d2b36SAndroid Build Coastguard Worker declarationsModules := ctx.GetDirectDepsWithTag(ccDeclarationsTag) 108*333d2b36SAndroid Build Coastguard Worker if len(declarationsModules) != 1 { 109*333d2b36SAndroid Build Coastguard Worker panic(fmt.Errorf("Exactly one aconfig_declarations property required")) 110*333d2b36SAndroid Build Coastguard Worker } 111*333d2b36SAndroid Build Coastguard Worker declarations, _ := android.OtherModuleProvider(ctx, declarationsModules[0], android.AconfigDeclarationsProviderKey) 112*333d2b36SAndroid Build Coastguard Worker 113*333d2b36SAndroid Build Coastguard Worker // Figure out the generated file paths. This has to match aconfig's codegen_cpp.rs. 114*333d2b36SAndroid Build Coastguard Worker this.generatedDir = android.PathForModuleGen(ctx) 115*333d2b36SAndroid Build Coastguard Worker 116*333d2b36SAndroid Build Coastguard Worker this.headerDir = android.PathForModuleGen(ctx, "include") 117*333d2b36SAndroid Build Coastguard Worker result.IncludeDirs = []android.Path{this.headerDir} 118*333d2b36SAndroid Build Coastguard Worker result.ReexportedDirs = []android.Path{this.headerDir} 119*333d2b36SAndroid Build Coastguard Worker 120*333d2b36SAndroid Build Coastguard Worker basename := strings.ReplaceAll(declarations.Package, ".", "_") 121*333d2b36SAndroid Build Coastguard Worker 122*333d2b36SAndroid Build Coastguard Worker this.generatedCpp = android.PathForModuleGen(ctx, basename+".cc") 123*333d2b36SAndroid Build Coastguard Worker result.Sources = []android.Path{this.generatedCpp} 124*333d2b36SAndroid Build Coastguard Worker 125*333d2b36SAndroid Build Coastguard Worker this.generatedH = android.PathForModuleGen(ctx, "include", basename+".h") 126*333d2b36SAndroid Build Coastguard Worker result.Headers = []android.Path{this.generatedH} 127*333d2b36SAndroid Build Coastguard Worker 128*333d2b36SAndroid Build Coastguard Worker return result 129*333d2b36SAndroid Build Coastguard Worker} 130*333d2b36SAndroid Build Coastguard Worker 131*333d2b36SAndroid Build Coastguard Workerfunc (this *CcAconfigLibraryCallbacks) GeneratorFlags(ctx cc.ModuleContext, flags cc.Flags, deps cc.PathDeps) cc.Flags { 132*333d2b36SAndroid Build Coastguard Worker return flags 133*333d2b36SAndroid Build Coastguard Worker} 134*333d2b36SAndroid Build Coastguard Worker 135*333d2b36SAndroid Build Coastguard Workerfunc (this *CcAconfigLibraryCallbacks) GeneratorBuildActions(ctx cc.ModuleContext, flags cc.Flags, deps cc.PathDeps) { 136*333d2b36SAndroid Build Coastguard Worker // Get the values that came from the global RELEASE_ACONFIG_VALUE_SETS flag 137*333d2b36SAndroid Build Coastguard Worker declarationsModules := ctx.GetDirectDepsWithTag(ccDeclarationsTag) 138*333d2b36SAndroid Build Coastguard Worker if len(declarationsModules) != 1 { 139*333d2b36SAndroid Build Coastguard Worker panic(fmt.Errorf("Exactly one aconfig_declarations property required")) 140*333d2b36SAndroid Build Coastguard Worker } 141*333d2b36SAndroid Build Coastguard Worker declarations, _ := android.OtherModuleProvider(ctx, declarationsModules[0], android.AconfigDeclarationsProviderKey) 142*333d2b36SAndroid Build Coastguard Worker 143*333d2b36SAndroid Build Coastguard Worker mode := proptools.StringDefault(this.properties.Mode, "production") 144*333d2b36SAndroid Build Coastguard Worker if !isModeSupported(mode) { 145*333d2b36SAndroid Build Coastguard Worker ctx.PropertyErrorf("mode", "%q is not a supported mode", mode) 146*333d2b36SAndroid Build Coastguard Worker } 147*333d2b36SAndroid Build Coastguard Worker 148*333d2b36SAndroid Build Coastguard Worker ctx.Build(pctx, android.BuildParams{ 149*333d2b36SAndroid Build Coastguard Worker Rule: cppRule, 150*333d2b36SAndroid Build Coastguard Worker Input: declarations.IntermediateCacheOutputPath, 151*333d2b36SAndroid Build Coastguard Worker Outputs: []android.WritablePath{ 152*333d2b36SAndroid Build Coastguard Worker this.generatedCpp, 153*333d2b36SAndroid Build Coastguard Worker this.generatedH, 154*333d2b36SAndroid Build Coastguard Worker }, 155*333d2b36SAndroid Build Coastguard Worker Description: "cc_aconfig_library", 156*333d2b36SAndroid Build Coastguard Worker Args: map[string]string{ 157*333d2b36SAndroid Build Coastguard Worker "gendir": this.generatedDir.String(), 158*333d2b36SAndroid Build Coastguard Worker "mode": mode, 159*333d2b36SAndroid Build Coastguard Worker "debug": strconv.FormatBool(ctx.Config().ReleaseReadFromNewStorage()), 160*333d2b36SAndroid Build Coastguard Worker }, 161*333d2b36SAndroid Build Coastguard Worker }) 162*333d2b36SAndroid Build Coastguard Worker 163*333d2b36SAndroid Build Coastguard Worker android.SetProvider(ctx, android.CodegenInfoProvider, android.CodegenInfo{ 164*333d2b36SAndroid Build Coastguard Worker ModeInfos: map[string]android.ModeInfo{ 165*333d2b36SAndroid Build Coastguard Worker ctx.ModuleName(): { 166*333d2b36SAndroid Build Coastguard Worker Container: declarations.Container, 167*333d2b36SAndroid Build Coastguard Worker Mode: mode, 168*333d2b36SAndroid Build Coastguard Worker }}, 169*333d2b36SAndroid Build Coastguard Worker }) 170*333d2b36SAndroid Build Coastguard Worker} 171