blob: 695e27d821f76eecc2f9ceca2663c88376f4ce8a [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
Colin Cross1332b002015-04-07 17:11:30 -070015package common
Colin Cross3f40fa42015-01-30 17:27:36 -080016
17import (
Colin Cross3f40fa42015-01-30 17:27:36 -080018 "encoding/json"
19 "fmt"
20 "os"
Colin Cross35cec122015-04-02 14:37:16 -070021 "path/filepath"
Colin Cross3f40fa42015-01-30 17:27:36 -080022 "runtime"
23)
24
Colin Cross1332b002015-04-07 17:11:30 -070025type Config interface {
26 CpPreserveSymlinksFlags() string
27 SrcDir() string
28 IntermediatesDir() string
29 Getenv(string) string
30 EnvDeps() map[string]string
31 DeviceOut() string
32 HostOut() string
33 PrebuiltOS() string
34 HostBinTool(string) (string, error)
35 HostJavaTool(string) (string, error)
36}
Colin Cross3f40fa42015-01-30 17:27:36 -080037
38// The configuration file name
39const ConfigFileName = "soong.config"
40
41// A FileConfigurableOptions contains options which can be configured by the
42// config file. These will be included in the config struct.
43type FileConfigurableOptions struct {
44}
45
46func NewFileConfigurableOptions() FileConfigurableOptions {
47 f := FileConfigurableOptions{}
48 return f
49}
50
51// A Config object represents the entire build configuration for Blue.
Colin Cross1332b002015-04-07 17:11:30 -070052type config struct {
Colin Cross3f40fa42015-01-30 17:27:36 -080053 FileConfigurableOptions
54
Colin Cross68f55102015-03-25 14:43:57 -070055 srcDir string // the path of the root source directory
56 envDeps map[string]string
Colin Cross3f40fa42015-01-30 17:27:36 -080057}
58
59// loads configuration options from a JSON file in the cwd.
Colin Cross1332b002015-04-07 17:11:30 -070060func loadFromConfigFile(config *config) error {
Colin Cross3f40fa42015-01-30 17:27:36 -080061 // Make a proxy config
62 var configProxy FileConfigurableOptions
63
64 // Try to open the file
65 configFileReader, err := os.Open(ConfigFileName)
66 defer configFileReader.Close()
67 if os.IsNotExist(err) {
68 // Need to create a file, so that blueprint & ninja don't get in
69 // a dependency tracking loop.
70 // Make a file-configurable-options with defaults, write it out using
71 // a json writer.
72 configProxy = NewFileConfigurableOptions()
73 err = saveToConfigFile(configProxy)
74 if err != nil {
75 return err
76 }
77 } else {
78 // Make a decoder for it
79 jsonDecoder := json.NewDecoder(configFileReader)
80 err = jsonDecoder.Decode(&configProxy)
81 if err != nil {
82 return fmt.Errorf("config file: %s did not parse correctly: "+err.Error(), ConfigFileName)
83 }
84 }
85
86 // Copy the configurable options out of the config_proxy into the config,
87 // and we're done!
88 config.FileConfigurableOptions = configProxy
89
90 // No error
91 return nil
92}
93
94func saveToConfigFile(config FileConfigurableOptions) error {
95 data, err := json.MarshalIndent(&config, "", " ")
96 if err != nil {
97 return fmt.Errorf("cannot marshal config data: %s", err.Error())
98 }
99
100 configFileWriter, err := os.Create(ConfigFileName)
101 if err != nil {
102 return fmt.Errorf("cannot create empty config file %s: %s\n", ConfigFileName, err.Error())
103 }
104 defer configFileWriter.Close()
105
106 _, err = configFileWriter.Write(data)
107 if err != nil {
108 return fmt.Errorf("default config file: %s could not be written: %s", ConfigFileName, err.Error())
109 }
110
111 return nil
112}
113
114// New creates a new Config object. The srcDir argument specifies the path to
115// the root source directory. It also loads the config file, if found.
Colin Cross1332b002015-04-07 17:11:30 -0700116func NewConfig(srcDir string) (Config, error) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800117 // Make a config with default options
Colin Cross1332b002015-04-07 17:11:30 -0700118 config := &config{
Colin Cross68f55102015-03-25 14:43:57 -0700119 srcDir: srcDir,
120 envDeps: make(map[string]string),
121 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800122
123 // Load any configurable options from the configuration file
124 err := loadFromConfigFile(config)
125 if err != nil {
126 return nil, err
127 }
128
129 return config, nil
130}
131
Colin Cross1332b002015-04-07 17:11:30 -0700132func (c *config) SrcDir() string {
Colin Cross3f40fa42015-01-30 17:27:36 -0800133 return c.srcDir
134}
135
Colin Cross1332b002015-04-07 17:11:30 -0700136func (c *config) IntermediatesDir() string {
Colin Cross581c1892015-04-07 16:50:10 -0700137 return ".intermediates"
138}
139
Colin Cross3f40fa42015-01-30 17:27:36 -0800140// HostGoOS returns the OS of the system that the Go toolchain is being run on.
Colin Cross1332b002015-04-07 17:11:30 -0700141func (c *config) HostGoOS() string {
Colin Cross3f40fa42015-01-30 17:27:36 -0800142 return runtime.GOOS
143}
144
145// PrebuiltOS returns the name of the host OS used in prebuilts directories
Colin Cross1332b002015-04-07 17:11:30 -0700146func (c *config) PrebuiltOS() string {
Colin Cross3f40fa42015-01-30 17:27:36 -0800147 switch runtime.GOOS {
148 case "linux":
149 return "linux-x86"
150 case "darwin":
151 return "darwin-x86"
152 default:
153 panic("Unknown GOOS")
154 }
155}
156
157// GoRoot returns the path to the root directory of the Go toolchain.
Colin Cross1332b002015-04-07 17:11:30 -0700158func (c *config) GoRoot() string {
Colin Cross3f40fa42015-01-30 17:27:36 -0800159 return fmt.Sprintf("%s/prebuilts/go/%s", c.srcDir, c.PrebuiltOS())
160}
161
Colin Cross1332b002015-04-07 17:11:30 -0700162func (c *config) CpPreserveSymlinksFlags() string {
Colin Cross3f40fa42015-01-30 17:27:36 -0800163 switch c.HostGoOS() {
164 case "darwin":
165 return "-R"
166 case "linux":
167 return "-d"
168 default:
169 return ""
170 }
171}
Colin Cross68f55102015-03-25 14:43:57 -0700172
Colin Cross1332b002015-04-07 17:11:30 -0700173func (c *config) Getenv(key string) string {
Colin Cross68f55102015-03-25 14:43:57 -0700174 var val string
175 var exists bool
176 if val, exists = c.envDeps[key]; !exists {
177 val = os.Getenv(key)
178 c.envDeps[key] = val
179 }
180 return val
181}
182
Colin Cross1332b002015-04-07 17:11:30 -0700183func (c *config) EnvDeps() map[string]string {
Colin Cross68f55102015-03-25 14:43:57 -0700184 return c.envDeps
185}
Colin Cross35cec122015-04-02 14:37:16 -0700186
187// DeviceName returns the name of the current device target
188// TODO: take an AndroidModuleContext to select the device name for multi-device builds
Colin Cross1332b002015-04-07 17:11:30 -0700189func (c *config) DeviceName() string {
Colin Cross35cec122015-04-02 14:37:16 -0700190 return "unset"
191}
192
193// DeviceOut returns the path to out directory for device targets
Colin Cross1332b002015-04-07 17:11:30 -0700194func (c *config) DeviceOut() string {
Colin Cross35cec122015-04-02 14:37:16 -0700195 return filepath.Join("target/product", c.DeviceName())
196}
197
198// HostOut returns the path to out directory for host targets
Colin Cross1332b002015-04-07 17:11:30 -0700199func (c *config) HostOut() string {
Colin Cross35cec122015-04-02 14:37:16 -0700200 return filepath.Join("host", c.PrebuiltOS())
201}
202
203// HostBin returns the path to bin directory for host targets
Colin Cross1332b002015-04-07 17:11:30 -0700204func (c *config) HostBin() string {
Colin Cross35cec122015-04-02 14:37:16 -0700205 return filepath.Join(c.HostOut(), "bin")
206}
207
208// HostBinTool returns the path to a host tool in the bin directory for host targets
Colin Cross1332b002015-04-07 17:11:30 -0700209func (c *config) HostBinTool(tool string) (string, error) {
Colin Cross35cec122015-04-02 14:37:16 -0700210 return filepath.Join(c.HostBin(), tool), nil
211}
Colin Cross65bf4f22015-04-03 16:54:17 -0700212
213// HostJavaDir returns the path to framework directory for host targets
Colin Cross1332b002015-04-07 17:11:30 -0700214func (c *config) HostJavaDir() string {
Colin Cross65bf4f22015-04-03 16:54:17 -0700215 return filepath.Join(c.HostOut(), "framework")
216}
217
218// HostJavaTool returns the path to a host tool in the frameworks directory for host targets
Colin Cross1332b002015-04-07 17:11:30 -0700219func (c *config) HostJavaTool(tool string) (string, error) {
Colin Cross65bf4f22015-04-03 16:54:17 -0700220 return filepath.Join(c.HostJavaDir(), tool), nil
221}