blob: b1116eadad927779c7cb0da7ac6b64c72239504d [file] [log] [blame]
Colin Cross7f64b6d2015-07-09 13:57:48 -07001// 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 common
16
17import (
18 "fmt"
19 "reflect"
20 "strings"
21
22 "android/soong"
23
24 "github.com/google/blueprint"
25 "github.com/google/blueprint/proptools"
26)
27
28func init() {
29 soong.RegisterEarlyMutator("variable", VariableMutator)
30}
31
32type variableProperties struct {
33 Product_variables struct {
34 Device_uses_logd struct {
35 Cflags []string
36 Srcs []string
37 }
38 Device_uses_dlmalloc struct {
39 Cflags []string
40 Srcs []string
41 }
42 Device_uses_jemalloc struct {
43 Cflags []string
44 Srcs []string
45 Whole_static_libs []string
46 Include_dirs []string
47 }
48 Dlmalloc_alignment struct {
49 Cflags []string
50 }
51 }
52}
53
54var zeroProductVariables variableProperties
55
Colin Cross485e5722015-08-27 13:28:01 -070056type productVariables struct {
57 Device_uses_logd bool
58 Device_uses_jemalloc bool
59 Device_uses_dlmalloc bool
60 Dlmalloc_alignment int
61}
62
63func (productVariables) DefaultConfig() jsonConfigurable {
64 v := productVariables{
65 Device_uses_logd: true,
66 Device_uses_jemalloc: true,
67 }
68 return v
Colin Cross7f64b6d2015-07-09 13:57:48 -070069}
70
71func VariableMutator(mctx blueprint.EarlyMutatorContext) {
72 var module AndroidModule
73 var ok bool
74 if module, ok = mctx.Module().(AndroidModule); !ok {
75 return
76 }
77
78 // TODO: depend on config variable, create variants, propagate variants up tree
79 a := module.base()
80 variableValues := reflect.ValueOf(a.variableProperties.Product_variables)
81 zeroValues := reflect.ValueOf(zeroProductVariables.Product_variables)
82
83 for i := 0; i < variableValues.NumField(); i++ {
84 variableValue := variableValues.Field(i)
85 zeroValue := zeroValues.Field(i)
86 if reflect.DeepEqual(variableValue, zeroValue) {
87 continue
88 }
89
Colin Cross485e5722015-08-27 13:28:01 -070090 name := variableValues.Type().Field(i).Name
91 property := "product_variables." + proptools.PropertyNameForField(name)
Colin Cross7f64b6d2015-07-09 13:57:48 -070092
Colin Cross485e5722015-08-27 13:28:01 -070093 val := reflect.ValueOf(mctx.Config().(Config).ProductVariables).FieldByName(name)
94
95 if mctx.ContainsProperty(property) && val.IsValid() {
96 a.setVariableProperties(mctx, property, variableValue, val.Interface())
Colin Cross7f64b6d2015-07-09 13:57:48 -070097 }
98 }
99}
100
101func (a *AndroidModuleBase) setVariableProperties(ctx blueprint.EarlyMutatorContext,
102 prefix string, productVariablePropertyValue reflect.Value, variableValue interface{}) {
103
104 generalPropertyValues := make([]reflect.Value, len(a.generalProperties))
105 for i := range a.generalProperties {
106 generalPropertyValues[i] = reflect.ValueOf(a.generalProperties[i]).Elem()
107 }
108
109 if variableValue != nil {
110 printfIntoProperties(productVariablePropertyValue, variableValue)
111 }
112
113 extendProperties(ctx, "", prefix, generalPropertyValues, productVariablePropertyValue, nil)
114}
115
116func printfIntoProperties(productVariablePropertyValue reflect.Value, variableValue interface{}) {
117 for i := 0; i < productVariablePropertyValue.NumField(); i++ {
118 propertyValue := productVariablePropertyValue.Field(i)
119 switch propertyValue.Kind() {
120 case reflect.String:
121 printfIntoProperty(propertyValue, variableValue)
122 case reflect.Slice:
123 for j := 0; j < propertyValue.Len(); j++ {
124 printfIntoProperty(propertyValue.Index(j), variableValue)
125 }
126 case reflect.Struct:
127 printfIntoProperties(propertyValue, variableValue)
128 default:
129 panic(fmt.Errorf("unsupported field kind %q", propertyValue.Kind()))
130 }
131 }
132}
133
134func printfIntoProperty(propertyValue reflect.Value, variableValue interface{}) {
135 s := propertyValue.String()
136 // For now, we only support int formats
137 var i int
138 if strings.Contains(s, "%d") {
139 switch v := variableValue.(type) {
140 case int:
141 i = v
142 case bool:
143 if v {
144 i = 1
145 }
146 default:
147 panic(fmt.Errorf("unsupported type %T", variableValue))
148 }
149 propertyValue.Set(reflect.ValueOf(fmt.Sprintf(s, i)))
150 }
151}