1// Copyright 2015 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 android 16 17import ( 18 "github.com/google/blueprint" 19 "github.com/google/blueprint/proptools" 20) 21 22// Phases: 23// run Pre-arch mutators 24// run archMutator 25// run Pre-deps mutators 26// run depsMutator 27// run PostDeps mutators 28// continue on to GenerateAndroidBuildActions 29 30func registerMutatorsToContext(ctx *blueprint.Context, mutators []*mutator) { 31 for _, t := range mutators { 32 var handle blueprint.MutatorHandle 33 if t.bottomUpMutator != nil { 34 handle = ctx.RegisterBottomUpMutator(t.name, t.bottomUpMutator) 35 } else if t.topDownMutator != nil { 36 handle = ctx.RegisterTopDownMutator(t.name, t.topDownMutator) 37 } 38 if t.parallel { 39 handle.Parallel() 40 } 41 } 42} 43 44func registerMutators(ctx *blueprint.Context, preArch, preDeps, postDeps []RegisterMutatorFunc) { 45 mctx := ®isterMutatorsContext{} 46 47 register := func(funcs []RegisterMutatorFunc) { 48 for _, f := range funcs { 49 f(mctx) 50 } 51 } 52 53 register(preArch) 54 55 register(preDeps) 56 57 mctx.BottomUp("deps", depsMutator).Parallel() 58 59 register(postDeps) 60 61 registerMutatorsToContext(ctx, mctx.mutators) 62} 63 64type registerMutatorsContext struct { 65 mutators []*mutator 66} 67 68type RegisterMutatorsContext interface { 69 TopDown(name string, m AndroidTopDownMutator) MutatorHandle 70 BottomUp(name string, m AndroidBottomUpMutator) MutatorHandle 71} 72 73type RegisterMutatorFunc func(RegisterMutatorsContext) 74 75var preArch = []RegisterMutatorFunc{ 76 func(ctx RegisterMutatorsContext) { 77 ctx.TopDown("load_hooks", loadHookMutator).Parallel() 78 }, 79 RegisterNamespaceMutator, 80 RegisterPrebuiltsPreArchMutators, 81 RegisterDefaultsPreArchMutators, 82} 83 84func registerArchMutator(ctx RegisterMutatorsContext) { 85 ctx.BottomUp("arch", archMutator).Parallel() 86 ctx.TopDown("arch_hooks", archHookMutator).Parallel() 87} 88 89var preDeps = []RegisterMutatorFunc{ 90 registerArchMutator, 91} 92 93var postDeps = []RegisterMutatorFunc{ 94 RegisterPrebuiltsPostDepsMutators, 95 registerNeverallowMutator, 96} 97 98func PreArchMutators(f RegisterMutatorFunc) { 99 preArch = append(preArch, f) 100} 101 102func PreDepsMutators(f RegisterMutatorFunc) { 103 preDeps = append(preDeps, f) 104} 105 106func PostDepsMutators(f RegisterMutatorFunc) { 107 postDeps = append(postDeps, f) 108} 109 110type AndroidTopDownMutator func(TopDownMutatorContext) 111 112type TopDownMutatorContext interface { 113 BaseModuleContext 114 androidBaseContext 115 116 OtherModuleExists(name string) bool 117 Rename(name string) 118 Module() Module 119 120 OtherModuleName(m blueprint.Module) string 121 OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{}) 122 OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag 123 124 CreateModule(blueprint.ModuleFactory, ...interface{}) 125 126 GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module 127 GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag) 128 129 VisitDirectDeps(visit func(Module)) 130 VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module)) 131 VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) 132 VisitDepsDepthFirst(visit func(Module)) 133 VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module)) 134 WalkDeps(visit func(Module, Module) bool) 135} 136 137type androidTopDownMutatorContext struct { 138 blueprint.TopDownMutatorContext 139 androidBaseContextImpl 140} 141 142type AndroidBottomUpMutator func(BottomUpMutatorContext) 143 144type BottomUpMutatorContext interface { 145 BaseModuleContext 146 androidBaseContext 147 148 OtherModuleExists(name string) bool 149 Rename(name string) 150 Module() blueprint.Module 151 152 AddDependency(module blueprint.Module, tag blueprint.DependencyTag, name ...string) 153 AddReverseDependency(module blueprint.Module, tag blueprint.DependencyTag, name string) 154 CreateVariations(...string) []blueprint.Module 155 CreateLocalVariations(...string) []blueprint.Module 156 SetDependencyVariation(string) 157 AddVariationDependencies([]blueprint.Variation, blueprint.DependencyTag, ...string) 158 AddFarVariationDependencies([]blueprint.Variation, blueprint.DependencyTag, ...string) 159 AddInterVariantDependency(tag blueprint.DependencyTag, from, to blueprint.Module) 160 ReplaceDependencies(string) 161} 162 163type androidBottomUpMutatorContext struct { 164 blueprint.BottomUpMutatorContext 165 androidBaseContextImpl 166} 167 168func (x *registerMutatorsContext) BottomUp(name string, m AndroidBottomUpMutator) MutatorHandle { 169 f := func(ctx blueprint.BottomUpMutatorContext) { 170 if a, ok := ctx.Module().(Module); ok { 171 actx := &androidBottomUpMutatorContext{ 172 BottomUpMutatorContext: ctx, 173 androidBaseContextImpl: a.base().androidBaseContextFactory(ctx), 174 } 175 m(actx) 176 } 177 } 178 mutator := &mutator{name: name, bottomUpMutator: f} 179 x.mutators = append(x.mutators, mutator) 180 return mutator 181} 182 183func (x *registerMutatorsContext) TopDown(name string, m AndroidTopDownMutator) MutatorHandle { 184 f := func(ctx blueprint.TopDownMutatorContext) { 185 if a, ok := ctx.Module().(Module); ok { 186 actx := &androidTopDownMutatorContext{ 187 TopDownMutatorContext: ctx, 188 androidBaseContextImpl: a.base().androidBaseContextFactory(ctx), 189 } 190 m(actx) 191 } 192 } 193 mutator := &mutator{name: name, topDownMutator: f} 194 x.mutators = append(x.mutators, mutator) 195 return mutator 196} 197 198type MutatorHandle interface { 199 Parallel() MutatorHandle 200} 201 202func (mutator *mutator) Parallel() MutatorHandle { 203 mutator.parallel = true 204 return mutator 205} 206 207func depsMutator(ctx BottomUpMutatorContext) { 208 if m, ok := ctx.Module().(Module); ok { 209 m.DepsMutator(ctx) 210 } 211} 212 213func (a *androidTopDownMutatorContext) Config() Config { 214 return a.config 215} 216 217func (a *androidBottomUpMutatorContext) Config() Config { 218 return a.config 219} 220 221func (a *androidTopDownMutatorContext) Module() Module { 222 module, _ := a.TopDownMutatorContext.Module().(Module) 223 return module 224} 225 226func (a *androidTopDownMutatorContext) VisitDirectDeps(visit func(Module)) { 227 a.TopDownMutatorContext.VisitDirectDeps(func(module blueprint.Module) { 228 if aModule, _ := module.(Module); aModule != nil { 229 visit(aModule) 230 } 231 }) 232} 233 234func (a *androidTopDownMutatorContext) VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module)) { 235 a.TopDownMutatorContext.VisitDirectDeps(func(module blueprint.Module) { 236 if aModule, _ := module.(Module); aModule != nil { 237 if a.TopDownMutatorContext.OtherModuleDependencyTag(aModule) == tag { 238 visit(aModule) 239 } 240 } 241 }) 242} 243 244func (a *androidTopDownMutatorContext) VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) { 245 a.TopDownMutatorContext.VisitDirectDepsIf( 246 // pred 247 func(module blueprint.Module) bool { 248 if aModule, _ := module.(Module); aModule != nil { 249 return pred(aModule) 250 } else { 251 return false 252 } 253 }, 254 // visit 255 func(module blueprint.Module) { 256 visit(module.(Module)) 257 }) 258} 259 260func (a *androidTopDownMutatorContext) VisitDepsDepthFirst(visit func(Module)) { 261 a.TopDownMutatorContext.VisitDepsDepthFirst(func(module blueprint.Module) { 262 if aModule, _ := module.(Module); aModule != nil { 263 visit(aModule) 264 } 265 }) 266} 267 268func (a *androidTopDownMutatorContext) VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module)) { 269 a.TopDownMutatorContext.VisitDepsDepthFirstIf( 270 // pred 271 func(module blueprint.Module) bool { 272 if aModule, _ := module.(Module); aModule != nil { 273 return pred(aModule) 274 } else { 275 return false 276 } 277 }, 278 // visit 279 func(module blueprint.Module) { 280 visit(module.(Module)) 281 }) 282} 283 284func (a *androidTopDownMutatorContext) WalkDeps(visit func(Module, Module) bool) { 285 a.TopDownMutatorContext.WalkDeps(func(child, parent blueprint.Module) bool { 286 childAndroidModule, _ := child.(Module) 287 parentAndroidModule, _ := parent.(Module) 288 if childAndroidModule != nil && parentAndroidModule != nil { 289 return visit(childAndroidModule, parentAndroidModule) 290 } else { 291 return false 292 } 293 }) 294} 295 296func (a *androidTopDownMutatorContext) AppendProperties(props ...interface{}) { 297 for _, p := range props { 298 err := proptools.AppendMatchingProperties(a.Module().base().customizableProperties, 299 p, nil) 300 if err != nil { 301 if propertyErr, ok := err.(*proptools.ExtendPropertyError); ok { 302 a.PropertyErrorf(propertyErr.Property, "%s", propertyErr.Err.Error()) 303 } else { 304 panic(err) 305 } 306 } 307 } 308} 309 310func (a *androidTopDownMutatorContext) PrependProperties(props ...interface{}) { 311 for _, p := range props { 312 err := proptools.PrependMatchingProperties(a.Module().base().customizableProperties, 313 p, nil) 314 if err != nil { 315 if propertyErr, ok := err.(*proptools.ExtendPropertyError); ok { 316 a.PropertyErrorf(propertyErr.Property, "%s", propertyErr.Err.Error()) 317 } else { 318 panic(err) 319 } 320 } 321 } 322} 323