blob: 6a908ea839eaf6b6e9b18d422ef778f4967ebafb [file] [log] [blame]
Colin Crosscfad1192015-11-02 16:43:11 -08001// 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
Colin Cross635c3b02016-05-18 15:37:25 -070015package android
Colin Crosscfad1192015-11-02 16:43:11 -080016
17import (
Colin Crosseabaedd2020-02-06 17:01:55 -080018 "reflect"
19
Colin Crosscfad1192015-11-02 16:43:11 -080020 "github.com/google/blueprint"
21 "github.com/google/blueprint/proptools"
22)
23
Colin Crossc99deeb2016-04-11 15:06:20 -070024type defaultsDependencyTag struct {
25 blueprint.BaseDependencyTag
26}
27
28var DefaultsDepTag defaultsDependencyTag
29
Colin Crosscfad1192015-11-02 16:43:11 -080030type defaultsProperties struct {
31 Defaults []string
32}
33
Colin Cross1f44a3a2017-07-07 14:33:33 -070034type DefaultableModuleBase struct {
Colin Crosseabaedd2020-02-06 17:01:55 -080035 defaultsProperties defaultsProperties
36 defaultableProperties []interface{}
37 defaultableVariableProperties interface{}
Colin Crosscfad1192015-11-02 16:43:11 -080038}
39
Colin Cross1f44a3a2017-07-07 14:33:33 -070040func (d *DefaultableModuleBase) defaults() *defaultsProperties {
Colin Crosscfad1192015-11-02 16:43:11 -080041 return &d.defaultsProperties
42}
43
Colin Crosseabaedd2020-02-06 17:01:55 -080044func (d *DefaultableModuleBase) setProperties(props []interface{}, variableProperties interface{}) {
Colin Crosscfad1192015-11-02 16:43:11 -080045 d.defaultableProperties = props
Colin Crosseabaedd2020-02-06 17:01:55 -080046 d.defaultableVariableProperties = variableProperties
Colin Crosscfad1192015-11-02 16:43:11 -080047}
48
Paul Duffin7df7fb02019-07-24 12:26:14 +010049// Interface that must be supported by any module to which defaults can be applied.
Colin Crosscfad1192015-11-02 16:43:11 -080050type Defaultable interface {
Paul Duffin7df7fb02019-07-24 12:26:14 +010051 // Get a pointer to the struct containing the Defaults property.
Colin Crosscfad1192015-11-02 16:43:11 -080052 defaults() *defaultsProperties
Paul Duffin7df7fb02019-07-24 12:26:14 +010053
54 // Set the property structures into which defaults will be added.
Colin Crosseabaedd2020-02-06 17:01:55 -080055 setProperties(props []interface{}, variableProperties interface{})
Paul Duffin7df7fb02019-07-24 12:26:14 +010056
57 // Apply defaults from the supplied Defaults to the property structures supplied to
58 // setProperties(...).
Colin Cross13177012016-08-09 12:00:45 -070059 applyDefaults(TopDownMutatorContext, []Defaults)
Colin Crosscfad1192015-11-02 16:43:11 -080060}
61
Colin Cross1f44a3a2017-07-07 14:33:33 -070062type DefaultableModule interface {
63 Module
64 Defaultable
Colin Crosscfad1192015-11-02 16:43:11 -080065}
66
Colin Cross1f44a3a2017-07-07 14:33:33 -070067var _ Defaultable = (*DefaultableModuleBase)(nil)
68
69func InitDefaultableModule(module DefaultableModule) {
Colin Crosseabaedd2020-02-06 17:01:55 -080070 if module.(Module).base().module == nil {
71 panic("InitAndroidModule must be called before InitDefaultableModule")
72 }
73 module.setProperties(module.(Module).GetProperties(), module.(Module).base().variableProperties)
Colin Cross1f44a3a2017-07-07 14:33:33 -070074
75 module.AddProperties(module.defaults())
76}
77
Paul Duffin95d53b52019-07-24 13:45:05 +010078// The Defaults_visibility property.
79type DefaultsVisibilityProperties struct {
80
81 // Controls the visibility of the defaults module itself.
82 Defaults_visibility []string
83}
84
Colin Cross1f44a3a2017-07-07 14:33:33 -070085type DefaultsModuleBase struct {
86 DefaultableModuleBase
Paul Duffin63c6e182019-07-24 14:24:38 +010087
88 // Container for defaults of the common properties
89 commonProperties commonProperties
Paul Duffin95d53b52019-07-24 13:45:05 +010090
91 defaultsVisibilityProperties DefaultsVisibilityProperties
Colin Crosscfad1192015-11-02 16:43:11 -080092}
93
Martin Stjernholmebd757d2019-05-24 11:00:30 +010094// The common pattern for defaults modules is to register separate instances of
95// the xxxProperties structs in the AddProperties calls, rather than reusing the
96// ones inherited from Module.
97//
98// The effect is that e.g. myDefaultsModuleInstance.base().xxxProperties won't
99// contain the values that have been set for the defaults module. Rather, to
100// retrieve the values it is necessary to iterate over properties(). E.g. to get
101// the commonProperties instance that have the real values:
102//
103// d := myModule.(Defaults)
104// for _, props := range d.properties() {
105// if cp, ok := props.(*commonProperties); ok {
106// ... access property values in cp ...
107// }
108// }
109//
110// The rationale is that the properties on a defaults module apply to the
111// defaultable modules using it, not to the defaults module itself. E.g. setting
112// the "enabled" property false makes inheriting modules disabled by default,
113// rather than disabling the defaults module itself.
Colin Crosscfad1192015-11-02 16:43:11 -0800114type Defaults interface {
Colin Crosse7b07132016-07-27 10:15:06 -0700115 Defaultable
Paul Duffin7df7fb02019-07-24 12:26:14 +0100116
117 // Although this function is unused it is actually needed to ensure that only modules that embed
118 // DefaultsModuleBase will type-assert to the Defaults interface.
Colin Crosscfad1192015-11-02 16:43:11 -0800119 isDefaults() bool
Paul Duffin7df7fb02019-07-24 12:26:14 +0100120
121 // Get the structures containing the properties for which defaults can be provided.
Colin Crosscfad1192015-11-02 16:43:11 -0800122 properties() []interface{}
Paul Duffin63c6e182019-07-24 14:24:38 +0100123
Colin Crosseabaedd2020-02-06 17:01:55 -0800124 productVariableProperties() interface{}
125
Paul Duffin63c6e182019-07-24 14:24:38 +0100126 // Return the defaults common properties.
127 common() *commonProperties
Paul Duffin95d53b52019-07-24 13:45:05 +0100128
129 // Return the defaults visibility properties.
130 defaultsVisibility() *DefaultsVisibilityProperties
Colin Crosscfad1192015-11-02 16:43:11 -0800131}
132
Colin Cross1f44a3a2017-07-07 14:33:33 -0700133func (d *DefaultsModuleBase) isDefaults() bool {
Colin Crosscfad1192015-11-02 16:43:11 -0800134 return true
135}
136
Paul Duffine62432f2019-07-24 12:51:21 +0100137type DefaultsModule interface {
138 Module
139 Defaults
140}
141
Colin Cross1f44a3a2017-07-07 14:33:33 -0700142func (d *DefaultsModuleBase) properties() []interface{} {
Colin Crosse7b07132016-07-27 10:15:06 -0700143 return d.defaultableProperties
Colin Crosscfad1192015-11-02 16:43:11 -0800144}
145
Colin Crosseabaedd2020-02-06 17:01:55 -0800146func (d *DefaultsModuleBase) productVariableProperties() interface{} {
147 return d.defaultableVariableProperties
148}
149
Paul Duffin63c6e182019-07-24 14:24:38 +0100150func (d *DefaultsModuleBase) common() *commonProperties {
151 return &d.commonProperties
152}
153
Paul Duffin95d53b52019-07-24 13:45:05 +0100154func (d *DefaultsModuleBase) defaultsVisibility() *DefaultsVisibilityProperties {
155 return &d.defaultsVisibilityProperties
156}
157
Colin Cross59037622019-06-10 13:12:56 -0700158func (d *DefaultsModuleBase) GenerateAndroidBuildActions(ctx ModuleContext) {
159}
160
Paul Duffine62432f2019-07-24 12:51:21 +0100161func InitDefaultsModule(module DefaultsModule) {
Paul Duffin63c6e182019-07-24 14:24:38 +0100162 commonProperties := module.common()
163
Colin Cross36242852017-06-23 15:06:31 -0700164 module.AddProperties(
Colin Crossfc754582016-05-17 16:34:16 -0700165 &hostAndDeviceProperties{},
Paul Duffin63c6e182019-07-24 14:24:38 +0100166 commonProperties,
Jiyong Park3814f4d2019-12-02 13:08:53 +0900167 &ApexProperties{})
Colin Crossfc754582016-05-17 16:34:16 -0700168
Colin Crosseabaedd2020-02-06 17:01:55 -0800169 initAndroidModuleBase(module)
170 initProductVariableModule(module)
Colin Cross36242852017-06-23 15:06:31 -0700171 InitArchModule(module)
Colin Cross1f44a3a2017-07-07 14:33:33 -0700172 InitDefaultableModule(module)
Colin Crossfc754582016-05-17 16:34:16 -0700173
Paul Duffin7df7fb02019-07-24 12:26:14 +0100174 // Add properties that will not have defaults applied to them.
Paul Duffin63c6e182019-07-24 14:24:38 +0100175 base := module.base()
Paul Duffin95d53b52019-07-24 13:45:05 +0100176 defaultsVisibility := module.defaultsVisibility()
177 module.AddProperties(&base.nameProperties, defaultsVisibility)
Colin Crossfc754582016-05-17 16:34:16 -0700178
Paul Duffin63c6e182019-07-24 14:24:38 +0100179 // Unlike non-defaults modules the visibility property is not stored in m.base().commonProperties.
Paul Duffin5ec73ec2020-05-01 17:52:01 +0100180 // Instead it is stored in a separate instance of commonProperties created above so clear the
181 // existing list of properties.
182 clearVisibilityProperties(module)
183
184 // The defaults_visibility property controls the visibility of a defaults module so it must be
185 // set as the primary property, which also adds it to the list.
186 setPrimaryVisibilityProperty(module, "defaults_visibility", &defaultsVisibility.Defaults_visibility)
187
Paul Duffin63c6e182019-07-24 14:24:38 +0100188 // The visibility property needs to be checked (but not parsed) by the visibility module during
Paul Duffin5ec73ec2020-05-01 17:52:01 +0100189 // its checking phase and parsing phase so add it to the list as a normal property.
190 AddVisibilityProperty(module, "visibility", &commonProperties.Visibility)
Paul Duffin63c6e182019-07-24 14:24:38 +0100191
192 base.module = module
Colin Crosscfad1192015-11-02 16:43:11 -0800193}
194
Colin Cross1f44a3a2017-07-07 14:33:33 -0700195var _ Defaults = (*DefaultsModuleBase)(nil)
Colin Crosscfad1192015-11-02 16:43:11 -0800196
Colin Cross1f44a3a2017-07-07 14:33:33 -0700197func (defaultable *DefaultableModuleBase) applyDefaults(ctx TopDownMutatorContext,
Colin Cross13177012016-08-09 12:00:45 -0700198 defaultsList []Defaults) {
Colin Crosscfad1192015-11-02 16:43:11 -0800199
Colin Cross13177012016-08-09 12:00:45 -0700200 for _, defaults := range defaultsList {
201 for _, prop := range defaultable.defaultableProperties {
Colin Crosseabaedd2020-02-06 17:01:55 -0800202 if prop == defaultable.defaultableVariableProperties {
203 defaultable.applyDefaultVariableProperties(ctx, defaults, prop)
204 } else {
205 defaultable.applyDefaultProperties(ctx, defaults, prop)
206 }
207 }
208 }
209}
210
211// Product variable properties need special handling, the type of the filtered product variable
212// property struct may not be identical between the defaults module and the defaultable module.
213// Use PrependMatchingProperties to apply whichever properties match.
214func (defaultable *DefaultableModuleBase) applyDefaultVariableProperties(ctx TopDownMutatorContext,
215 defaults Defaults, defaultableProp interface{}) {
216 if defaultableProp == nil {
217 return
218 }
219
220 defaultsProp := defaults.productVariableProperties()
221 if defaultsProp == nil {
222 return
223 }
224
225 dst := []interface{}{
226 defaultableProp,
227 // Put an empty copy of the src properties into dst so that properties in src that are not in dst
228 // don't cause a "failed to find property to extend" error.
229 proptools.CloneEmptyProperties(reflect.ValueOf(defaultsProp)).Interface(),
230 }
231
232 err := proptools.PrependMatchingProperties(dst, defaultsProp, nil)
233 if err != nil {
234 if propertyErr, ok := err.(*proptools.ExtendPropertyError); ok {
235 ctx.PropertyErrorf(propertyErr.Property, "%s", propertyErr.Err.Error())
236 } else {
237 panic(err)
238 }
239 }
240}
241
242func (defaultable *DefaultableModuleBase) applyDefaultProperties(ctx TopDownMutatorContext,
243 defaults Defaults, defaultableProp interface{}) {
244
245 for _, def := range defaults.properties() {
246 if proptools.TypeEqual(defaultableProp, def) {
247 err := proptools.PrependProperties(defaultableProp, def, nil)
248 if err != nil {
249 if propertyErr, ok := err.(*proptools.ExtendPropertyError); ok {
250 ctx.PropertyErrorf(propertyErr.Property, "%s", propertyErr.Err.Error())
251 } else {
252 panic(err)
Colin Crosscfad1192015-11-02 16:43:11 -0800253 }
254 }
255 }
256 }
257}
258
Colin Cross89536d42017-07-07 14:35:50 -0700259func RegisterDefaultsPreArchMutators(ctx RegisterMutatorsContext) {
Colin Crosscec81712017-07-13 14:43:27 -0700260 ctx.BottomUp("defaults_deps", defaultsDepsMutator).Parallel()
261 ctx.TopDown("defaults", defaultsMutator).Parallel()
262}
263
Colin Cross635c3b02016-05-18 15:37:25 -0700264func defaultsDepsMutator(ctx BottomUpMutatorContext) {
Colin Crosscfad1192015-11-02 16:43:11 -0800265 if defaultable, ok := ctx.Module().(Defaultable); ok {
Colin Crossc99deeb2016-04-11 15:06:20 -0700266 ctx.AddDependency(ctx.Module(), DefaultsDepTag, defaultable.defaults().Defaults...)
Colin Crosscfad1192015-11-02 16:43:11 -0800267 }
268}
269
Colin Cross13177012016-08-09 12:00:45 -0700270func defaultsMutator(ctx TopDownMutatorContext) {
271 if defaultable, ok := ctx.Module().(Defaultable); ok && len(defaultable.defaults().Defaults) > 0 {
272 var defaultsList []Defaults
Colin Crossa1ce2a02018-06-20 15:19:39 -0700273 seen := make(map[Defaults]bool)
274
Colin Crossd11fcda2017-10-23 17:59:01 -0700275 ctx.WalkDeps(func(module, parent Module) bool {
Colin Cross13177012016-08-09 12:00:45 -0700276 if ctx.OtherModuleDependencyTag(module) == DefaultsDepTag {
277 if defaults, ok := module.(Defaults); ok {
Colin Crossa1ce2a02018-06-20 15:19:39 -0700278 if !seen[defaults] {
279 seen[defaults] = true
280 defaultsList = append(defaultsList, defaults)
281 return len(defaults.defaults().Defaults) > 0
282 }
Colin Cross13177012016-08-09 12:00:45 -0700283 } else {
284 ctx.PropertyErrorf("defaults", "module %s is not an defaults module",
285 ctx.OtherModuleName(module))
Colin Crosscfad1192015-11-02 16:43:11 -0800286 }
Colin Cross13177012016-08-09 12:00:45 -0700287 }
288 return false
289 })
290 defaultable.applyDefaults(ctx, defaultsList)
Colin Crosscfad1192015-11-02 16:43:11 -0800291 }
292}