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 "reflect" 19 20 "github.com/google/blueprint" 21 "github.com/google/blueprint/proptools" 22) 23 24// Phases: 25// run Pre-arch mutators 26// run archMutator 27// run Pre-deps mutators 28// run depsMutator 29// run PostDeps mutators 30// run FinalDeps mutators (CreateVariations disallowed in this phase) 31// continue on to GenerateAndroidBuildActions 32 33func registerMutatorsToContext(ctx *blueprint.Context, mutators []*mutator) { 34 for _, t := range mutators { 35 var handle blueprint.MutatorHandle 36 if t.bottomUpMutator != nil { 37 handle = ctx.RegisterBottomUpMutator(t.name, t.bottomUpMutator) 38 } else if t.topDownMutator != nil { 39 handle = ctx.RegisterTopDownMutator(t.name, t.topDownMutator) 40 } 41 if t.parallel { 42 handle.Parallel() 43 } 44 } 45} 46 47func registerMutators(ctx *blueprint.Context, preArch, preDeps, postDeps, finalDeps []RegisterMutatorFunc) { 48 mctx := ®isterMutatorsContext{} 49 50 register := func(funcs []RegisterMutatorFunc) { 51 for _, f := range funcs { 52 f(mctx) 53 } 54 } 55 56 register(preArch) 57 58 register(preDeps) 59 60 mctx.BottomUp("deps", depsMutator).Parallel() 61 62 register(postDeps) 63 64 mctx.finalPhase = true 65 register(finalDeps) 66 67 registerMutatorsToContext(ctx, mctx.mutators) 68} 69 70type registerMutatorsContext struct { 71 mutators []*mutator 72 finalPhase bool 73} 74 75type RegisterMutatorsContext interface { 76 TopDown(name string, m TopDownMutator) MutatorHandle 77 BottomUp(name string, m BottomUpMutator) MutatorHandle 78} 79 80type RegisterMutatorFunc func(RegisterMutatorsContext) 81 82var preArch = []RegisterMutatorFunc{ 83 RegisterNamespaceMutator, 84 85 // Check the visibility rules are valid. 86 // 87 // This must run after the package renamer mutators so that any issues found during 88 // validation of the package's default_visibility property are reported using the 89 // correct package name and not the synthetic name. 90 // 91 // This must also be run before defaults mutators as the rules for validation are 92 // different before checking the rules than they are afterwards. e.g. 93 // visibility: ["//visibility:private", "//visibility:public"] 94 // would be invalid if specified in a module definition but is valid if it results 95 // from something like this: 96 // 97 // defaults { 98 // name: "defaults", 99 // // Be inaccessible outside a package by default. 100 // visibility: ["//visibility:private"] 101 // } 102 // 103 // defaultable_module { 104 // name: "defaultable_module", 105 // defaults: ["defaults"], 106 // // Override the default. 107 // visibility: ["//visibility:public"] 108 // } 109 // 110 RegisterVisibilityRuleChecker, 111 112 // Apply properties from defaults modules to the referencing modules. 113 // 114 // Any mutators that are added before this will not see any modules created by 115 // a DefaultableHook. 116 RegisterDefaultsPreArchMutators, 117 118 // Add dependencies on any components so that any component references can be 119 // resolved within the deps mutator. 120 // 121 // Must be run after defaults so it can be used to create dependencies on the 122 // component modules that are creating in a DefaultableHook. 123 // 124 // Must be run before RegisterPrebuiltsPreArchMutators, i.e. before prebuilts are 125 // renamed. That is so that if a module creates components using a prebuilt module 126 // type that any dependencies (which must use prebuilt_ prefixes) are resolved to 127 // the prebuilt module and not the source module. 128 RegisterComponentsMutator, 129 130 // Create an association between prebuilt modules and their corresponding source 131 // modules (if any). 132 // 133 // Must be run after defaults mutators to ensure that any modules created by 134 // a DefaultableHook can be either a prebuilt or a source module with a matching 135 // prebuilt. 136 RegisterPrebuiltsPreArchMutators, 137 138 // Gather the visibility rules for all modules for us during visibility enforcement. 139 // 140 // This must come after the defaults mutators to ensure that any visibility supplied 141 // in a defaults module has been successfully applied before the rules are gathered. 142 RegisterVisibilityRuleGatherer, 143} 144 145func registerArchMutator(ctx RegisterMutatorsContext) { 146 ctx.BottomUp("os", osMutator).Parallel() 147 ctx.BottomUp("image", imageMutator).Parallel() 148 ctx.BottomUp("arch", archMutator).Parallel() 149} 150 151var preDeps = []RegisterMutatorFunc{ 152 registerArchMutator, 153} 154 155var postDeps = []RegisterMutatorFunc{ 156 registerPathDepsMutator, 157 RegisterPrebuiltsPostDepsMutators, 158 RegisterVisibilityRuleEnforcer, 159 RegisterNeverallowMutator, 160 RegisterOverridePostDepsMutators, 161} 162 163var finalDeps = []RegisterMutatorFunc{} 164 165func PreArchMutators(f RegisterMutatorFunc) { 166 preArch = append(preArch, f) 167} 168 169func PreDepsMutators(f RegisterMutatorFunc) { 170 preDeps = append(preDeps, f) 171} 172 173func PostDepsMutators(f RegisterMutatorFunc) { 174 postDeps = append(postDeps, f) 175} 176 177func FinalDepsMutators(f RegisterMutatorFunc) { 178 finalDeps = append(finalDeps, f) 179} 180 181type TopDownMutator func(TopDownMutatorContext) 182 183type TopDownMutatorContext interface { 184 BaseModuleContext 185 186 MutatorName() string 187 188 Rename(name string) 189 190 CreateModule(ModuleFactory, ...interface{}) Module 191} 192 193type topDownMutatorContext struct { 194 bp blueprint.TopDownMutatorContext 195 baseModuleContext 196} 197 198type BottomUpMutator func(BottomUpMutatorContext) 199 200type BottomUpMutatorContext interface { 201 BaseModuleContext 202 203 MutatorName() string 204 205 Rename(name string) 206 207 AddDependency(module blueprint.Module, tag blueprint.DependencyTag, name ...string) 208 AddReverseDependency(module blueprint.Module, tag blueprint.DependencyTag, name string) 209 CreateVariations(...string) []Module 210 CreateLocalVariations(...string) []Module 211 SetDependencyVariation(string) 212 SetDefaultDependencyVariation(*string) 213 AddVariationDependencies([]blueprint.Variation, blueprint.DependencyTag, ...string) 214 AddFarVariationDependencies([]blueprint.Variation, blueprint.DependencyTag, ...string) 215 AddInterVariantDependency(tag blueprint.DependencyTag, from, to blueprint.Module) 216 ReplaceDependencies(string) 217 ReplaceDependenciesIf(string, blueprint.ReplaceDependencyPredicate) 218 AliasVariation(variationName string) 219} 220 221type bottomUpMutatorContext struct { 222 bp blueprint.BottomUpMutatorContext 223 baseModuleContext 224 finalPhase bool 225} 226 227func (x *registerMutatorsContext) BottomUp(name string, m BottomUpMutator) MutatorHandle { 228 finalPhase := x.finalPhase 229 f := func(ctx blueprint.BottomUpMutatorContext) { 230 if a, ok := ctx.Module().(Module); ok { 231 actx := &bottomUpMutatorContext{ 232 bp: ctx, 233 baseModuleContext: a.base().baseModuleContextFactory(ctx), 234 finalPhase: finalPhase, 235 } 236 m(actx) 237 } 238 } 239 mutator := &mutator{name: name, bottomUpMutator: f} 240 x.mutators = append(x.mutators, mutator) 241 return mutator 242} 243 244func (x *registerMutatorsContext) TopDown(name string, m TopDownMutator) MutatorHandle { 245 f := func(ctx blueprint.TopDownMutatorContext) { 246 if a, ok := ctx.Module().(Module); ok { 247 actx := &topDownMutatorContext{ 248 bp: ctx, 249 baseModuleContext: a.base().baseModuleContextFactory(ctx), 250 } 251 m(actx) 252 } 253 } 254 mutator := &mutator{name: name, topDownMutator: f} 255 x.mutators = append(x.mutators, mutator) 256 return mutator 257} 258 259type MutatorHandle interface { 260 Parallel() MutatorHandle 261} 262 263func (mutator *mutator) Parallel() MutatorHandle { 264 mutator.parallel = true 265 return mutator 266} 267 268func RegisterComponentsMutator(ctx RegisterMutatorsContext) { 269 ctx.BottomUp("component-deps", componentDepsMutator).Parallel() 270} 271 272// A special mutator that runs just prior to the deps mutator to allow the dependencies 273// on component modules to be added so that they can depend directly on a prebuilt 274// module. 275func componentDepsMutator(ctx BottomUpMutatorContext) { 276 if m := ctx.Module(); m.Enabled() { 277 m.ComponentDepsMutator(ctx) 278 } 279} 280 281func depsMutator(ctx BottomUpMutatorContext) { 282 if m := ctx.Module(); m.Enabled() { 283 m.DepsMutator(ctx) 284 } 285} 286 287func (t *topDownMutatorContext) AppendProperties(props ...interface{}) { 288 for _, p := range props { 289 err := proptools.AppendMatchingProperties(t.Module().base().customizableProperties, 290 p, nil) 291 if err != nil { 292 if propertyErr, ok := err.(*proptools.ExtendPropertyError); ok { 293 t.PropertyErrorf(propertyErr.Property, "%s", propertyErr.Err.Error()) 294 } else { 295 panic(err) 296 } 297 } 298 } 299} 300 301func (t *topDownMutatorContext) PrependProperties(props ...interface{}) { 302 for _, p := range props { 303 err := proptools.PrependMatchingProperties(t.Module().base().customizableProperties, 304 p, nil) 305 if err != nil { 306 if propertyErr, ok := err.(*proptools.ExtendPropertyError); ok { 307 t.PropertyErrorf(propertyErr.Property, "%s", propertyErr.Err.Error()) 308 } else { 309 panic(err) 310 } 311 } 312 } 313} 314 315// android.topDownMutatorContext either has to embed blueprint.TopDownMutatorContext, in which case every method that 316// has an overridden version in android.BaseModuleContext has to be manually forwarded to BaseModuleContext to avoid 317// ambiguous method errors, or it has to store a blueprint.TopDownMutatorContext non-embedded, in which case every 318// non-overridden method has to be forwarded. There are fewer non-overridden methods, so use the latter. The following 319// methods forward to the identical blueprint versions for topDownMutatorContext and bottomUpMutatorContext. 320 321func (t *topDownMutatorContext) MutatorName() string { 322 return t.bp.MutatorName() 323} 324 325func (t *topDownMutatorContext) Rename(name string) { 326 t.bp.Rename(name) 327 t.Module().base().commonProperties.DebugName = name 328} 329 330func (t *topDownMutatorContext) CreateModule(factory ModuleFactory, props ...interface{}) Module { 331 inherited := []interface{}{&t.Module().base().commonProperties} 332 module := t.bp.CreateModule(ModuleFactoryAdaptor(factory), append(inherited, props...)...).(Module) 333 334 if t.Module().base().variableProperties != nil && module.base().variableProperties != nil { 335 src := t.Module().base().variableProperties 336 dst := []interface{}{ 337 module.base().variableProperties, 338 // Put an empty copy of the src properties into dst so that properties in src that are not in dst 339 // don't cause a "failed to find property to extend" error. 340 proptools.CloneEmptyProperties(reflect.ValueOf(src)).Interface(), 341 } 342 err := proptools.AppendMatchingProperties(dst, src, nil) 343 if err != nil { 344 panic(err) 345 } 346 } 347 348 return module 349} 350 351func (b *bottomUpMutatorContext) MutatorName() string { 352 return b.bp.MutatorName() 353} 354 355func (b *bottomUpMutatorContext) Rename(name string) { 356 b.bp.Rename(name) 357 b.Module().base().commonProperties.DebugName = name 358} 359 360func (b *bottomUpMutatorContext) AddDependency(module blueprint.Module, tag blueprint.DependencyTag, name ...string) { 361 b.bp.AddDependency(module, tag, name...) 362} 363 364func (b *bottomUpMutatorContext) AddReverseDependency(module blueprint.Module, tag blueprint.DependencyTag, name string) { 365 b.bp.AddReverseDependency(module, tag, name) 366} 367 368func (b *bottomUpMutatorContext) CreateVariations(variations ...string) []Module { 369 if b.finalPhase { 370 panic("CreateVariations not allowed in FinalDepsMutators") 371 } 372 373 modules := b.bp.CreateVariations(variations...) 374 375 aModules := make([]Module, len(modules)) 376 for i := range variations { 377 aModules[i] = modules[i].(Module) 378 base := aModules[i].base() 379 base.commonProperties.DebugMutators = append(base.commonProperties.DebugMutators, b.MutatorName()) 380 base.commonProperties.DebugVariations = append(base.commonProperties.DebugVariations, variations[i]) 381 } 382 383 return aModules 384} 385 386func (b *bottomUpMutatorContext) CreateLocalVariations(variations ...string) []Module { 387 if b.finalPhase { 388 panic("CreateLocalVariations not allowed in FinalDepsMutators") 389 } 390 391 modules := b.bp.CreateLocalVariations(variations...) 392 393 aModules := make([]Module, len(modules)) 394 for i := range variations { 395 aModules[i] = modules[i].(Module) 396 base := aModules[i].base() 397 base.commonProperties.DebugMutators = append(base.commonProperties.DebugMutators, b.MutatorName()) 398 base.commonProperties.DebugVariations = append(base.commonProperties.DebugVariations, variations[i]) 399 } 400 401 return aModules 402} 403 404func (b *bottomUpMutatorContext) SetDependencyVariation(variation string) { 405 b.bp.SetDependencyVariation(variation) 406} 407 408func (b *bottomUpMutatorContext) SetDefaultDependencyVariation(variation *string) { 409 b.bp.SetDefaultDependencyVariation(variation) 410} 411 412func (b *bottomUpMutatorContext) AddVariationDependencies(variations []blueprint.Variation, tag blueprint.DependencyTag, 413 names ...string) { 414 415 b.bp.AddVariationDependencies(variations, tag, names...) 416} 417 418func (b *bottomUpMutatorContext) AddFarVariationDependencies(variations []blueprint.Variation, 419 tag blueprint.DependencyTag, names ...string) { 420 421 b.bp.AddFarVariationDependencies(variations, tag, names...) 422} 423 424func (b *bottomUpMutatorContext) AddInterVariantDependency(tag blueprint.DependencyTag, from, to blueprint.Module) { 425 b.bp.AddInterVariantDependency(tag, from, to) 426} 427 428func (b *bottomUpMutatorContext) ReplaceDependencies(name string) { 429 b.bp.ReplaceDependencies(name) 430} 431 432func (b *bottomUpMutatorContext) ReplaceDependenciesIf(name string, predicate blueprint.ReplaceDependencyPredicate) { 433 b.bp.ReplaceDependenciesIf(name, predicate) 434} 435 436func (b *bottomUpMutatorContext) AliasVariation(variationName string) { 437 b.bp.AliasVariation(variationName) 438} 439