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 // Create an association between prebuilt modules and their corresponding source 119 // modules (if any). 120 // 121 // Must be run after defaults mutators to ensure that any modules created by 122 // a DefaultableHook can be either a prebuilt or a source module with a matching 123 // prebuilt. 124 RegisterPrebuiltsPreArchMutators, 125 126 // Gather the visibility rules for all modules for us during visibility enforcement. 127 // 128 // This must come after the defaults mutators to ensure that any visibility supplied 129 // in a defaults module has been successfully applied before the rules are gathered. 130 RegisterVisibilityRuleGatherer, 131} 132 133func registerArchMutator(ctx RegisterMutatorsContext) { 134 ctx.BottomUp("os", osMutator).Parallel() 135 ctx.BottomUp("image", imageMutator).Parallel() 136 ctx.BottomUp("arch", archMutator).Parallel() 137} 138 139var preDeps = []RegisterMutatorFunc{ 140 registerArchMutator, 141} 142 143var postDeps = []RegisterMutatorFunc{ 144 registerPathDepsMutator, 145 RegisterPrebuiltsPostDepsMutators, 146 RegisterVisibilityRuleEnforcer, 147 RegisterNeverallowMutator, 148 RegisterOverridePostDepsMutators, 149} 150 151var finalDeps = []RegisterMutatorFunc{} 152 153func PreArchMutators(f RegisterMutatorFunc) { 154 preArch = append(preArch, f) 155} 156 157func PreDepsMutators(f RegisterMutatorFunc) { 158 preDeps = append(preDeps, f) 159} 160 161func PostDepsMutators(f RegisterMutatorFunc) { 162 postDeps = append(postDeps, f) 163} 164 165func FinalDepsMutators(f RegisterMutatorFunc) { 166 finalDeps = append(finalDeps, f) 167} 168 169type TopDownMutator func(TopDownMutatorContext) 170 171type TopDownMutatorContext interface { 172 BaseModuleContext 173 174 MutatorName() string 175 176 Rename(name string) 177 178 CreateModule(ModuleFactory, ...interface{}) Module 179} 180 181type topDownMutatorContext struct { 182 bp blueprint.TopDownMutatorContext 183 baseModuleContext 184} 185 186type BottomUpMutator func(BottomUpMutatorContext) 187 188type BottomUpMutatorContext interface { 189 BaseModuleContext 190 191 MutatorName() string 192 193 Rename(name string) 194 195 AddDependency(module blueprint.Module, tag blueprint.DependencyTag, name ...string) 196 AddReverseDependency(module blueprint.Module, tag blueprint.DependencyTag, name string) 197 CreateVariations(...string) []Module 198 CreateLocalVariations(...string) []Module 199 SetDependencyVariation(string) 200 SetDefaultDependencyVariation(*string) 201 AddVariationDependencies([]blueprint.Variation, blueprint.DependencyTag, ...string) 202 AddFarVariationDependencies([]blueprint.Variation, blueprint.DependencyTag, ...string) 203 AddInterVariantDependency(tag blueprint.DependencyTag, from, to blueprint.Module) 204 ReplaceDependencies(string) 205 AliasVariation(variationName string) 206} 207 208type bottomUpMutatorContext struct { 209 bp blueprint.BottomUpMutatorContext 210 baseModuleContext 211 finalPhase bool 212} 213 214func (x *registerMutatorsContext) BottomUp(name string, m BottomUpMutator) MutatorHandle { 215 finalPhase := x.finalPhase 216 f := func(ctx blueprint.BottomUpMutatorContext) { 217 if a, ok := ctx.Module().(Module); ok { 218 actx := &bottomUpMutatorContext{ 219 bp: ctx, 220 baseModuleContext: a.base().baseModuleContextFactory(ctx), 221 finalPhase: finalPhase, 222 } 223 m(actx) 224 } 225 } 226 mutator := &mutator{name: name, bottomUpMutator: f} 227 x.mutators = append(x.mutators, mutator) 228 return mutator 229} 230 231func (x *registerMutatorsContext) TopDown(name string, m TopDownMutator) MutatorHandle { 232 f := func(ctx blueprint.TopDownMutatorContext) { 233 if a, ok := ctx.Module().(Module); ok { 234 actx := &topDownMutatorContext{ 235 bp: ctx, 236 baseModuleContext: a.base().baseModuleContextFactory(ctx), 237 } 238 m(actx) 239 } 240 } 241 mutator := &mutator{name: name, topDownMutator: f} 242 x.mutators = append(x.mutators, mutator) 243 return mutator 244} 245 246type MutatorHandle interface { 247 Parallel() MutatorHandle 248} 249 250func (mutator *mutator) Parallel() MutatorHandle { 251 mutator.parallel = true 252 return mutator 253} 254 255func depsMutator(ctx BottomUpMutatorContext) { 256 if m, ok := ctx.Module().(Module); ok && m.Enabled() { 257 m.DepsMutator(ctx) 258 } 259} 260 261func (t *topDownMutatorContext) AppendProperties(props ...interface{}) { 262 for _, p := range props { 263 err := proptools.AppendMatchingProperties(t.Module().base().customizableProperties, 264 p, nil) 265 if err != nil { 266 if propertyErr, ok := err.(*proptools.ExtendPropertyError); ok { 267 t.PropertyErrorf(propertyErr.Property, "%s", propertyErr.Err.Error()) 268 } else { 269 panic(err) 270 } 271 } 272 } 273} 274 275func (t *topDownMutatorContext) PrependProperties(props ...interface{}) { 276 for _, p := range props { 277 err := proptools.PrependMatchingProperties(t.Module().base().customizableProperties, 278 p, nil) 279 if err != nil { 280 if propertyErr, ok := err.(*proptools.ExtendPropertyError); ok { 281 t.PropertyErrorf(propertyErr.Property, "%s", propertyErr.Err.Error()) 282 } else { 283 panic(err) 284 } 285 } 286 } 287} 288 289// android.topDownMutatorContext either has to embed blueprint.TopDownMutatorContext, in which case every method that 290// has an overridden version in android.BaseModuleContext has to be manually forwarded to BaseModuleContext to avoid 291// ambiguous method errors, or it has to store a blueprint.TopDownMutatorContext non-embedded, in which case every 292// non-overridden method has to be forwarded. There are fewer non-overridden methods, so use the latter. The following 293// methods forward to the identical blueprint versions for topDownMutatorContext and bottomUpMutatorContext. 294 295func (t *topDownMutatorContext) MutatorName() string { 296 return t.bp.MutatorName() 297} 298 299func (t *topDownMutatorContext) Rename(name string) { 300 t.bp.Rename(name) 301 t.Module().base().commonProperties.DebugName = name 302} 303 304func (t *topDownMutatorContext) CreateModule(factory ModuleFactory, props ...interface{}) Module { 305 inherited := []interface{}{&t.Module().base().commonProperties} 306 module := t.bp.CreateModule(ModuleFactoryAdaptor(factory), append(inherited, props...)...).(Module) 307 308 if t.Module().base().variableProperties != nil && module.base().variableProperties != nil { 309 src := t.Module().base().variableProperties 310 dst := []interface{}{ 311 module.base().variableProperties, 312 // Put an empty copy of the src properties into dst so that properties in src that are not in dst 313 // don't cause a "failed to find property to extend" error. 314 proptools.CloneEmptyProperties(reflect.ValueOf(src)).Interface(), 315 } 316 err := proptools.AppendMatchingProperties(dst, src, nil) 317 if err != nil { 318 panic(err) 319 } 320 } 321 322 return module 323} 324 325func (b *bottomUpMutatorContext) MutatorName() string { 326 return b.bp.MutatorName() 327} 328 329func (b *bottomUpMutatorContext) Rename(name string) { 330 b.bp.Rename(name) 331 b.Module().base().commonProperties.DebugName = name 332} 333 334func (b *bottomUpMutatorContext) AddDependency(module blueprint.Module, tag blueprint.DependencyTag, name ...string) { 335 b.bp.AddDependency(module, tag, name...) 336} 337 338func (b *bottomUpMutatorContext) AddReverseDependency(module blueprint.Module, tag blueprint.DependencyTag, name string) { 339 b.bp.AddReverseDependency(module, tag, name) 340} 341 342func (b *bottomUpMutatorContext) CreateVariations(variations ...string) []Module { 343 if b.finalPhase { 344 panic("CreateVariations not allowed in FinalDepsMutators") 345 } 346 347 modules := b.bp.CreateVariations(variations...) 348 349 aModules := make([]Module, len(modules)) 350 for i := range variations { 351 aModules[i] = modules[i].(Module) 352 base := aModules[i].base() 353 base.commonProperties.DebugMutators = append(base.commonProperties.DebugMutators, b.MutatorName()) 354 base.commonProperties.DebugVariations = append(base.commonProperties.DebugVariations, variations[i]) 355 } 356 357 return aModules 358} 359 360func (b *bottomUpMutatorContext) CreateLocalVariations(variations ...string) []Module { 361 if b.finalPhase { 362 panic("CreateLocalVariations not allowed in FinalDepsMutators") 363 } 364 365 modules := b.bp.CreateLocalVariations(variations...) 366 367 aModules := make([]Module, len(modules)) 368 for i := range variations { 369 aModules[i] = modules[i].(Module) 370 base := aModules[i].base() 371 base.commonProperties.DebugMutators = append(base.commonProperties.DebugMutators, b.MutatorName()) 372 base.commonProperties.DebugVariations = append(base.commonProperties.DebugVariations, variations[i]) 373 } 374 375 return aModules 376} 377 378func (b *bottomUpMutatorContext) SetDependencyVariation(variation string) { 379 b.bp.SetDependencyVariation(variation) 380} 381 382func (b *bottomUpMutatorContext) SetDefaultDependencyVariation(variation *string) { 383 b.bp.SetDefaultDependencyVariation(variation) 384} 385 386func (b *bottomUpMutatorContext) AddVariationDependencies(variations []blueprint.Variation, tag blueprint.DependencyTag, 387 names ...string) { 388 389 b.bp.AddVariationDependencies(variations, tag, names...) 390} 391 392func (b *bottomUpMutatorContext) AddFarVariationDependencies(variations []blueprint.Variation, 393 tag blueprint.DependencyTag, names ...string) { 394 395 b.bp.AddFarVariationDependencies(variations, tag, names...) 396} 397 398func (b *bottomUpMutatorContext) AddInterVariantDependency(tag blueprint.DependencyTag, from, to blueprint.Module) { 399 b.bp.AddInterVariantDependency(tag, from, to) 400} 401 402func (b *bottomUpMutatorContext) ReplaceDependencies(name string) { 403 b.bp.ReplaceDependencies(name) 404} 405 406func (b *bottomUpMutatorContext) AliasVariation(variationName string) { 407 b.bp.AliasVariation(variationName) 408} 409