blob: a6837c131aa429233736f5c723c2f9cee22ec768 [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 Cross3f40fa42015-01-30 17:27:36 -080025// The configuration file name
26const ConfigFileName = "soong.config"
27
28// A FileConfigurableOptions contains options which can be configured by the
29// config file. These will be included in the config struct.
30type FileConfigurableOptions struct {
31}
32
33func NewFileConfigurableOptions() FileConfigurableOptions {
34 f := FileConfigurableOptions{}
35 return f
36}
37
Colin Crossc3c0a492015-04-10 15:43:55 -070038type Config struct {
39 *config
40}
41
42// A config object represents the entire build configuration for Blue.
Colin Cross1332b002015-04-07 17:11:30 -070043type config struct {
Colin Cross3f40fa42015-01-30 17:27:36 -080044 FileConfigurableOptions
45
Colin Cross68f55102015-03-25 14:43:57 -070046 srcDir string // the path of the root source directory
47 envDeps map[string]string
Colin Cross3f40fa42015-01-30 17:27:36 -080048}
49
50// loads configuration options from a JSON file in the cwd.
Colin Cross1332b002015-04-07 17:11:30 -070051func loadFromConfigFile(config *config) error {
Colin Cross3f40fa42015-01-30 17:27:36 -080052 // Make a proxy config
53 var configProxy FileConfigurableOptions
54
55 // Try to open the file
56 configFileReader, err := os.Open(ConfigFileName)
57 defer configFileReader.Close()
58 if os.IsNotExist(err) {
59 // Need to create a file, so that blueprint & ninja don't get in
60 // a dependency tracking loop.
61 // Make a file-configurable-options with defaults, write it out using
62 // a json writer.
63 configProxy = NewFileConfigurableOptions()
64 err = saveToConfigFile(configProxy)
65 if err != nil {
66 return err
67 }
68 } else {
69 // Make a decoder for it
70 jsonDecoder := json.NewDecoder(configFileReader)
71 err = jsonDecoder.Decode(&configProxy)
72 if err != nil {
73 return fmt.Errorf("config file: %s did not parse correctly: "+err.Error(), ConfigFileName)
74 }
75 }
76
77 // Copy the configurable options out of the config_proxy into the config,
78 // and we're done!
79 config.FileConfigurableOptions = configProxy
80
81 // No error
82 return nil
83}
84
85func saveToConfigFile(config FileConfigurableOptions) error {
86 data, err := json.MarshalIndent(&config, "", " ")
87 if err != nil {
88 return fmt.Errorf("cannot marshal config data: %s", err.Error())
89 }
90
91 configFileWriter, err := os.Create(ConfigFileName)
92 if err != nil {
93 return fmt.Errorf("cannot create empty config file %s: %s\n", ConfigFileName, err.Error())
94 }
95 defer configFileWriter.Close()
96
97 _, err = configFileWriter.Write(data)
98 if err != nil {
99 return fmt.Errorf("default config file: %s could not be written: %s", ConfigFileName, err.Error())
100 }
101
102 return nil
103}
104
105// New creates a new Config object. The srcDir argument specifies the path to
106// the root source directory. It also loads the config file, if found.
Colin Cross1332b002015-04-07 17:11:30 -0700107func NewConfig(srcDir string) (Config, error) {
Colin Cross3f40fa42015-01-30 17:27:36 -0800108 // Make a config with default options
Colin Crossc3c0a492015-04-10 15:43:55 -0700109 config := Config{
110 config: &config{
111 srcDir: srcDir,
112 envDeps: make(map[string]string),
113 },
Colin Cross68f55102015-03-25 14:43:57 -0700114 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800115
116 // Load any configurable options from the configuration file
Colin Crossc3c0a492015-04-10 15:43:55 -0700117 err := loadFromConfigFile(config.config)
Colin Cross3f40fa42015-01-30 17:27:36 -0800118 if err != nil {
Colin Crossc3c0a492015-04-10 15:43:55 -0700119 return Config{}, err
Colin Cross3f40fa42015-01-30 17:27:36 -0800120 }
121
122 return config, nil
123}
124
Colin Cross1332b002015-04-07 17:11:30 -0700125func (c *config) SrcDir() string {
Colin Cross3f40fa42015-01-30 17:27:36 -0800126 return c.srcDir
127}
128
Colin Cross1332b002015-04-07 17:11:30 -0700129func (c *config) IntermediatesDir() string {
Colin Cross581c1892015-04-07 16:50:10 -0700130 return ".intermediates"
131}
132
Colin Cross3f40fa42015-01-30 17:27:36 -0800133// HostGoOS returns the OS of the system that the Go toolchain is being run on.
Colin Cross1332b002015-04-07 17:11:30 -0700134func (c *config) HostGoOS() string {
Colin Cross3f40fa42015-01-30 17:27:36 -0800135 return runtime.GOOS
136}
137
138// PrebuiltOS returns the name of the host OS used in prebuilts directories
Colin Cross1332b002015-04-07 17:11:30 -0700139func (c *config) PrebuiltOS() string {
Colin Cross3f40fa42015-01-30 17:27:36 -0800140 switch runtime.GOOS {
141 case "linux":
142 return "linux-x86"
143 case "darwin":
144 return "darwin-x86"
145 default:
146 panic("Unknown GOOS")
147 }
148}
149
150// GoRoot returns the path to the root directory of the Go toolchain.
Colin Cross1332b002015-04-07 17:11:30 -0700151func (c *config) GoRoot() string {
Colin Cross3f40fa42015-01-30 17:27:36 -0800152 return fmt.Sprintf("%s/prebuilts/go/%s", c.srcDir, c.PrebuiltOS())
153}
154
Colin Cross1332b002015-04-07 17:11:30 -0700155func (c *config) CpPreserveSymlinksFlags() string {
Colin Cross3f40fa42015-01-30 17:27:36 -0800156 switch c.HostGoOS() {
157 case "darwin":
158 return "-R"
159 case "linux":
160 return "-d"
161 default:
162 return ""
163 }
164}
Colin Cross68f55102015-03-25 14:43:57 -0700165
Colin Cross1332b002015-04-07 17:11:30 -0700166func (c *config) Getenv(key string) string {
Colin Cross68f55102015-03-25 14:43:57 -0700167 var val string
168 var exists bool
169 if val, exists = c.envDeps[key]; !exists {
170 val = os.Getenv(key)
171 c.envDeps[key] = val
172 }
173 return val
174}
175
Colin Cross1332b002015-04-07 17:11:30 -0700176func (c *config) EnvDeps() map[string]string {
Colin Cross68f55102015-03-25 14:43:57 -0700177 return c.envDeps
178}
Colin Cross35cec122015-04-02 14:37:16 -0700179
180// DeviceName returns the name of the current device target
181// TODO: take an AndroidModuleContext to select the device name for multi-device builds
Colin Cross1332b002015-04-07 17:11:30 -0700182func (c *config) DeviceName() string {
Colin Cross35cec122015-04-02 14:37:16 -0700183 return "unset"
184}
185
186// DeviceOut returns the path to out directory for device targets
Colin Cross1332b002015-04-07 17:11:30 -0700187func (c *config) DeviceOut() string {
Colin Cross35cec122015-04-02 14:37:16 -0700188 return filepath.Join("target/product", c.DeviceName())
189}
190
191// HostOut returns the path to out directory for host targets
Colin Cross1332b002015-04-07 17:11:30 -0700192func (c *config) HostOut() string {
Colin Cross35cec122015-04-02 14:37:16 -0700193 return filepath.Join("host", c.PrebuiltOS())
194}
195
196// HostBin returns the path to bin directory for host targets
Colin Cross1332b002015-04-07 17:11:30 -0700197func (c *config) HostBin() string {
Colin Cross35cec122015-04-02 14:37:16 -0700198 return filepath.Join(c.HostOut(), "bin")
199}
200
201// HostBinTool returns the path to a host tool in the bin directory for host targets
Colin Cross1332b002015-04-07 17:11:30 -0700202func (c *config) HostBinTool(tool string) (string, error) {
Colin Cross35cec122015-04-02 14:37:16 -0700203 return filepath.Join(c.HostBin(), tool), nil
204}
Colin Cross65bf4f22015-04-03 16:54:17 -0700205
206// HostJavaDir returns the path to framework directory for host targets
Colin Cross1332b002015-04-07 17:11:30 -0700207func (c *config) HostJavaDir() string {
Colin Cross65bf4f22015-04-03 16:54:17 -0700208 return filepath.Join(c.HostOut(), "framework")
209}
210
211// HostJavaTool returns the path to a host tool in the frameworks directory for host targets
Colin Cross1332b002015-04-07 17:11:30 -0700212func (c *config) HostJavaTool(tool string) (string, error) {
Colin Cross65bf4f22015-04-03 16:54:17 -0700213 return filepath.Join(c.HostJavaDir(), tool), nil
214}