1*333d2b36SAndroid Build Coastguard Worker// Copyright 2015 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 android 16*333d2b36SAndroid Build Coastguard Worker 17*333d2b36SAndroid Build Coastguard Workerimport ( 18*333d2b36SAndroid Build Coastguard Worker "reflect" 19*333d2b36SAndroid Build Coastguard Worker 20*333d2b36SAndroid Build Coastguard Worker "github.com/google/blueprint" 21*333d2b36SAndroid Build Coastguard Worker "github.com/google/blueprint/proptools" 22*333d2b36SAndroid Build Coastguard Worker) 23*333d2b36SAndroid Build Coastguard Worker 24*333d2b36SAndroid Build Coastguard Workertype defaultsDependencyTag struct { 25*333d2b36SAndroid Build Coastguard Worker blueprint.BaseDependencyTag 26*333d2b36SAndroid Build Coastguard Worker} 27*333d2b36SAndroid Build Coastguard Worker 28*333d2b36SAndroid Build Coastguard Workervar DefaultsDepTag defaultsDependencyTag 29*333d2b36SAndroid Build Coastguard Worker 30*333d2b36SAndroid Build Coastguard Workertype defaultsProperties struct { 31*333d2b36SAndroid Build Coastguard Worker Defaults []string 32*333d2b36SAndroid Build Coastguard Worker} 33*333d2b36SAndroid Build Coastguard Worker 34*333d2b36SAndroid Build Coastguard Workertype DefaultableModuleBase struct { 35*333d2b36SAndroid Build Coastguard Worker defaultsProperties defaultsProperties 36*333d2b36SAndroid Build Coastguard Worker defaultableProperties []interface{} 37*333d2b36SAndroid Build Coastguard Worker defaultableVariableProperties interface{} 38*333d2b36SAndroid Build Coastguard Worker 39*333d2b36SAndroid Build Coastguard Worker // The optional hook to call after any defaults have been applied. 40*333d2b36SAndroid Build Coastguard Worker hook DefaultableHook 41*333d2b36SAndroid Build Coastguard Worker} 42*333d2b36SAndroid Build Coastguard Worker 43*333d2b36SAndroid Build Coastguard Workerfunc (d *DefaultableModuleBase) defaults() *defaultsProperties { 44*333d2b36SAndroid Build Coastguard Worker return &d.defaultsProperties 45*333d2b36SAndroid Build Coastguard Worker} 46*333d2b36SAndroid Build Coastguard Worker 47*333d2b36SAndroid Build Coastguard Workerfunc (d *DefaultableModuleBase) setProperties(props []interface{}, variableProperties interface{}) { 48*333d2b36SAndroid Build Coastguard Worker d.defaultableProperties = props 49*333d2b36SAndroid Build Coastguard Worker d.defaultableVariableProperties = variableProperties 50*333d2b36SAndroid Build Coastguard Worker} 51*333d2b36SAndroid Build Coastguard Worker 52*333d2b36SAndroid Build Coastguard Workerfunc (d *DefaultableModuleBase) SetDefaultableHook(hook DefaultableHook) { 53*333d2b36SAndroid Build Coastguard Worker d.hook = hook 54*333d2b36SAndroid Build Coastguard Worker} 55*333d2b36SAndroid Build Coastguard Worker 56*333d2b36SAndroid Build Coastguard Workerfunc (d *DefaultableModuleBase) CallHookIfAvailable(ctx DefaultableHookContext) { 57*333d2b36SAndroid Build Coastguard Worker if d.hook != nil { 58*333d2b36SAndroid Build Coastguard Worker d.hook(ctx) 59*333d2b36SAndroid Build Coastguard Worker } 60*333d2b36SAndroid Build Coastguard Worker} 61*333d2b36SAndroid Build Coastguard Worker 62*333d2b36SAndroid Build Coastguard Worker// Interface that must be supported by any module to which defaults can be applied. 63*333d2b36SAndroid Build Coastguard Workertype Defaultable interface { 64*333d2b36SAndroid Build Coastguard Worker // Get a pointer to the struct containing the Defaults property. 65*333d2b36SAndroid Build Coastguard Worker defaults() *defaultsProperties 66*333d2b36SAndroid Build Coastguard Worker 67*333d2b36SAndroid Build Coastguard Worker // Set the property structures into which defaults will be added. 68*333d2b36SAndroid Build Coastguard Worker setProperties(props []interface{}, variableProperties interface{}) 69*333d2b36SAndroid Build Coastguard Worker 70*333d2b36SAndroid Build Coastguard Worker // Apply defaults from the supplied Defaults to the property structures supplied to 71*333d2b36SAndroid Build Coastguard Worker // setProperties(...). 72*333d2b36SAndroid Build Coastguard Worker applyDefaults(BottomUpMutatorContext, []Defaults) 73*333d2b36SAndroid Build Coastguard Worker 74*333d2b36SAndroid Build Coastguard Worker // Set the hook to be called after any defaults have been applied. 75*333d2b36SAndroid Build Coastguard Worker // 76*333d2b36SAndroid Build Coastguard Worker // Should be used in preference to a AddLoadHook when the behavior of the load 77*333d2b36SAndroid Build Coastguard Worker // hook is dependent on properties supplied in the Android.bp file. 78*333d2b36SAndroid Build Coastguard Worker SetDefaultableHook(hook DefaultableHook) 79*333d2b36SAndroid Build Coastguard Worker 80*333d2b36SAndroid Build Coastguard Worker // Call the hook if specified. 81*333d2b36SAndroid Build Coastguard Worker CallHookIfAvailable(context DefaultableHookContext) 82*333d2b36SAndroid Build Coastguard Worker} 83*333d2b36SAndroid Build Coastguard Worker 84*333d2b36SAndroid Build Coastguard Workertype DefaultableModule interface { 85*333d2b36SAndroid Build Coastguard Worker Module 86*333d2b36SAndroid Build Coastguard Worker Defaultable 87*333d2b36SAndroid Build Coastguard Worker} 88*333d2b36SAndroid Build Coastguard Worker 89*333d2b36SAndroid Build Coastguard Workervar _ Defaultable = (*DefaultableModuleBase)(nil) 90*333d2b36SAndroid Build Coastguard Worker 91*333d2b36SAndroid Build Coastguard Workerfunc InitDefaultableModule(module DefaultableModule) { 92*333d2b36SAndroid Build Coastguard Worker if module.base().module == nil { 93*333d2b36SAndroid Build Coastguard Worker panic("InitAndroidModule must be called before InitDefaultableModule") 94*333d2b36SAndroid Build Coastguard Worker } 95*333d2b36SAndroid Build Coastguard Worker 96*333d2b36SAndroid Build Coastguard Worker module.setProperties(module.GetProperties(), module.base().variableProperties) 97*333d2b36SAndroid Build Coastguard Worker 98*333d2b36SAndroid Build Coastguard Worker module.AddProperties(module.defaults()) 99*333d2b36SAndroid Build Coastguard Worker} 100*333d2b36SAndroid Build Coastguard Worker 101*333d2b36SAndroid Build Coastguard Worker// A restricted subset of context methods, similar to LoadHookContext. 102*333d2b36SAndroid Build Coastguard Workertype DefaultableHookContext interface { 103*333d2b36SAndroid Build Coastguard Worker EarlyModuleContext 104*333d2b36SAndroid Build Coastguard Worker OtherModuleProviderContext 105*333d2b36SAndroid Build Coastguard Worker 106*333d2b36SAndroid Build Coastguard Worker CreateModule(ModuleFactory, ...interface{}) Module 107*333d2b36SAndroid Build Coastguard Worker AddMissingDependencies(missingDeps []string) 108*333d2b36SAndroid Build Coastguard Worker} 109*333d2b36SAndroid Build Coastguard Worker 110*333d2b36SAndroid Build Coastguard Workertype DefaultableHook func(ctx DefaultableHookContext) 111*333d2b36SAndroid Build Coastguard Worker 112*333d2b36SAndroid Build Coastguard Worker// The Defaults_visibility property. 113*333d2b36SAndroid Build Coastguard Workertype DefaultsVisibilityProperties struct { 114*333d2b36SAndroid Build Coastguard Worker 115*333d2b36SAndroid Build Coastguard Worker // Controls the visibility of the defaults module itself. 116*333d2b36SAndroid Build Coastguard Worker Defaults_visibility []string 117*333d2b36SAndroid Build Coastguard Worker} 118*333d2b36SAndroid Build Coastguard Worker 119*333d2b36SAndroid Build Coastguard Workertype DefaultsModuleBase struct { 120*333d2b36SAndroid Build Coastguard Worker DefaultableModuleBase 121*333d2b36SAndroid Build Coastguard Worker} 122*333d2b36SAndroid Build Coastguard Worker 123*333d2b36SAndroid Build Coastguard Worker// The common pattern for defaults modules is to register separate instances of 124*333d2b36SAndroid Build Coastguard Worker// the xxxProperties structs in the AddProperties calls, rather than reusing the 125*333d2b36SAndroid Build Coastguard Worker// ones inherited from Module. 126*333d2b36SAndroid Build Coastguard Worker// 127*333d2b36SAndroid Build Coastguard Worker// The effect is that e.g. myDefaultsModuleInstance.base().xxxProperties won't 128*333d2b36SAndroid Build Coastguard Worker// contain the values that have been set for the defaults module. Rather, to 129*333d2b36SAndroid Build Coastguard Worker// retrieve the values it is necessary to iterate over properties(). E.g. to get 130*333d2b36SAndroid Build Coastguard Worker// the commonProperties instance that have the real values: 131*333d2b36SAndroid Build Coastguard Worker// 132*333d2b36SAndroid Build Coastguard Worker// d := myModule.(Defaults) 133*333d2b36SAndroid Build Coastguard Worker// for _, props := range d.properties() { 134*333d2b36SAndroid Build Coastguard Worker// if cp, ok := props.(*commonProperties); ok { 135*333d2b36SAndroid Build Coastguard Worker// ... access property values in cp ... 136*333d2b36SAndroid Build Coastguard Worker// } 137*333d2b36SAndroid Build Coastguard Worker// } 138*333d2b36SAndroid Build Coastguard Worker// 139*333d2b36SAndroid Build Coastguard Worker// The rationale is that the properties on a defaults module apply to the 140*333d2b36SAndroid Build Coastguard Worker// defaultable modules using it, not to the defaults module itself. E.g. setting 141*333d2b36SAndroid Build Coastguard Worker// the "enabled" property false makes inheriting modules disabled by default, 142*333d2b36SAndroid Build Coastguard Worker// rather than disabling the defaults module itself. 143*333d2b36SAndroid Build Coastguard Workertype Defaults interface { 144*333d2b36SAndroid Build Coastguard Worker Defaultable 145*333d2b36SAndroid Build Coastguard Worker 146*333d2b36SAndroid Build Coastguard Worker // Although this function is unused it is actually needed to ensure that only modules that embed 147*333d2b36SAndroid Build Coastguard Worker // DefaultsModuleBase will type-assert to the Defaults interface. 148*333d2b36SAndroid Build Coastguard Worker isDefaults() bool 149*333d2b36SAndroid Build Coastguard Worker 150*333d2b36SAndroid Build Coastguard Worker // Get the structures containing the properties for which defaults can be provided. 151*333d2b36SAndroid Build Coastguard Worker properties() []interface{} 152*333d2b36SAndroid Build Coastguard Worker 153*333d2b36SAndroid Build Coastguard Worker productVariableProperties() interface{} 154*333d2b36SAndroid Build Coastguard Worker} 155*333d2b36SAndroid Build Coastguard Worker 156*333d2b36SAndroid Build Coastguard Workerfunc (d *DefaultsModuleBase) isDefaults() bool { 157*333d2b36SAndroid Build Coastguard Worker return true 158*333d2b36SAndroid Build Coastguard Worker} 159*333d2b36SAndroid Build Coastguard Worker 160*333d2b36SAndroid Build Coastguard Workertype DefaultsModule interface { 161*333d2b36SAndroid Build Coastguard Worker Module 162*333d2b36SAndroid Build Coastguard Worker Defaults 163*333d2b36SAndroid Build Coastguard Worker} 164*333d2b36SAndroid Build Coastguard Worker 165*333d2b36SAndroid Build Coastguard Workerfunc (d *DefaultsModuleBase) properties() []interface{} { 166*333d2b36SAndroid Build Coastguard Worker return d.defaultableProperties 167*333d2b36SAndroid Build Coastguard Worker} 168*333d2b36SAndroid Build Coastguard Worker 169*333d2b36SAndroid Build Coastguard Workerfunc (d *DefaultsModuleBase) productVariableProperties() interface{} { 170*333d2b36SAndroid Build Coastguard Worker return d.defaultableVariableProperties 171*333d2b36SAndroid Build Coastguard Worker} 172*333d2b36SAndroid Build Coastguard Worker 173*333d2b36SAndroid Build Coastguard Workerfunc (d *DefaultsModuleBase) GenerateAndroidBuildActions(ctx ModuleContext) {} 174*333d2b36SAndroid Build Coastguard Worker 175*333d2b36SAndroid Build Coastguard Workerfunc InitDefaultsModule(module DefaultsModule) { 176*333d2b36SAndroid Build Coastguard Worker commonProperties := &commonProperties{} 177*333d2b36SAndroid Build Coastguard Worker 178*333d2b36SAndroid Build Coastguard Worker module.AddProperties( 179*333d2b36SAndroid Build Coastguard Worker &hostAndDeviceProperties{}, 180*333d2b36SAndroid Build Coastguard Worker commonProperties, 181*333d2b36SAndroid Build Coastguard Worker &ApexProperties{}, 182*333d2b36SAndroid Build Coastguard Worker &distProperties{}) 183*333d2b36SAndroid Build Coastguard Worker 184*333d2b36SAndroid Build Coastguard Worker initAndroidModuleBase(module) 185*333d2b36SAndroid Build Coastguard Worker initProductVariableModule(module) 186*333d2b36SAndroid Build Coastguard Worker initArchModule(module) 187*333d2b36SAndroid Build Coastguard Worker InitDefaultableModule(module) 188*333d2b36SAndroid Build Coastguard Worker 189*333d2b36SAndroid Build Coastguard Worker // Add properties that will not have defaults applied to them. 190*333d2b36SAndroid Build Coastguard Worker base := module.base() 191*333d2b36SAndroid Build Coastguard Worker defaultsVisibility := &DefaultsVisibilityProperties{} 192*333d2b36SAndroid Build Coastguard Worker module.AddProperties(&base.nameProperties, defaultsVisibility) 193*333d2b36SAndroid Build Coastguard Worker 194*333d2b36SAndroid Build Coastguard Worker // Unlike non-defaults modules the visibility property is not stored in m.base().commonProperties. 195*333d2b36SAndroid Build Coastguard Worker // Instead it is stored in a separate instance of commonProperties created above so clear the 196*333d2b36SAndroid Build Coastguard Worker // existing list of properties. 197*333d2b36SAndroid Build Coastguard Worker clearVisibilityProperties(module) 198*333d2b36SAndroid Build Coastguard Worker 199*333d2b36SAndroid Build Coastguard Worker // The defaults_visibility property controls the visibility of a defaults module so it must be 200*333d2b36SAndroid Build Coastguard Worker // set as the primary property, which also adds it to the list. 201*333d2b36SAndroid Build Coastguard Worker setPrimaryVisibilityProperty(module, "defaults_visibility", &defaultsVisibility.Defaults_visibility) 202*333d2b36SAndroid Build Coastguard Worker 203*333d2b36SAndroid Build Coastguard Worker // The visibility property needs to be checked (but not parsed) by the visibility module during 204*333d2b36SAndroid Build Coastguard Worker // its checking phase and parsing phase so add it to the list as a normal property. 205*333d2b36SAndroid Build Coastguard Worker AddVisibilityProperty(module, "visibility", &commonProperties.Visibility) 206*333d2b36SAndroid Build Coastguard Worker 207*333d2b36SAndroid Build Coastguard Worker // The applicable licenses property for defaults is 'licenses'. 208*333d2b36SAndroid Build Coastguard Worker setPrimaryLicensesProperty(module, "licenses", &commonProperties.Licenses) 209*333d2b36SAndroid Build Coastguard Worker} 210*333d2b36SAndroid Build Coastguard Worker 211*333d2b36SAndroid Build Coastguard Workervar _ Defaults = (*DefaultsModuleBase)(nil) 212*333d2b36SAndroid Build Coastguard Worker 213*333d2b36SAndroid Build Coastguard Workerfunc (defaultable *DefaultableModuleBase) applyDefaults(ctx BottomUpMutatorContext, 214*333d2b36SAndroid Build Coastguard Worker defaultsList []Defaults) { 215*333d2b36SAndroid Build Coastguard Worker 216*333d2b36SAndroid Build Coastguard Worker for _, defaults := range defaultsList { 217*333d2b36SAndroid Build Coastguard Worker for _, prop := range defaultable.defaultableProperties { 218*333d2b36SAndroid Build Coastguard Worker if prop == defaultable.defaultableVariableProperties { 219*333d2b36SAndroid Build Coastguard Worker defaultable.applyDefaultVariableProperties(ctx, defaults, prop) 220*333d2b36SAndroid Build Coastguard Worker } else { 221*333d2b36SAndroid Build Coastguard Worker defaultable.applyDefaultProperties(ctx, defaults, prop) 222*333d2b36SAndroid Build Coastguard Worker } 223*333d2b36SAndroid Build Coastguard Worker } 224*333d2b36SAndroid Build Coastguard Worker } 225*333d2b36SAndroid Build Coastguard Worker} 226*333d2b36SAndroid Build Coastguard Worker 227*333d2b36SAndroid Build Coastguard Worker// Product variable properties need special handling, the type of the filtered product variable 228*333d2b36SAndroid Build Coastguard Worker// property struct may not be identical between the defaults module and the defaultable module. 229*333d2b36SAndroid Build Coastguard Worker// Use PrependMatchingProperties to apply whichever properties match. 230*333d2b36SAndroid Build Coastguard Workerfunc (defaultable *DefaultableModuleBase) applyDefaultVariableProperties(ctx BottomUpMutatorContext, 231*333d2b36SAndroid Build Coastguard Worker defaults Defaults, defaultableProp interface{}) { 232*333d2b36SAndroid Build Coastguard Worker if defaultableProp == nil { 233*333d2b36SAndroid Build Coastguard Worker return 234*333d2b36SAndroid Build Coastguard Worker } 235*333d2b36SAndroid Build Coastguard Worker 236*333d2b36SAndroid Build Coastguard Worker defaultsProp := defaults.productVariableProperties() 237*333d2b36SAndroid Build Coastguard Worker if defaultsProp == nil { 238*333d2b36SAndroid Build Coastguard Worker return 239*333d2b36SAndroid Build Coastguard Worker } 240*333d2b36SAndroid Build Coastguard Worker 241*333d2b36SAndroid Build Coastguard Worker dst := []interface{}{ 242*333d2b36SAndroid Build Coastguard Worker defaultableProp, 243*333d2b36SAndroid Build Coastguard Worker // Put an empty copy of the src properties into dst so that properties in src that are not in dst 244*333d2b36SAndroid Build Coastguard Worker // don't cause a "failed to find property to extend" error. 245*333d2b36SAndroid Build Coastguard Worker proptools.CloneEmptyProperties(reflect.ValueOf(defaultsProp)).Interface(), 246*333d2b36SAndroid Build Coastguard Worker } 247*333d2b36SAndroid Build Coastguard Worker 248*333d2b36SAndroid Build Coastguard Worker err := proptools.PrependMatchingProperties(dst, defaultsProp, nil) 249*333d2b36SAndroid Build Coastguard Worker if err != nil { 250*333d2b36SAndroid Build Coastguard Worker if propertyErr, ok := err.(*proptools.ExtendPropertyError); ok { 251*333d2b36SAndroid Build Coastguard Worker ctx.PropertyErrorf(propertyErr.Property, "%s", propertyErr.Err.Error()) 252*333d2b36SAndroid Build Coastguard Worker } else { 253*333d2b36SAndroid Build Coastguard Worker panic(err) 254*333d2b36SAndroid Build Coastguard Worker } 255*333d2b36SAndroid Build Coastguard Worker } 256*333d2b36SAndroid Build Coastguard Worker} 257*333d2b36SAndroid Build Coastguard Worker 258*333d2b36SAndroid Build Coastguard Workerfunc (defaultable *DefaultableModuleBase) applyDefaultProperties(ctx BottomUpMutatorContext, 259*333d2b36SAndroid Build Coastguard Worker defaults Defaults, defaultableProp interface{}) { 260*333d2b36SAndroid Build Coastguard Worker 261*333d2b36SAndroid Build Coastguard Worker for _, def := range defaults.properties() { 262*333d2b36SAndroid Build Coastguard Worker if proptools.TypeEqual(defaultableProp, def) { 263*333d2b36SAndroid Build Coastguard Worker err := proptools.PrependProperties(defaultableProp, def, nil) 264*333d2b36SAndroid Build Coastguard Worker if err != nil { 265*333d2b36SAndroid Build Coastguard Worker if propertyErr, ok := err.(*proptools.ExtendPropertyError); ok { 266*333d2b36SAndroid Build Coastguard Worker ctx.PropertyErrorf(propertyErr.Property, "%s", propertyErr.Err.Error()) 267*333d2b36SAndroid Build Coastguard Worker } else { 268*333d2b36SAndroid Build Coastguard Worker panic(err) 269*333d2b36SAndroid Build Coastguard Worker } 270*333d2b36SAndroid Build Coastguard Worker } 271*333d2b36SAndroid Build Coastguard Worker } 272*333d2b36SAndroid Build Coastguard Worker } 273*333d2b36SAndroid Build Coastguard Worker} 274*333d2b36SAndroid Build Coastguard Worker 275*333d2b36SAndroid Build Coastguard Workerfunc RegisterDefaultsPreArchMutators(ctx RegisterMutatorsContext) { 276*333d2b36SAndroid Build Coastguard Worker ctx.BottomUp("defaults_deps", defaultsDepsMutator) 277*333d2b36SAndroid Build Coastguard Worker ctx.BottomUp("defaults", defaultsMutator).UsesCreateModule() 278*333d2b36SAndroid Build Coastguard Worker} 279*333d2b36SAndroid Build Coastguard Worker 280*333d2b36SAndroid Build Coastguard Workerfunc defaultsDepsMutator(ctx BottomUpMutatorContext) { 281*333d2b36SAndroid Build Coastguard Worker if defaultable, ok := ctx.Module().(Defaultable); ok { 282*333d2b36SAndroid Build Coastguard Worker ctx.AddDependency(ctx.Module(), DefaultsDepTag, defaultable.defaults().Defaults...) 283*333d2b36SAndroid Build Coastguard Worker } 284*333d2b36SAndroid Build Coastguard Worker} 285*333d2b36SAndroid Build Coastguard Worker 286*333d2b36SAndroid Build Coastguard Workerfunc defaultsMutator(ctx BottomUpMutatorContext) { 287*333d2b36SAndroid Build Coastguard Worker if defaultable, ok := ctx.Module().(Defaultable); ok { 288*333d2b36SAndroid Build Coastguard Worker if _, isDefaultsModule := ctx.Module().(Defaults); isDefaultsModule { 289*333d2b36SAndroid Build Coastguard Worker // Don't squash transitive defaults into defaults modules 290*333d2b36SAndroid Build Coastguard Worker return 291*333d2b36SAndroid Build Coastguard Worker } 292*333d2b36SAndroid Build Coastguard Worker defaults := defaultable.defaults().Defaults 293*333d2b36SAndroid Build Coastguard Worker if len(defaults) > 0 { 294*333d2b36SAndroid Build Coastguard Worker var defaultsList []Defaults 295*333d2b36SAndroid Build Coastguard Worker seen := make(map[Defaults]bool) 296*333d2b36SAndroid Build Coastguard Worker 297*333d2b36SAndroid Build Coastguard Worker ctx.WalkDeps(func(module, parent Module) bool { 298*333d2b36SAndroid Build Coastguard Worker if ctx.OtherModuleDependencyTag(module) == DefaultsDepTag { 299*333d2b36SAndroid Build Coastguard Worker if defaults, ok := module.(Defaults); ok { 300*333d2b36SAndroid Build Coastguard Worker if !seen[defaults] { 301*333d2b36SAndroid Build Coastguard Worker seen[defaults] = true 302*333d2b36SAndroid Build Coastguard Worker defaultsList = append(defaultsList, defaults) 303*333d2b36SAndroid Build Coastguard Worker return len(defaults.defaults().Defaults) > 0 304*333d2b36SAndroid Build Coastguard Worker } 305*333d2b36SAndroid Build Coastguard Worker } else { 306*333d2b36SAndroid Build Coastguard Worker ctx.PropertyErrorf("defaults", "module %s is not an defaults module", 307*333d2b36SAndroid Build Coastguard Worker ctx.OtherModuleName(module)) 308*333d2b36SAndroid Build Coastguard Worker } 309*333d2b36SAndroid Build Coastguard Worker } 310*333d2b36SAndroid Build Coastguard Worker return false 311*333d2b36SAndroid Build Coastguard Worker }) 312*333d2b36SAndroid Build Coastguard Worker defaultable.applyDefaults(ctx, defaultsList) 313*333d2b36SAndroid Build Coastguard Worker } 314*333d2b36SAndroid Build Coastguard Worker 315*333d2b36SAndroid Build Coastguard Worker defaultable.CallHookIfAvailable(ctx) 316*333d2b36SAndroid Build Coastguard Worker } 317*333d2b36SAndroid Build Coastguard Worker} 318