Read product variables from soong.variables
Refactor the soong.config loading code to support reading in
product variables from soong.variables.
Change-Id: I389e6bb5c501b53167267d5f5d0d25557811cf72
diff --git a/common/config.go b/common/config.go
index 10ed4f0..348d0db 100644
--- a/common/config.go
+++ b/common/config.go
@@ -25,13 +25,14 @@
// 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 @@
// 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 @@
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 @@
}
// 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 @@
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) 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 19ec625..b1116ea 100644
--- a/common/variable.go
+++ b/common/variable.go
@@ -53,10 +53,19 @@
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 @@
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())
}
}
}