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 15 package android 16 17 import ( 18 "sync" 19 20 "github.com/google/blueprint" 21 ) 22 23 // Mutator phases: 24 // Pre-arch 25 // Arch 26 // Pre-deps 27 // Deps 28 // PostDeps 29 30 var registerMutatorsOnce sync.Once 31 var registeredMutators []*mutator 32 33 func 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 47 func registerMutators(ctx *blueprint.Context) { 48 49 registerMutatorsOnce.Do(func() { 50 ctx := ®isterMutatorsContext{} 51 52 register := func(funcs []RegisterMutatorFunc) { 53 for _, f := range funcs { 54 f(ctx) 55 } 56 } 57 58 ctx.TopDown("load_hooks", loadHookMutator).Parallel() 59 ctx.BottomUp("prebuilts", prebuiltMutator).Parallel() 60 ctx.BottomUp("defaults_deps", defaultsDepsMutator).Parallel() 61 ctx.TopDown("defaults", defaultsMutator).Parallel() 62 63 register(preArch) 64 65 ctx.BottomUp("arch", archMutator).Parallel() 66 ctx.TopDown("arch_hooks", archHookMutator).Parallel() 67 68 register(preDeps) 69 70 ctx.BottomUp("deps", depsMutator).Parallel() 71 72 ctx.TopDown("prebuilt_select", PrebuiltSelectModuleMutator).Parallel() 73 ctx.BottomUp("prebuilt_replace", PrebuiltReplaceMutator).Parallel() 74 75 register(postDeps) 76 77 registeredMutators = ctx.mutators 78 }) 79 80 registerMutatorsToContext(ctx, registeredMutators) 81 } 82 83 func RegisterTestMutators(ctx *blueprint.Context) { 84 mutators := registerMutatorsContext{} 85 mutators.BottomUp("deps", depsMutator).Parallel() 86 registerMutatorsToContext(ctx, mutators.mutators) 87 } 88 89 type registerMutatorsContext struct { 90 mutators []*mutator 91 } 92 93 type RegisterMutatorsContext interface { 94 TopDown(name string, m AndroidTopDownMutator) MutatorHandle 95 BottomUp(name string, m AndroidBottomUpMutator) MutatorHandle 96 } 97 98 type RegisterMutatorFunc func(RegisterMutatorsContext) 99 100 var preArch, preDeps, postDeps []RegisterMutatorFunc 101 102 func PreArchMutators(f RegisterMutatorFunc) { 103 preArch = append(preArch, f) 104 } 105 106 func PreDepsMutators(f RegisterMutatorFunc) { 107 preDeps = append(preDeps, f) 108 } 109 110 func PostDepsMutators(f RegisterMutatorFunc) { 111 postDeps = append(postDeps, f) 112 } 113 114 type AndroidTopDownMutator func(TopDownMutatorContext) 115 116 type TopDownMutatorContext interface { 117 blueprint.TopDownMutatorContext 118 androidBaseContext 119 } 120 121 type androidTopDownMutatorContext struct { 122 blueprint.TopDownMutatorContext 123 androidBaseContextImpl 124 } 125 126 type AndroidBottomUpMutator func(BottomUpMutatorContext) 127 128 type BottomUpMutatorContext interface { 129 blueprint.BottomUpMutatorContext 130 androidBaseContext 131 } 132 133 type androidBottomUpMutatorContext struct { 134 blueprint.BottomUpMutatorContext 135 androidBaseContextImpl 136 } 137 138 func (x *registerMutatorsContext) BottomUp(name string, m AndroidBottomUpMutator) MutatorHandle { 139 f := func(ctx blueprint.BottomUpMutatorContext) { 140 if a, ok := ctx.Module().(Module); ok { 141 actx := &androidBottomUpMutatorContext{ 142 BottomUpMutatorContext: ctx, 143 androidBaseContextImpl: a.base().androidBaseContextFactory(ctx), 144 } 145 m(actx) 146 } 147 } 148 mutator := &mutator{name: name, bottomUpMutator: f} 149 x.mutators = append(x.mutators, mutator) 150 return mutator 151 } 152 153 func (x *registerMutatorsContext) TopDown(name string, m AndroidTopDownMutator) MutatorHandle { 154 f := func(ctx blueprint.TopDownMutatorContext) { 155 if a, ok := ctx.Module().(Module); ok { 156 actx := &androidTopDownMutatorContext{ 157 TopDownMutatorContext: ctx, 158 androidBaseContextImpl: a.base().androidBaseContextFactory(ctx), 159 } 160 m(actx) 161 } 162 } 163 mutator := &mutator{name: name, topDownMutator: f} 164 x.mutators = append(x.mutators, mutator) 165 return mutator 166 } 167 168 type MutatorHandle interface { 169 Parallel() MutatorHandle 170 } 171 172 func (mutator *mutator) Parallel() MutatorHandle { 173 mutator.parallel = true 174 return mutator 175 } 176 177 func depsMutator(ctx BottomUpMutatorContext) { 178 if m, ok := ctx.Module().(Module); ok { 179 m.DepsMutator(ctx) 180 } 181 } 182