blob: 6cdc211e7d8e9a810c52777893e3f86272b262d9 [file] [log] [blame]
Colin Cross3f40fa42015-01-30 17:27:36 -08001// 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 config
16
17import (
18 "android/soong/common"
19 "encoding/json"
20 "fmt"
21 "os"
22 "runtime"
23)
24
25var _ common.Config = (*Config)(nil)
26
27// The configuration file name
28const ConfigFileName = "soong.config"
29
30// A FileConfigurableOptions contains options which can be configured by the
31// config file. These will be included in the config struct.
32type FileConfigurableOptions struct {
33}
34
35func NewFileConfigurableOptions() FileConfigurableOptions {
36 f := FileConfigurableOptions{}
37 return f
38}
39
40// A Config object represents the entire build configuration for Blue.
41type Config struct {
42 FileConfigurableOptions
43
44 srcDir string // the path of the root source directory
45}
46
47// loads configuration options from a JSON file in the cwd.
48func loadFromConfigFile(config *Config) error {
49 // Make a proxy config
50 var configProxy FileConfigurableOptions
51
52 // Try to open the file
53 configFileReader, err := os.Open(ConfigFileName)
54 defer configFileReader.Close()
55 if os.IsNotExist(err) {
56 // Need to create a file, so that blueprint & ninja don't get in
57 // a dependency tracking loop.
58 // Make a file-configurable-options with defaults, write it out using
59 // a json writer.
60 configProxy = NewFileConfigurableOptions()
61 err = saveToConfigFile(configProxy)
62 if err != nil {
63 return err
64 }
65 } else {
66 // Make a decoder for it
67 jsonDecoder := json.NewDecoder(configFileReader)
68 err = jsonDecoder.Decode(&configProxy)
69 if err != nil {
70 return fmt.Errorf("config file: %s did not parse correctly: "+err.Error(), ConfigFileName)
71 }
72 }
73
74 // Copy the configurable options out of the config_proxy into the config,
75 // and we're done!
76 config.FileConfigurableOptions = configProxy
77
78 // No error
79 return nil
80}
81
82func saveToConfigFile(config FileConfigurableOptions) error {
83 data, err := json.MarshalIndent(&config, "", " ")
84 if err != nil {
85 return fmt.Errorf("cannot marshal config data: %s", err.Error())
86 }
87
88 configFileWriter, err := os.Create(ConfigFileName)
89 if err != nil {
90 return fmt.Errorf("cannot create empty config file %s: %s\n", ConfigFileName, err.Error())
91 }
92 defer configFileWriter.Close()
93
94 _, err = configFileWriter.Write(data)
95 if err != nil {
96 return fmt.Errorf("default config file: %s could not be written: %s", ConfigFileName, err.Error())
97 }
98
99 return nil
100}
101
102// New creates a new Config object. The srcDir argument specifies the path to
103// the root source directory. It also loads the config file, if found.
104func New(srcDir string) (*Config, error) {
105 // Make a config with default options
106 config := &Config{srcDir: srcDir}
107
108 // Load any configurable options from the configuration file
109 err := loadFromConfigFile(config)
110 if err != nil {
111 return nil, err
112 }
113
114 return config, nil
115}
116
117func (c *Config) SrcDir() string {
118 return c.srcDir
119}
120
121// HostGoOS returns the OS of the system that the Go toolchain is being run on.
122func (c *Config) HostGoOS() string {
123 return runtime.GOOS
124}
125
126// PrebuiltOS returns the name of the host OS used in prebuilts directories
127func (c *Config) PrebuiltOS() string {
128 switch runtime.GOOS {
129 case "linux":
130 return "linux-x86"
131 case "darwin":
132 return "darwin-x86"
133 default:
134 panic("Unknown GOOS")
135 }
136}
137
138// GoRoot returns the path to the root directory of the Go toolchain.
139func (c *Config) GoRoot() string {
140 return fmt.Sprintf("%s/prebuilts/go/%s", c.srcDir, c.PrebuiltOS())
141}
142
143func (c *Config) CpPreserveSymlinksFlags() string {
144 switch c.HostGoOS() {
145 case "darwin":
146 return "-R"
147 case "linux":
148 return "-d"
149 default:
150 return ""
151 }
152}