github.com/westcoastroms/westcoastroms-build@v0.0.0-20190928114312-2350e5a73030/build/soong/android/mutator.go (about)

     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  	"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  
    30  func 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  
    44  func registerMutators(ctx *blueprint.Context, preArch, preDeps, postDeps []RegisterMutatorFunc) {
    45  	mctx := &registerMutatorsContext{}
    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  
    64  type registerMutatorsContext struct {
    65  	mutators []*mutator
    66  }
    67  
    68  type RegisterMutatorsContext interface {
    69  	TopDown(name string, m AndroidTopDownMutator) MutatorHandle
    70  	BottomUp(name string, m AndroidBottomUpMutator) MutatorHandle
    71  }
    72  
    73  type RegisterMutatorFunc func(RegisterMutatorsContext)
    74  
    75  var preArch = []RegisterMutatorFunc{
    76  	func(ctx RegisterMutatorsContext) {
    77  		ctx.TopDown("load_hooks", loadHookMutator).Parallel()
    78  	},
    79  	RegisterNamespaceMutator,
    80  	RegisterPrebuiltsPreArchMutators,
    81  	RegisterDefaultsPreArchMutators,
    82  }
    83  
    84  func registerArchMutator(ctx RegisterMutatorsContext) {
    85  	ctx.BottomUp("arch", archMutator).Parallel()
    86  	ctx.TopDown("arch_hooks", archHookMutator).Parallel()
    87  }
    88  
    89  var preDeps = []RegisterMutatorFunc{
    90  	registerArchMutator,
    91  }
    92  
    93  var postDeps = []RegisterMutatorFunc{
    94  	RegisterPrebuiltsPostDepsMutators,
    95  	registerNeverallowMutator,
    96  }
    97  
    98  func PreArchMutators(f RegisterMutatorFunc) {
    99  	preArch = append(preArch, f)
   100  }
   101  
   102  func PreDepsMutators(f RegisterMutatorFunc) {
   103  	preDeps = append(preDeps, f)
   104  }
   105  
   106  func PostDepsMutators(f RegisterMutatorFunc) {
   107  	postDeps = append(postDeps, f)
   108  }
   109  
   110  type AndroidTopDownMutator func(TopDownMutatorContext)
   111  
   112  type 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  
   137  type androidTopDownMutatorContext struct {
   138  	blueprint.TopDownMutatorContext
   139  	androidBaseContextImpl
   140  }
   141  
   142  type AndroidBottomUpMutator func(BottomUpMutatorContext)
   143  
   144  type 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  
   163  type androidBottomUpMutatorContext struct {
   164  	blueprint.BottomUpMutatorContext
   165  	androidBaseContextImpl
   166  }
   167  
   168  func (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  
   183  func (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  
   198  type MutatorHandle interface {
   199  	Parallel() MutatorHandle
   200  }
   201  
   202  func (mutator *mutator) Parallel() MutatorHandle {
   203  	mutator.parallel = true
   204  	return mutator
   205  }
   206  
   207  func depsMutator(ctx BottomUpMutatorContext) {
   208  	if m, ok := ctx.Module().(Module); ok {
   209  		m.DepsMutator(ctx)
   210  	}
   211  }
   212  
   213  func (a *androidTopDownMutatorContext) Config() Config {
   214  	return a.config
   215  }
   216  
   217  func (a *androidBottomUpMutatorContext) Config() Config {
   218  	return a.config
   219  }
   220  
   221  func (a *androidTopDownMutatorContext) Module() Module {
   222  	module, _ := a.TopDownMutatorContext.Module().(Module)
   223  	return module
   224  }
   225  
   226  func (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  
   234  func (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  
   244  func (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  
   260  func (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  
   268  func (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  
   284  func (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  
   296  func (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  
   310  func (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  }