blob: f489c02c135f75ff891b83f16d73e4727cd12be1 [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 (
18 "github.com/google/blueprint"
19 "github.com/google/blueprint/proptools"
20)
21
Colin Crossc99deeb2016-04-11 15:06:20 -070022type defaultsDependencyTag struct {
23 blueprint.BaseDependencyTag
24}
25
26var DefaultsDepTag defaultsDependencyTag
27
Colin Crosscfad1192015-11-02 16:43:11 -080028type defaultsProperties struct {
29 Defaults []string
30}
31
Colin Cross1f44a3a2017-07-07 14:33:33 -070032type DefaultableModuleBase struct {
Colin Crosscfad1192015-11-02 16:43:11 -080033 defaultsProperties defaultsProperties
34 defaultableProperties []interface{}
35}
36
Colin Cross1f44a3a2017-07-07 14:33:33 -070037func (d *DefaultableModuleBase) defaults() *defaultsProperties {
Colin Crosscfad1192015-11-02 16:43:11 -080038 return &d.defaultsProperties
39}
40
Colin Cross1f44a3a2017-07-07 14:33:33 -070041func (d *DefaultableModuleBase) setProperties(props []interface{}) {
Colin Crosscfad1192015-11-02 16:43:11 -080042 d.defaultableProperties = props
43}
44
Paul Duffin7df7fb02019-07-24 12:26:14 +010045// Interface that must be supported by any module to which defaults can be applied.
Colin Crosscfad1192015-11-02 16:43:11 -080046type Defaultable interface {
Paul Duffin7df7fb02019-07-24 12:26:14 +010047 // Get a pointer to the struct containing the Defaults property.
Colin Crosscfad1192015-11-02 16:43:11 -080048 defaults() *defaultsProperties
Paul Duffin7df7fb02019-07-24 12:26:14 +010049
50 // Set the property structures into which defaults will be added.
Colin Crosscfad1192015-11-02 16:43:11 -080051 setProperties([]interface{})
Paul Duffin7df7fb02019-07-24 12:26:14 +010052
53 // Apply defaults from the supplied Defaults to the property structures supplied to
54 // setProperties(...).
Colin Cross13177012016-08-09 12:00:45 -070055 applyDefaults(TopDownMutatorContext, []Defaults)
Colin Crosscfad1192015-11-02 16:43:11 -080056}
57
Colin Cross1f44a3a2017-07-07 14:33:33 -070058type DefaultableModule interface {
59 Module
60 Defaultable
Colin Crosscfad1192015-11-02 16:43:11 -080061}
62
Colin Cross1f44a3a2017-07-07 14:33:33 -070063var _ Defaultable = (*DefaultableModuleBase)(nil)
64
65func InitDefaultableModule(module DefaultableModule) {
Paul Duffin7df7fb02019-07-24 12:26:14 +010066 module.setProperties(module.(Module).GetProperties())
Colin Cross1f44a3a2017-07-07 14:33:33 -070067
68 module.AddProperties(module.defaults())
69}
70
Paul Duffin95d53b52019-07-24 13:45:05 +010071// The Defaults_visibility property.
72type DefaultsVisibilityProperties struct {
73
74 // Controls the visibility of the defaults module itself.
75 Defaults_visibility []string
76}
77
Colin Cross1f44a3a2017-07-07 14:33:33 -070078type DefaultsModuleBase struct {
79 DefaultableModuleBase
Paul Duffin63c6e182019-07-24 14:24:38 +010080
81 // Container for defaults of the common properties
82 commonProperties commonProperties
Paul Duffin95d53b52019-07-24 13:45:05 +010083
84 defaultsVisibilityProperties DefaultsVisibilityProperties
Colin Crosscfad1192015-11-02 16:43:11 -080085}
86
Martin Stjernholmebd757d2019-05-24 11:00:30 +010087// The common pattern for defaults modules is to register separate instances of
88// the xxxProperties structs in the AddProperties calls, rather than reusing the
89// ones inherited from Module.
90//
91// The effect is that e.g. myDefaultsModuleInstance.base().xxxProperties won't
92// contain the values that have been set for the defaults module. Rather, to
93// retrieve the values it is necessary to iterate over properties(). E.g. to get
94// the commonProperties instance that have the real values:
95//
96// d := myModule.(Defaults)
97// for _, props := range d.properties() {
98// if cp, ok := props.(*commonProperties); ok {
99// ... access property values in cp ...
100// }
101// }
102//
103// The rationale is that the properties on a defaults module apply to the
104// defaultable modules using it, not to the defaults module itself. E.g. setting
105// the "enabled" property false makes inheriting modules disabled by default,
106// rather than disabling the defaults module itself.
Colin Crosscfad1192015-11-02 16:43:11 -0800107type Defaults interface {
Colin Crosse7b07132016-07-27 10:15:06 -0700108 Defaultable
Paul Duffin7df7fb02019-07-24 12:26:14 +0100109
110 // Although this function is unused it is actually needed to ensure that only modules that embed
111 // DefaultsModuleBase will type-assert to the Defaults interface.
Colin Crosscfad1192015-11-02 16:43:11 -0800112 isDefaults() bool
Paul Duffin7df7fb02019-07-24 12:26:14 +0100113
114 // Get the structures containing the properties for which defaults can be provided.
Colin Crosscfad1192015-11-02 16:43:11 -0800115 properties() []interface{}
Paul Duffin63c6e182019-07-24 14:24:38 +0100116
117 // Return the defaults common properties.
118 common() *commonProperties
Paul Duffin95d53b52019-07-24 13:45:05 +0100119
120 // Return the defaults visibility properties.
121 defaultsVisibility() *DefaultsVisibilityProperties
Colin Crosscfad1192015-11-02 16:43:11 -0800122}
123
Colin Cross1f44a3a2017-07-07 14:33:33 -0700124func (d *DefaultsModuleBase) isDefaults() bool {
Colin Crosscfad1192015-11-02 16:43:11 -0800125 return true
126}
127
Paul Duffine62432f2019-07-24 12:51:21 +0100128type DefaultsModule interface {
129 Module
130 Defaults
131}
132
Colin Cross1f44a3a2017-07-07 14:33:33 -0700133func (d *DefaultsModuleBase) properties() []interface{} {
Colin Crosse7b07132016-07-27 10:15:06 -0700134 return d.defaultableProperties
Colin Crosscfad1192015-11-02 16:43:11 -0800135}
136
Paul Duffin63c6e182019-07-24 14:24:38 +0100137func (d *DefaultsModuleBase) common() *commonProperties {
138 return &d.commonProperties
139}
140
Paul Duffin95d53b52019-07-24 13:45:05 +0100141func (d *DefaultsModuleBase) defaultsVisibility() *DefaultsVisibilityProperties {
142 return &d.defaultsVisibilityProperties
143}
144
Colin Cross59037622019-06-10 13:12:56 -0700145func (d *DefaultsModuleBase) GenerateAndroidBuildActions(ctx ModuleContext) {
146}
147
Paul Duffine62432f2019-07-24 12:51:21 +0100148func InitDefaultsModule(module DefaultsModule) {
Paul Duffin63c6e182019-07-24 14:24:38 +0100149 commonProperties := module.common()
150
Colin Cross36242852017-06-23 15:06:31 -0700151 module.AddProperties(
Colin Crossfc754582016-05-17 16:34:16 -0700152 &hostAndDeviceProperties{},
Paul Duffin63c6e182019-07-24 14:24:38 +0100153 commonProperties,
Colin Crossfc754582016-05-17 16:34:16 -0700154 &variableProperties{})
155
Colin Cross36242852017-06-23 15:06:31 -0700156 InitArchModule(module)
Colin Cross1f44a3a2017-07-07 14:33:33 -0700157 InitDefaultableModule(module)
Colin Crossfc754582016-05-17 16:34:16 -0700158
Paul Duffin7df7fb02019-07-24 12:26:14 +0100159 // Add properties that will not have defaults applied to them.
Paul Duffin63c6e182019-07-24 14:24:38 +0100160 base := module.base()
Paul Duffin95d53b52019-07-24 13:45:05 +0100161 defaultsVisibility := module.defaultsVisibility()
162 module.AddProperties(&base.nameProperties, defaultsVisibility)
Colin Crossfc754582016-05-17 16:34:16 -0700163
Paul Duffin95d53b52019-07-24 13:45:05 +0100164 // The defaults_visibility property controls the visibility of a defaults module.
165 base.primaryVisibilityProperty =
166 newVisibilityProperty("defaults_visibility", &defaultsVisibility.Defaults_visibility)
Paul Duffin63c6e182019-07-24 14:24:38 +0100167
168 // Unlike non-defaults modules the visibility property is not stored in m.base().commonProperties.
169 // Instead it is stored in a separate instance of commonProperties created above so use that.
170 // The visibility property needs to be checked (but not parsed) by the visibility module during
171 // its checking phase and parsing phase.
172 base.visibilityPropertyInfo = []visibilityProperty{
Paul Duffin95d53b52019-07-24 13:45:05 +0100173 base.primaryVisibilityProperty,
Paul Duffin63c6e182019-07-24 14:24:38 +0100174 newVisibilityProperty("visibility", &commonProperties.Visibility),
175 }
176
177 base.module = module
Colin Crosscfad1192015-11-02 16:43:11 -0800178}
179
Colin Cross1f44a3a2017-07-07 14:33:33 -0700180var _ Defaults = (*DefaultsModuleBase)(nil)
Colin Crosscfad1192015-11-02 16:43:11 -0800181
Colin Cross1f44a3a2017-07-07 14:33:33 -0700182func (defaultable *DefaultableModuleBase) applyDefaults(ctx TopDownMutatorContext,
Colin Cross13177012016-08-09 12:00:45 -0700183 defaultsList []Defaults) {
Colin Crosscfad1192015-11-02 16:43:11 -0800184
Colin Cross13177012016-08-09 12:00:45 -0700185 for _, defaults := range defaultsList {
186 for _, prop := range defaultable.defaultableProperties {
187 for _, def := range defaults.properties() {
188 if proptools.TypeEqual(prop, def) {
189 err := proptools.PrependProperties(prop, def, nil)
190 if err != nil {
191 if propertyErr, ok := err.(*proptools.ExtendPropertyError); ok {
192 ctx.PropertyErrorf(propertyErr.Property, "%s", propertyErr.Err.Error())
193 } else {
194 panic(err)
195 }
Colin Crosscfad1192015-11-02 16:43:11 -0800196 }
197 }
198 }
199 }
200 }
201}
202
Colin Cross89536d42017-07-07 14:35:50 -0700203func RegisterDefaultsPreArchMutators(ctx RegisterMutatorsContext) {
Colin Crosscec81712017-07-13 14:43:27 -0700204 ctx.BottomUp("defaults_deps", defaultsDepsMutator).Parallel()
205 ctx.TopDown("defaults", defaultsMutator).Parallel()
206}
207
Colin Cross635c3b02016-05-18 15:37:25 -0700208func defaultsDepsMutator(ctx BottomUpMutatorContext) {
Colin Crosscfad1192015-11-02 16:43:11 -0800209 if defaultable, ok := ctx.Module().(Defaultable); ok {
Colin Crossc99deeb2016-04-11 15:06:20 -0700210 ctx.AddDependency(ctx.Module(), DefaultsDepTag, defaultable.defaults().Defaults...)
Colin Crosscfad1192015-11-02 16:43:11 -0800211 }
212}
213
Colin Cross13177012016-08-09 12:00:45 -0700214func defaultsMutator(ctx TopDownMutatorContext) {
215 if defaultable, ok := ctx.Module().(Defaultable); ok && len(defaultable.defaults().Defaults) > 0 {
216 var defaultsList []Defaults
Colin Crossa1ce2a02018-06-20 15:19:39 -0700217 seen := make(map[Defaults]bool)
218
Colin Crossd11fcda2017-10-23 17:59:01 -0700219 ctx.WalkDeps(func(module, parent Module) bool {
Colin Cross13177012016-08-09 12:00:45 -0700220 if ctx.OtherModuleDependencyTag(module) == DefaultsDepTag {
221 if defaults, ok := module.(Defaults); ok {
Colin Crossa1ce2a02018-06-20 15:19:39 -0700222 if !seen[defaults] {
223 seen[defaults] = true
224 defaultsList = append(defaultsList, defaults)
225 return len(defaults.defaults().Defaults) > 0
226 }
Colin Cross13177012016-08-09 12:00:45 -0700227 } else {
228 ctx.PropertyErrorf("defaults", "module %s is not an defaults module",
229 ctx.OtherModuleName(module))
Colin Crosscfad1192015-11-02 16:43:11 -0800230 }
Colin Cross13177012016-08-09 12:00:45 -0700231 }
232 return false
233 })
234 defaultable.applyDefaults(ctx, defaultsList)
Colin Crosscfad1192015-11-02 16:43:11 -0800235 }
236}