blob: 19ec6251a461f076dd218019854dba1c41693bf3 [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
56// TODO: replace hardcoded test values with per-product values
57var productVariables = map[string]interface{}{
58 "device_uses_logd": true,
59 "device_uses_jemalloc": true,
60}
61
62func VariableMutator(mctx blueprint.EarlyMutatorContext) {
63 var module AndroidModule
64 var ok bool
65 if module, ok = mctx.Module().(AndroidModule); !ok {
66 return
67 }
68
69 // TODO: depend on config variable, create variants, propagate variants up tree
70 a := module.base()
71 variableValues := reflect.ValueOf(a.variableProperties.Product_variables)
72 zeroValues := reflect.ValueOf(zeroProductVariables.Product_variables)
73
74 for i := 0; i < variableValues.NumField(); i++ {
75 variableValue := variableValues.Field(i)
76 zeroValue := zeroValues.Field(i)
77 if reflect.DeepEqual(variableValue, zeroValue) {
78 continue
79 }
80
81 name := proptools.PropertyNameForField(variableValues.Type().Field(i).Name)
82 property := "product_variables." + name
83 val := productVariables[name]
84
85 if mctx.ContainsProperty(property) && val != nil {
86 a.setVariableProperties(mctx, property, variableValue, val)
87 }
88 }
89}
90
91func (a *AndroidModuleBase) setVariableProperties(ctx blueprint.EarlyMutatorContext,
92 prefix string, productVariablePropertyValue reflect.Value, variableValue interface{}) {
93
94 generalPropertyValues := make([]reflect.Value, len(a.generalProperties))
95 for i := range a.generalProperties {
96 generalPropertyValues[i] = reflect.ValueOf(a.generalProperties[i]).Elem()
97 }
98
99 if variableValue != nil {
100 printfIntoProperties(productVariablePropertyValue, variableValue)
101 }
102
103 extendProperties(ctx, "", prefix, generalPropertyValues, productVariablePropertyValue, nil)
104}
105
106func printfIntoProperties(productVariablePropertyValue reflect.Value, variableValue interface{}) {
107 for i := 0; i < productVariablePropertyValue.NumField(); i++ {
108 propertyValue := productVariablePropertyValue.Field(i)
109 switch propertyValue.Kind() {
110 case reflect.String:
111 printfIntoProperty(propertyValue, variableValue)
112 case reflect.Slice:
113 for j := 0; j < propertyValue.Len(); j++ {
114 printfIntoProperty(propertyValue.Index(j), variableValue)
115 }
116 case reflect.Struct:
117 printfIntoProperties(propertyValue, variableValue)
118 default:
119 panic(fmt.Errorf("unsupported field kind %q", propertyValue.Kind()))
120 }
121 }
122}
123
124func printfIntoProperty(propertyValue reflect.Value, variableValue interface{}) {
125 s := propertyValue.String()
126 // For now, we only support int formats
127 var i int
128 if strings.Contains(s, "%d") {
129 switch v := variableValue.(type) {
130 case int:
131 i = v
132 case bool:
133 if v {
134 i = 1
135 }
136 default:
137 panic(fmt.Errorf("unsupported type %T", variableValue))
138 }
139 propertyValue.Set(reflect.ValueOf(fmt.Sprintf(s, i)))
140 }
141}