From 485e572aeb8690abcb2907149f01f25fc85394db Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 27 Aug 2015 13:28:01 -0700 Subject: [PATCH] Read product variables from soong.variables Refactor the soong.config loading code to support reading in product variables from soong.variables. Change-Id: I389e6bb5c501b53167267d5f5d0d25557811cf72 --- androidbp/cmd/soong.go | 2 +- cmd/soong_build/main.go | 2 +- common/config.go | 57 +++++++++++++++++++++++------------------ common/variable.go | 28 +++++++++++++------- 4 files changed, 53 insertions(+), 36 deletions(-) diff --git a/androidbp/cmd/soong.go b/androidbp/cmd/soong.go index e9d421acd..65a4239f8 100644 --- a/androidbp/cmd/soong.go +++ b/androidbp/cmd/soong.go @@ -173,7 +173,7 @@ var targetToHostModuleRule = map[string]string{ "BUILD_JAVA_LIBRARY": "BUILD_HOST_JAVA_LIBRARY", } -var productVariableConditionals = map[string]struct{conditional, value string}{ +var productVariableConditionals = map[string]struct{ conditional, value string }{ "device_uses_jemalloc": {"ifneq ($(MALLOC_IMPL),dlmalloc)", ""}, "device_uses_dlmalloc": {"ifeq ($(MALLOC_IMPL),dlmalloc)", ""}, "device_uses_logd": {"ifneq ($(TARGET_USES_LOGD),false)", ""}, diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go index 94fb6e74a..33fdd6980 100644 --- a/cmd/soong_build/main.go +++ b/cmd/soong_build/main.go @@ -49,5 +49,5 @@ func main() { // Temporary hack //ctx.SetIgnoreUnknownModuleTypes(true) - bootstrap.Main(ctx, configuration, common.ConfigFileName) + bootstrap.Main(ctx, configuration, common.ConfigFileName, common.ProductVariablesFileName) } diff --git a/common/config.go b/common/config.go index 10ed4f083..348d0dbb7 100644 --- a/common/config.go +++ b/common/config.go @@ -25,13 +25,14 @@ import ( // The configuration file name const ConfigFileName = "soong.config" +const ProductVariablesFileName = "soong.variables" // A FileConfigurableOptions contains options which can be configured by the // config file. These will be included in the config struct. type FileConfigurableOptions struct { } -func NewFileConfigurableOptions() FileConfigurableOptions { +func (FileConfigurableOptions) DefaultConfig() jsonConfigurable { f := FileConfigurableOptions{} return f } @@ -43,6 +44,7 @@ type Config struct { // A config object represents the entire build configuration for Blue. type config struct { FileConfigurableOptions + ProductVariables productVariables srcDir string // the path of the root source directory @@ -50,56 +52,66 @@ type config struct { envDeps map[string]string } -// loads configuration options from a JSON file in the cwd. -func loadFromConfigFile(config *config) error { - // Make a proxy config - var configProxy FileConfigurableOptions +type jsonConfigurable interface { + DefaultConfig() jsonConfigurable +} +func loadConfig(config *config) error { + err := loadFromConfigFile(&config.FileConfigurableOptions, ConfigFileName) + if err != nil { + return err + } + + return loadFromConfigFile(&config.ProductVariables, ProductVariablesFileName) +} + +// loads configuration options from a JSON file in the cwd. +func loadFromConfigFile(configurable jsonConfigurable, filename string) error { // Try to open the file - configFileReader, err := os.Open(ConfigFileName) + configFileReader, err := os.Open(filename) defer configFileReader.Close() if os.IsNotExist(err) { // Need to create a file, so that blueprint & ninja don't get in // a dependency tracking loop. // Make a file-configurable-options with defaults, write it out using // a json writer. - configProxy = NewFileConfigurableOptions() - err = saveToConfigFile(configProxy) + err = saveToConfigFile(configurable.DefaultConfig(), filename) if err != nil { return err } } else { // Make a decoder for it jsonDecoder := json.NewDecoder(configFileReader) - err = jsonDecoder.Decode(&configProxy) + err = jsonDecoder.Decode(configurable) if err != nil { - return fmt.Errorf("config file: %s did not parse correctly: "+err.Error(), ConfigFileName) + return fmt.Errorf("config file: %s did not parse correctly: "+err.Error(), filename) } } - // Copy the configurable options out of the config_proxy into the config, - // and we're done! - config.FileConfigurableOptions = configProxy - // No error return nil } -func saveToConfigFile(config FileConfigurableOptions) error { +func saveToConfigFile(config jsonConfigurable, filename string) error { data, err := json.MarshalIndent(&config, "", " ") if err != nil { return fmt.Errorf("cannot marshal config data: %s", err.Error()) } - configFileWriter, err := os.Create(ConfigFileName) + configFileWriter, err := os.Create(filename) if err != nil { - return fmt.Errorf("cannot create empty config file %s: %s\n", ConfigFileName, err.Error()) + return fmt.Errorf("cannot create empty config file %s: %s\n", filename, err.Error()) } defer configFileWriter.Close() _, err = configFileWriter.Write(data) if err != nil { - return fmt.Errorf("default config file: %s could not be written: %s", ConfigFileName, err.Error()) + return fmt.Errorf("default config file: %s could not be written: %s", filename, err.Error()) + } + + _, err = configFileWriter.WriteString("\n") + if err != nil { + return fmt.Errorf("default config file: %s could not be written: %s", filename, err.Error()) } return nil @@ -117,7 +129,7 @@ func NewConfig(srcDir string) (Config, error) { } // Load any configurable options from the configuration file - err := loadFromConfigFile(config.config) + err := loadConfig(config.config) if err != nil { return Config{}, err } @@ -133,11 +145,6 @@ func (c *config) IntermediatesDir() string { return ".intermediates" } -// HostGoOS returns the OS of the system that the Go toolchain is being run on. -func (c *config) HostGoOS() string { - return runtime.GOOS -} - // PrebuiltOS returns the name of the host OS used in prebuilts directories func (c *config) PrebuiltOS() string { switch runtime.GOOS { @@ -156,7 +163,7 @@ func (c *config) GoRoot() string { } func (c *config) CpPreserveSymlinksFlags() string { - switch c.HostGoOS() { + switch runtime.GOOS { case "darwin": return "-R" case "linux": diff --git a/common/variable.go b/common/variable.go index 19ec6251a..b1116eada 100644 --- a/common/variable.go +++ b/common/variable.go @@ -53,10 +53,19 @@ type variableProperties struct { var zeroProductVariables variableProperties -// TODO: replace hardcoded test values with per-product values -var productVariables = map[string]interface{}{ - "device_uses_logd": true, - "device_uses_jemalloc": true, +type productVariables struct { + Device_uses_logd bool + Device_uses_jemalloc bool + Device_uses_dlmalloc bool + Dlmalloc_alignment int +} + +func (productVariables) DefaultConfig() jsonConfigurable { + v := productVariables{ + Device_uses_logd: true, + Device_uses_jemalloc: true, + } + return v } func VariableMutator(mctx blueprint.EarlyMutatorContext) { @@ -78,12 +87,13 @@ func VariableMutator(mctx blueprint.EarlyMutatorContext) { continue } - name := proptools.PropertyNameForField(variableValues.Type().Field(i).Name) - property := "product_variables." + name - val := productVariables[name] + name := variableValues.Type().Field(i).Name + property := "product_variables." + proptools.PropertyNameForField(name) - if mctx.ContainsProperty(property) && val != nil { - a.setVariableProperties(mctx, property, variableValue, val) + val := reflect.ValueOf(mctx.Config().(Config).ProductVariables).FieldByName(name) + + if mctx.ContainsProperty(property) && val.IsValid() { + a.setVariableProperties(mctx, property, variableValue, val.Interface()) } } }