47cf66b8d1
For libc to use Change-Id: I5048509e27ea4e4dc7773e7bd33e7f7b4deca608
168 lines
4.5 KiB
Go
168 lines
4.5 KiB
Go
// Copyright 2015 Google Inc. All rights reserved.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package common
|
|
|
|
import (
|
|
"fmt"
|
|
"reflect"
|
|
"strings"
|
|
|
|
"android/soong"
|
|
|
|
"github.com/google/blueprint"
|
|
"github.com/google/blueprint/proptools"
|
|
)
|
|
|
|
func init() {
|
|
soong.RegisterEarlyMutator("variable", VariableMutator)
|
|
}
|
|
|
|
type variableProperties struct {
|
|
Product_variables struct {
|
|
Device_uses_dlmalloc struct {
|
|
Cflags []string
|
|
Srcs []string
|
|
}
|
|
Device_uses_jemalloc struct {
|
|
Cflags []string
|
|
Srcs []string
|
|
Whole_static_libs []string
|
|
Include_dirs []string
|
|
}
|
|
Dlmalloc_alignment struct {
|
|
Cflags []string
|
|
}
|
|
Platform_sdk_version struct {
|
|
Asflags []string
|
|
}
|
|
}
|
|
}
|
|
|
|
var zeroProductVariables variableProperties
|
|
|
|
type productVariables struct {
|
|
Device_uses_jemalloc *bool `json:",omitempty"`
|
|
Device_uses_dlmalloc *bool `json:",omitempty"`
|
|
Dlmalloc_alignment *int `json:",omitempty"`
|
|
Platform_sdk_version *int
|
|
}
|
|
|
|
func boolPtr(v bool) *bool {
|
|
return &v
|
|
}
|
|
|
|
func intPtr(v int) *int {
|
|
return &v
|
|
}
|
|
|
|
func (productVariables) DefaultConfig() jsonConfigurable {
|
|
v := productVariables{
|
|
Device_uses_jemalloc: boolPtr(true),
|
|
Platform_sdk_version: intPtr(22),
|
|
}
|
|
return v
|
|
}
|
|
|
|
func VariableMutator(mctx blueprint.EarlyMutatorContext) {
|
|
var module AndroidModule
|
|
var ok bool
|
|
if module, ok = mctx.Module().(AndroidModule); !ok {
|
|
return
|
|
}
|
|
|
|
// TODO: depend on config variable, create variants, propagate variants up tree
|
|
a := module.base()
|
|
variableValues := reflect.ValueOf(a.variableProperties.Product_variables)
|
|
zeroValues := reflect.ValueOf(zeroProductVariables.Product_variables)
|
|
|
|
for i := 0; i < variableValues.NumField(); i++ {
|
|
variableValue := variableValues.Field(i)
|
|
zeroValue := zeroValues.Field(i)
|
|
name := variableValues.Type().Field(i).Name
|
|
property := "product_variables." + proptools.PropertyNameForField(name)
|
|
|
|
// Check that the variable was set for the product
|
|
val := reflect.ValueOf(mctx.Config().(Config).ProductVariables).FieldByName(name)
|
|
if !val.IsValid() || val.Kind() != reflect.Ptr || val.IsNil() {
|
|
continue
|
|
}
|
|
|
|
val = val.Elem()
|
|
|
|
// For bools, check that the value is true
|
|
if val.Kind() == reflect.Bool && val.Bool() == false {
|
|
continue
|
|
}
|
|
|
|
// Check if any properties were set for the module
|
|
if reflect.DeepEqual(variableValue.Interface(), zeroValue.Interface()) {
|
|
continue
|
|
}
|
|
|
|
a.setVariableProperties(mctx, property, variableValue, val.Interface())
|
|
}
|
|
}
|
|
|
|
func (a *AndroidModuleBase) setVariableProperties(ctx blueprint.EarlyMutatorContext,
|
|
prefix string, productVariablePropertyValue reflect.Value, variableValue interface{}) {
|
|
|
|
generalPropertyValues := make([]reflect.Value, len(a.generalProperties))
|
|
for i := range a.generalProperties {
|
|
generalPropertyValues[i] = reflect.ValueOf(a.generalProperties[i]).Elem()
|
|
}
|
|
|
|
if variableValue != nil {
|
|
printfIntoProperties(productVariablePropertyValue, variableValue)
|
|
}
|
|
|
|
extendProperties(ctx, "", prefix, generalPropertyValues, productVariablePropertyValue, nil)
|
|
}
|
|
|
|
func printfIntoProperties(productVariablePropertyValue reflect.Value, variableValue interface{}) {
|
|
for i := 0; i < productVariablePropertyValue.NumField(); i++ {
|
|
propertyValue := productVariablePropertyValue.Field(i)
|
|
switch propertyValue.Kind() {
|
|
case reflect.String:
|
|
printfIntoProperty(propertyValue, variableValue)
|
|
case reflect.Slice:
|
|
for j := 0; j < propertyValue.Len(); j++ {
|
|
printfIntoProperty(propertyValue.Index(j), variableValue)
|
|
}
|
|
case reflect.Struct:
|
|
printfIntoProperties(propertyValue, variableValue)
|
|
default:
|
|
panic(fmt.Errorf("unsupported field kind %q", propertyValue.Kind()))
|
|
}
|
|
}
|
|
}
|
|
|
|
func printfIntoProperty(propertyValue reflect.Value, variableValue interface{}) {
|
|
s := propertyValue.String()
|
|
// For now, we only support int formats
|
|
var i int
|
|
if strings.Contains(s, "%d") {
|
|
switch v := variableValue.(type) {
|
|
case int:
|
|
i = v
|
|
case bool:
|
|
if v {
|
|
i = 1
|
|
}
|
|
default:
|
|
panic(fmt.Errorf("unsupported type %T", variableValue))
|
|
}
|
|
propertyValue.Set(reflect.ValueOf(fmt.Sprintf(s, i)))
|
|
}
|
|
}
|