blob: 6cdc211e7d8e9a810c52777893e3f86272b262d9 [file] [log] [blame]
// 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 config
import (
"android/soong/common"
"encoding/json"
"fmt"
"os"
"runtime"
)
var _ common.Config = (*Config)(nil)
// The configuration file name
const ConfigFileName = "soong.config"
// 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 {
f := FileConfigurableOptions{}
return f
}
// A Config object represents the entire build configuration for Blue.
type Config struct {
FileConfigurableOptions
srcDir string // the path of the root source directory
}
// loads configuration options from a JSON file in the cwd.
func loadFromConfigFile(config *Config) error {
// Make a proxy config
var configProxy FileConfigurableOptions
// Try to open the file
configFileReader, err := os.Open(ConfigFileName)
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)
if err != nil {
return err
}
} else {
// Make a decoder for it
jsonDecoder := json.NewDecoder(configFileReader)
err = jsonDecoder.Decode(&configProxy)
if err != nil {
return fmt.Errorf("config file: %s did not parse correctly: "+err.Error(), ConfigFileName)
}
}
// 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 {
data, err := json.MarshalIndent(&config, "", " ")
if err != nil {
return fmt.Errorf("cannot marshal config data: %s", err.Error())
}
configFileWriter, err := os.Create(ConfigFileName)
if err != nil {
return fmt.Errorf("cannot create empty config file %s: %s\n", ConfigFileName, 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 nil
}
// New creates a new Config object. The srcDir argument specifies the path to
// the root source directory. It also loads the config file, if found.
func New(srcDir string) (*Config, error) {
// Make a config with default options
config := &Config{srcDir: srcDir}
// Load any configurable options from the configuration file
err := loadFromConfigFile(config)
if err != nil {
return nil, err
}
return config, nil
}
func (c *Config) SrcDir() string {
return c.srcDir
}
// 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 {
case "linux":
return "linux-x86"
case "darwin":
return "darwin-x86"
default:
panic("Unknown GOOS")
}
}
// GoRoot returns the path to the root directory of the Go toolchain.
func (c *Config) GoRoot() string {
return fmt.Sprintf("%s/prebuilts/go/%s", c.srcDir, c.PrebuiltOS())
}
func (c *Config) CpPreserveSymlinksFlags() string {
switch c.HostGoOS() {
case "darwin":
return "-R"
case "linux":
return "-d"
default:
return ""
}
}