| Dan Willemsen | 1e70446 | 2016-08-21 15:17:17 -0700 | [diff] [blame] | 1 | // Copyright 2017 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 |  | 
|  | 15 | package build | 
|  | 16 |  | 
|  | 17 | import ( | 
| Nan Zhang | 2e6a4ff | 2018-02-14 13:27:26 -0800 | [diff] [blame] | 18 | "io/ioutil" | 
| Dan Willemsen | c2af0be | 2017-01-20 14:10:01 -0800 | [diff] [blame] | 19 | "log" | 
|  | 20 | "os" | 
| Dan Willemsen | 1e70446 | 2016-08-21 15:17:17 -0700 | [diff] [blame] | 21 | "path/filepath" | 
|  | 22 | "runtime" | 
|  | 23 | "strconv" | 
|  | 24 | "strings" | 
| Nan Zhang | 2e6a4ff | 2018-02-14 13:27:26 -0800 | [diff] [blame] | 25 | "time" | 
| Jeff Gaston | efc1b41 | 2017-03-29 17:29:06 -0700 | [diff] [blame] | 26 |  | 
|  | 27 | "android/soong/shared" | 
| Dan Willemsen | 1e70446 | 2016-08-21 15:17:17 -0700 | [diff] [blame] | 28 | ) | 
|  | 29 |  | 
|  | 30 | type Config struct{ *configImpl } | 
|  | 31 |  | 
|  | 32 | type configImpl struct { | 
|  | 33 | // From the environment | 
|  | 34 | arguments []string | 
|  | 35 | goma      bool | 
|  | 36 | environ   *Environment | 
|  | 37 |  | 
|  | 38 | // From the arguments | 
| Colin Cross | 3719349 | 2017-11-16 17:55:00 -0800 | [diff] [blame] | 39 | parallel   int | 
|  | 40 | keepGoing  int | 
|  | 41 | verbose    bool | 
|  | 42 | checkbuild bool | 
|  | 43 | dist       bool | 
|  | 44 | skipMake   bool | 
| Dan Willemsen | 1e70446 | 2016-08-21 15:17:17 -0700 | [diff] [blame] | 45 |  | 
|  | 46 | // From the product config | 
| Dan Willemsen | 6ab79db | 2018-05-02 00:06:28 -0700 | [diff] [blame] | 47 | katiArgs        []string | 
|  | 48 | ninjaArgs       []string | 
|  | 49 | katiSuffix      string | 
|  | 50 | targetDevice    string | 
|  | 51 | targetDeviceDir string | 
| Dan Willemsen | 3d60b11 | 2018-04-04 22:25:56 -0700 | [diff] [blame] | 52 |  | 
|  | 53 | brokenDupRules bool | 
| Dan Willemsen | a14704c | 2017-10-28 22:57:22 -0700 | [diff] [blame] | 54 |  | 
|  | 55 | pathReplaced bool | 
| Dan Willemsen | 1e70446 | 2016-08-21 15:17:17 -0700 | [diff] [blame] | 56 | } | 
|  | 57 |  | 
| Dan Willemsen | c2af0be | 2017-01-20 14:10:01 -0800 | [diff] [blame] | 58 | const srcDirFileCheck = "build/soong/root.bp" | 
|  | 59 |  | 
| Dan Willemsen | 1e70446 | 2016-08-21 15:17:17 -0700 | [diff] [blame] | 60 | func NewConfig(ctx Context, args ...string) Config { | 
|  | 61 | ret := &configImpl{ | 
|  | 62 | environ: OsEnvironment(), | 
|  | 63 | } | 
|  | 64 |  | 
| Dan Willemsen | 9b58749 | 2017-07-10 22:13:00 -0700 | [diff] [blame] | 65 | // Sane default matching ninja | 
|  | 66 | ret.parallel = runtime.NumCPU() + 2 | 
|  | 67 | ret.keepGoing = 1 | 
|  | 68 |  | 
|  | 69 | ret.parseArgs(ctx, args) | 
|  | 70 |  | 
| Dan Willemsen | 0c3919e | 2017-03-02 15:49:10 -0800 | [diff] [blame] | 71 | // Make sure OUT_DIR is set appropriately | 
| Dan Willemsen | 02f3add | 2017-05-12 13:50:19 -0700 | [diff] [blame] | 72 | if outDir, ok := ret.environ.Get("OUT_DIR"); ok { | 
|  | 73 | ret.environ.Set("OUT_DIR", filepath.Clean(outDir)) | 
|  | 74 | } else { | 
| Dan Willemsen | 0c3919e | 2017-03-02 15:49:10 -0800 | [diff] [blame] | 75 | outDir := "out" | 
|  | 76 | if baseDir, ok := ret.environ.Get("OUT_DIR_COMMON_BASE"); ok { | 
|  | 77 | if wd, err := os.Getwd(); err != nil { | 
|  | 78 | ctx.Fatalln("Failed to get working directory:", err) | 
|  | 79 | } else { | 
|  | 80 | outDir = filepath.Join(baseDir, filepath.Base(wd)) | 
|  | 81 | } | 
|  | 82 | } | 
|  | 83 | ret.environ.Set("OUT_DIR", outDir) | 
|  | 84 | } | 
|  | 85 |  | 
| Dan Willemsen | 1e70446 | 2016-08-21 15:17:17 -0700 | [diff] [blame] | 86 | ret.environ.Unset( | 
|  | 87 | // We're already using it | 
|  | 88 | "USE_SOONG_UI", | 
|  | 89 |  | 
|  | 90 | // We should never use GOROOT/GOPATH from the shell environment | 
|  | 91 | "GOROOT", | 
|  | 92 | "GOPATH", | 
|  | 93 |  | 
|  | 94 | // These should only come from Soong, not the environment. | 
|  | 95 | "CLANG", | 
|  | 96 | "CLANG_CXX", | 
|  | 97 | "CCC_CC", | 
|  | 98 | "CCC_CXX", | 
|  | 99 |  | 
|  | 100 | // Used by the goma compiler wrapper, but should only be set by | 
|  | 101 | // gomacc | 
|  | 102 | "GOMACC_PATH", | 
| Dan Willemsen | 0c3919e | 2017-03-02 15:49:10 -0800 | [diff] [blame] | 103 |  | 
|  | 104 | // We handle this above | 
|  | 105 | "OUT_DIR_COMMON_BASE", | 
| Dan Willemsen | 68a0985 | 2017-04-18 13:56:57 -0700 | [diff] [blame] | 106 |  | 
|  | 107 | // Variables that have caused problems in the past | 
| Dan Willemsen | ebfe33a | 2018-05-01 10:07:50 -0700 | [diff] [blame] | 108 | "CDPATH", | 
| Dan Willemsen | 68a0985 | 2017-04-18 13:56:57 -0700 | [diff] [blame] | 109 | "DISPLAY", | 
|  | 110 | "GREP_OPTIONS", | 
| Dan Willemsen | ebfe33a | 2018-05-01 10:07:50 -0700 | [diff] [blame] | 111 | "NDK_ROOT", | 
| Dan Willemsen | c40e10b | 2017-07-11 14:30:00 -0700 | [diff] [blame] | 112 |  | 
|  | 113 | // Drop make flags | 
|  | 114 | "MAKEFLAGS", | 
|  | 115 | "MAKELEVEL", | 
|  | 116 | "MFLAGS", | 
| Dan Willemsen | d9e8f0a | 2017-10-30 13:42:06 -0700 | [diff] [blame] | 117 |  | 
|  | 118 | // Set in envsetup.sh, reset in makefiles | 
|  | 119 | "ANDROID_JAVA_TOOLCHAIN", | 
| Dan Willemsen | 1e70446 | 2016-08-21 15:17:17 -0700 | [diff] [blame] | 120 | ) | 
|  | 121 |  | 
|  | 122 | // Tell python not to spam the source tree with .pyc files. | 
|  | 123 | ret.environ.Set("PYTHONDONTWRITEBYTECODE", "1") | 
|  | 124 |  | 
| Dan Willemsen | 32a669b | 2018-03-08 19:42:00 -0800 | [diff] [blame] | 125 | ret.environ.Set("TMPDIR", absPath(ctx, ret.TempDir())) | 
|  | 126 |  | 
| Dan Willemsen | c2af0be | 2017-01-20 14:10:01 -0800 | [diff] [blame] | 127 | // Precondition: the current directory is the top of the source tree | 
|  | 128 | if _, err := os.Stat(srcDirFileCheck); err != nil { | 
|  | 129 | if os.IsNotExist(err) { | 
|  | 130 | log.Fatalf("Current working directory must be the source tree. %q not found", srcDirFileCheck) | 
|  | 131 | } | 
|  | 132 | log.Fatalln("Error verifying tree state:", err) | 
|  | 133 | } | 
|  | 134 |  | 
| Dan Willemsen | d9e8f0a | 2017-10-30 13:42:06 -0700 | [diff] [blame] | 135 | if srcDir := absPath(ctx, "."); strings.ContainsRune(srcDir, ' ') { | 
|  | 136 | log.Println("You are building in a directory whose absolute path contains a space character:") | 
|  | 137 | log.Println() | 
|  | 138 | log.Printf("%q\n", srcDir) | 
|  | 139 | log.Println() | 
|  | 140 | log.Fatalln("Directory names containing spaces are not supported") | 
| Dan Willemsen | db8457c | 2017-05-12 16:38:17 -0700 | [diff] [blame] | 141 | } | 
|  | 142 |  | 
|  | 143 | if outDir := ret.OutDir(); strings.ContainsRune(outDir, ' ') { | 
|  | 144 | log.Println("The absolute path of your output directory ($OUT_DIR) contains a space character:") | 
|  | 145 | log.Println() | 
|  | 146 | log.Printf("%q\n", outDir) | 
|  | 147 | log.Println() | 
|  | 148 | log.Fatalln("Directory names containing spaces are not supported") | 
|  | 149 | } | 
|  | 150 |  | 
|  | 151 | if distDir := ret.DistDir(); strings.ContainsRune(distDir, ' ') { | 
|  | 152 | log.Println("The absolute path of your dist directory ($DIST_DIR) contains a space character:") | 
|  | 153 | log.Println() | 
|  | 154 | log.Printf("%q\n", distDir) | 
|  | 155 | log.Println() | 
|  | 156 | log.Fatalln("Directory names containing spaces are not supported") | 
|  | 157 | } | 
|  | 158 |  | 
| Dan Willemsen | d9e8f0a | 2017-10-30 13:42:06 -0700 | [diff] [blame] | 159 | // Configure Java-related variables, including adding it to $PATH | 
| Tobias Thierer | e59aeff | 2017-12-20 22:40:39 +0000 | [diff] [blame] | 160 | java8Home := filepath.Join("prebuilts/jdk/jdk8", ret.HostPrebuiltTag()) | 
|  | 161 | java9Home := filepath.Join("prebuilts/jdk/jdk9", ret.HostPrebuiltTag()) | 
| Dan Willemsen | d9e8f0a | 2017-10-30 13:42:06 -0700 | [diff] [blame] | 162 | javaHome := func() string { | 
|  | 163 | if override, ok := ret.environ.Get("OVERRIDE_ANDROID_JAVA_HOME"); ok { | 
|  | 164 | return override | 
|  | 165 | } | 
| Tobias Thierer | 18099fd | 2017-11-17 14:14:29 +0000 | [diff] [blame] | 166 | v, ok := ret.environ.Get("EXPERIMENTAL_USE_OPENJDK9") | 
|  | 167 | if !ok { | 
|  | 168 | v2, ok2 := ret.environ.Get("RUN_ERROR_PRONE") | 
|  | 169 | if ok2 && (v2 == "true") { | 
|  | 170 | v = "false" | 
|  | 171 | } else { | 
|  | 172 | v = "1.8" | 
|  | 173 | } | 
|  | 174 | } | 
|  | 175 | if v != "false" { | 
| Tobias Thierer | e59aeff | 2017-12-20 22:40:39 +0000 | [diff] [blame] | 176 | return java9Home | 
| Dan Willemsen | d9e8f0a | 2017-10-30 13:42:06 -0700 | [diff] [blame] | 177 | } | 
| Tobias Thierer | e59aeff | 2017-12-20 22:40:39 +0000 | [diff] [blame] | 178 | return java8Home | 
| Dan Willemsen | d9e8f0a | 2017-10-30 13:42:06 -0700 | [diff] [blame] | 179 | }() | 
|  | 180 | absJavaHome := absPath(ctx, javaHome) | 
|  | 181 |  | 
| Dan Willemsen | ed86952 | 2018-01-08 14:58:46 -0800 | [diff] [blame] | 182 | ret.configureLocale(ctx) | 
|  | 183 |  | 
| Dan Willemsen | d9e8f0a | 2017-10-30 13:42:06 -0700 | [diff] [blame] | 184 | newPath := []string{filepath.Join(absJavaHome, "bin")} | 
|  | 185 | if path, ok := ret.environ.Get("PATH"); ok && path != "" { | 
|  | 186 | newPath = append(newPath, path) | 
|  | 187 | } | 
|  | 188 | ret.environ.Unset("OVERRIDE_ANDROID_JAVA_HOME") | 
|  | 189 | ret.environ.Set("JAVA_HOME", absJavaHome) | 
|  | 190 | ret.environ.Set("ANDROID_JAVA_HOME", javaHome) | 
| Tobias Thierer | e59aeff | 2017-12-20 22:40:39 +0000 | [diff] [blame] | 191 | ret.environ.Set("ANDROID_JAVA8_HOME", java8Home) | 
|  | 192 | ret.environ.Set("ANDROID_JAVA9_HOME", java9Home) | 
| Dan Willemsen | d9e8f0a | 2017-10-30 13:42:06 -0700 | [diff] [blame] | 193 | ret.environ.Set("PATH", strings.Join(newPath, string(filepath.ListSeparator))) | 
|  | 194 |  | 
| Nan Zhang | 2e6a4ff | 2018-02-14 13:27:26 -0800 | [diff] [blame] | 195 | outDir := ret.OutDir() | 
|  | 196 | buildDateTimeFile := filepath.Join(outDir, "build_date.txt") | 
|  | 197 | var content string | 
|  | 198 | if buildDateTime, ok := ret.environ.Get("BUILD_DATETIME"); ok && buildDateTime != "" { | 
|  | 199 | content = buildDateTime | 
|  | 200 | } else { | 
|  | 201 | content = strconv.FormatInt(time.Now().Unix(), 10) | 
|  | 202 | } | 
|  | 203 | err := ioutil.WriteFile(buildDateTimeFile, []byte(content), 0777) | 
|  | 204 | if err != nil { | 
|  | 205 | ctx.Fatalln("Failed to write BUILD_DATETIME to file:", err) | 
|  | 206 | } | 
|  | 207 | ret.environ.Set("BUILD_DATETIME_FILE", buildDateTimeFile) | 
|  | 208 |  | 
| Dan Willemsen | 9b58749 | 2017-07-10 22:13:00 -0700 | [diff] [blame] | 209 | return Config{ret} | 
|  | 210 | } | 
|  | 211 |  | 
|  | 212 | func (c *configImpl) parseArgs(ctx Context, args []string) { | 
|  | 213 | for i := 0; i < len(args); i++ { | 
|  | 214 | arg := strings.TrimSpace(args[i]) | 
| Dan Willemsen | 1e70446 | 2016-08-21 15:17:17 -0700 | [diff] [blame] | 215 | if arg == "--make-mode" { | 
| Dan Willemsen | 1e70446 | 2016-08-21 15:17:17 -0700 | [diff] [blame] | 216 | } else if arg == "showcommands" { | 
| Dan Willemsen | 9b58749 | 2017-07-10 22:13:00 -0700 | [diff] [blame] | 217 | c.verbose = true | 
| Dan Willemsen | e0879fc | 2017-08-04 15:06:27 -0700 | [diff] [blame] | 218 | } else if arg == "--skip-make" { | 
|  | 219 | c.skipMake = true | 
| Dan Willemsen | 6ac63ef | 2017-10-17 20:35:34 -0700 | [diff] [blame] | 220 | } else if len(arg) > 0 && arg[0] == '-' { | 
| Dan Willemsen | 9b58749 | 2017-07-10 22:13:00 -0700 | [diff] [blame] | 221 | parseArgNum := func(def int) int { | 
|  | 222 | if len(arg) > 2 { | 
|  | 223 | p, err := strconv.ParseUint(arg[2:], 10, 31) | 
|  | 224 | if err != nil { | 
|  | 225 | ctx.Fatalf("Failed to parse %q: %v", arg, err) | 
|  | 226 | } | 
|  | 227 | return int(p) | 
|  | 228 | } else if i+1 < len(args) { | 
|  | 229 | p, err := strconv.ParseUint(args[i+1], 10, 31) | 
|  | 230 | if err == nil { | 
|  | 231 | i++ | 
|  | 232 | return int(p) | 
|  | 233 | } | 
|  | 234 | } | 
|  | 235 | return def | 
|  | 236 | } | 
|  | 237 |  | 
| Dan Willemsen | 6ac63ef | 2017-10-17 20:35:34 -0700 | [diff] [blame] | 238 | if len(arg) > 1 && arg[1] == 'j' { | 
| Dan Willemsen | 9b58749 | 2017-07-10 22:13:00 -0700 | [diff] [blame] | 239 | c.parallel = parseArgNum(c.parallel) | 
| Dan Willemsen | 6ac63ef | 2017-10-17 20:35:34 -0700 | [diff] [blame] | 240 | } else if len(arg) > 1 && arg[1] == 'k' { | 
| Dan Willemsen | 9b58749 | 2017-07-10 22:13:00 -0700 | [diff] [blame] | 241 | c.keepGoing = parseArgNum(0) | 
| Dan Willemsen | 1e70446 | 2016-08-21 15:17:17 -0700 | [diff] [blame] | 242 | } else { | 
|  | 243 | ctx.Fatalln("Unknown option:", arg) | 
|  | 244 | } | 
| Dan Willemsen | 091525e | 2017-07-11 14:17:50 -0700 | [diff] [blame] | 245 | } else if k, v, ok := decodeKeyValue(arg); ok && len(k) > 0 { | 
|  | 246 | c.environ.Set(k, v) | 
| Dan Willemsen | 1e70446 | 2016-08-21 15:17:17 -0700 | [diff] [blame] | 247 | } else { | 
| Dan Willemsen | e0879fc | 2017-08-04 15:06:27 -0700 | [diff] [blame] | 248 | if arg == "dist" { | 
|  | 249 | c.dist = true | 
| Colin Cross | 3719349 | 2017-11-16 17:55:00 -0800 | [diff] [blame] | 250 | } else if arg == "checkbuild" { | 
|  | 251 | c.checkbuild = true | 
| Dan Willemsen | e0879fc | 2017-08-04 15:06:27 -0700 | [diff] [blame] | 252 | } | 
| Dan Willemsen | 9b58749 | 2017-07-10 22:13:00 -0700 | [diff] [blame] | 253 | c.arguments = append(c.arguments, arg) | 
| Dan Willemsen | 1e70446 | 2016-08-21 15:17:17 -0700 | [diff] [blame] | 254 | } | 
|  | 255 | } | 
| Dan Willemsen | 1e70446 | 2016-08-21 15:17:17 -0700 | [diff] [blame] | 256 | } | 
|  | 257 |  | 
| Dan Willemsen | ed86952 | 2018-01-08 14:58:46 -0800 | [diff] [blame] | 258 | func (c *configImpl) configureLocale(ctx Context) { | 
|  | 259 | cmd := Command(ctx, Config{c}, "locale", "locale", "-a") | 
|  | 260 | output, err := cmd.Output() | 
|  | 261 |  | 
|  | 262 | var locales []string | 
|  | 263 | if err == nil { | 
|  | 264 | locales = strings.Split(string(output), "\n") | 
|  | 265 | } else { | 
|  | 266 | // If we're unable to list the locales, let's assume en_US.UTF-8 | 
|  | 267 | locales = []string{"en_US.UTF-8"} | 
|  | 268 | ctx.Verbosef("Failed to list locales (%q), falling back to %q", err, locales) | 
|  | 269 | } | 
|  | 270 |  | 
|  | 271 | // gettext uses LANGUAGE, which is passed directly through | 
|  | 272 |  | 
|  | 273 | // For LANG and LC_*, only preserve the evaluated version of | 
|  | 274 | // LC_MESSAGES | 
|  | 275 | user_lang := "" | 
|  | 276 | if lc_all, ok := c.environ.Get("LC_ALL"); ok { | 
|  | 277 | user_lang = lc_all | 
|  | 278 | } else if lc_messages, ok := c.environ.Get("LC_MESSAGES"); ok { | 
|  | 279 | user_lang = lc_messages | 
|  | 280 | } else if lang, ok := c.environ.Get("LANG"); ok { | 
|  | 281 | user_lang = lang | 
|  | 282 | } | 
|  | 283 |  | 
|  | 284 | c.environ.UnsetWithPrefix("LC_") | 
|  | 285 |  | 
|  | 286 | if user_lang != "" { | 
|  | 287 | c.environ.Set("LC_MESSAGES", user_lang) | 
|  | 288 | } | 
|  | 289 |  | 
|  | 290 | // The for LANG, use C.UTF-8 if it exists (Debian currently, proposed | 
|  | 291 | // for others) | 
|  | 292 | if inList("C.UTF-8", locales) { | 
|  | 293 | c.environ.Set("LANG", "C.UTF-8") | 
|  | 294 | } else if inList("en_US.UTF-8", locales) { | 
|  | 295 | c.environ.Set("LANG", "en_US.UTF-8") | 
|  | 296 | } else if inList("en_US.utf8", locales) { | 
|  | 297 | // These normalize to the same thing | 
|  | 298 | c.environ.Set("LANG", "en_US.UTF-8") | 
|  | 299 | } else { | 
|  | 300 | ctx.Fatalln("System doesn't support either C.UTF-8 or en_US.UTF-8") | 
|  | 301 | } | 
|  | 302 | } | 
|  | 303 |  | 
| Dan Willemsen | 1e70446 | 2016-08-21 15:17:17 -0700 | [diff] [blame] | 304 | // Lunch configures the environment for a specific product similarly to the | 
|  | 305 | // `lunch` bash function. | 
|  | 306 | func (c *configImpl) Lunch(ctx Context, product, variant string) { | 
|  | 307 | if variant != "eng" && variant != "userdebug" && variant != "user" { | 
|  | 308 | ctx.Fatalf("Invalid variant %q. Must be one of 'user', 'userdebug' or 'eng'", variant) | 
|  | 309 | } | 
|  | 310 |  | 
|  | 311 | c.environ.Set("TARGET_PRODUCT", product) | 
|  | 312 | c.environ.Set("TARGET_BUILD_VARIANT", variant) | 
|  | 313 | c.environ.Set("TARGET_BUILD_TYPE", "release") | 
|  | 314 | c.environ.Unset("TARGET_BUILD_APPS") | 
|  | 315 | } | 
|  | 316 |  | 
|  | 317 | // Tapas configures the environment to build one or more unbundled apps, | 
|  | 318 | // similarly to the `tapas` bash function. | 
|  | 319 | func (c *configImpl) Tapas(ctx Context, apps []string, arch, variant string) { | 
|  | 320 | if len(apps) == 0 { | 
|  | 321 | apps = []string{"all"} | 
|  | 322 | } | 
|  | 323 | if variant == "" { | 
|  | 324 | variant = "eng" | 
|  | 325 | } | 
|  | 326 |  | 
|  | 327 | if variant != "eng" && variant != "userdebug" && variant != "user" { | 
|  | 328 | ctx.Fatalf("Invalid variant %q. Must be one of 'user', 'userdebug' or 'eng'", variant) | 
|  | 329 | } | 
|  | 330 |  | 
|  | 331 | var product string | 
|  | 332 | switch arch { | 
| Dan Willemsen | 1e70446 | 2016-08-21 15:17:17 -0700 | [diff] [blame] | 333 | case "arm", "": | 
|  | 334 | product = "aosp_arm" | 
|  | 335 | case "arm64": | 
|  | 336 | product = "aosm_arm64" | 
|  | 337 | case "mips": | 
|  | 338 | product = "aosp_mips" | 
|  | 339 | case "mips64": | 
|  | 340 | product = "aosp_mips64" | 
|  | 341 | case "x86": | 
|  | 342 | product = "aosp_x86" | 
|  | 343 | case "x86_64": | 
|  | 344 | product = "aosp_x86_64" | 
|  | 345 | default: | 
|  | 346 | ctx.Fatalf("Invalid architecture: %q", arch) | 
|  | 347 | } | 
|  | 348 |  | 
|  | 349 | c.environ.Set("TARGET_PRODUCT", product) | 
|  | 350 | c.environ.Set("TARGET_BUILD_VARIANT", variant) | 
|  | 351 | c.environ.Set("TARGET_BUILD_TYPE", "release") | 
|  | 352 | c.environ.Set("TARGET_BUILD_APPS", strings.Join(apps, " ")) | 
|  | 353 | } | 
|  | 354 |  | 
|  | 355 | func (c *configImpl) Environment() *Environment { | 
|  | 356 | return c.environ | 
|  | 357 | } | 
|  | 358 |  | 
|  | 359 | func (c *configImpl) Arguments() []string { | 
|  | 360 | return c.arguments | 
|  | 361 | } | 
|  | 362 |  | 
|  | 363 | func (c *configImpl) OutDir() string { | 
|  | 364 | if outDir, ok := c.environ.Get("OUT_DIR"); ok { | 
|  | 365 | return outDir | 
|  | 366 | } | 
|  | 367 | return "out" | 
|  | 368 | } | 
|  | 369 |  | 
| Dan Willemsen | 8a073a8 | 2017-02-04 17:30:44 -0800 | [diff] [blame] | 370 | func (c *configImpl) DistDir() string { | 
|  | 371 | if distDir, ok := c.environ.Get("DIST_DIR"); ok { | 
|  | 372 | return distDir | 
|  | 373 | } | 
|  | 374 | return filepath.Join(c.OutDir(), "dist") | 
|  | 375 | } | 
|  | 376 |  | 
| Dan Willemsen | 1e70446 | 2016-08-21 15:17:17 -0700 | [diff] [blame] | 377 | func (c *configImpl) NinjaArgs() []string { | 
| Dan Willemsen | e0879fc | 2017-08-04 15:06:27 -0700 | [diff] [blame] | 378 | if c.skipMake { | 
|  | 379 | return c.arguments | 
|  | 380 | } | 
| Dan Willemsen | 1e70446 | 2016-08-21 15:17:17 -0700 | [diff] [blame] | 381 | return c.ninjaArgs | 
|  | 382 | } | 
|  | 383 |  | 
|  | 384 | func (c *configImpl) SoongOutDir() string { | 
|  | 385 | return filepath.Join(c.OutDir(), "soong") | 
|  | 386 | } | 
|  | 387 |  | 
| Jeff Gaston | efc1b41 | 2017-03-29 17:29:06 -0700 | [diff] [blame] | 388 | func (c *configImpl) TempDir() string { | 
|  | 389 | return shared.TempDirForOutDir(c.SoongOutDir()) | 
|  | 390 | } | 
|  | 391 |  | 
| Jeff Gaston | b64fc1c | 2017-08-04 12:30:12 -0700 | [diff] [blame] | 392 | func (c *configImpl) FileListDir() string { | 
|  | 393 | return filepath.Join(c.OutDir(), ".module_paths") | 
|  | 394 | } | 
|  | 395 |  | 
| Dan Willemsen | 1e70446 | 2016-08-21 15:17:17 -0700 | [diff] [blame] | 396 | func (c *configImpl) KatiSuffix() string { | 
|  | 397 | if c.katiSuffix != "" { | 
|  | 398 | return c.katiSuffix | 
|  | 399 | } | 
|  | 400 | panic("SetKatiSuffix has not been called") | 
|  | 401 | } | 
|  | 402 |  | 
| Colin Cross | 3719349 | 2017-11-16 17:55:00 -0800 | [diff] [blame] | 403 | // Checkbuild returns true if "checkbuild" was one of the build goals, which means that the | 
|  | 404 | // user is interested in additional checks at the expense of build time. | 
|  | 405 | func (c *configImpl) Checkbuild() bool { | 
|  | 406 | return c.checkbuild | 
|  | 407 | } | 
|  | 408 |  | 
| Dan Willemsen | 8a073a8 | 2017-02-04 17:30:44 -0800 | [diff] [blame] | 409 | func (c *configImpl) Dist() bool { | 
|  | 410 | return c.dist | 
|  | 411 | } | 
|  | 412 |  | 
| Dan Willemsen | 1e70446 | 2016-08-21 15:17:17 -0700 | [diff] [blame] | 413 | func (c *configImpl) IsVerbose() bool { | 
|  | 414 | return c.verbose | 
|  | 415 | } | 
|  | 416 |  | 
| Dan Willemsen | e0879fc | 2017-08-04 15:06:27 -0700 | [diff] [blame] | 417 | func (c *configImpl) SkipMake() bool { | 
|  | 418 | return c.skipMake | 
|  | 419 | } | 
|  | 420 |  | 
| Dan Willemsen | 1e70446 | 2016-08-21 15:17:17 -0700 | [diff] [blame] | 421 | func (c *configImpl) TargetProduct() string { | 
|  | 422 | if v, ok := c.environ.Get("TARGET_PRODUCT"); ok { | 
|  | 423 | return v | 
|  | 424 | } | 
|  | 425 | panic("TARGET_PRODUCT is not defined") | 
|  | 426 | } | 
|  | 427 |  | 
| Dan Willemsen | 02781d5 | 2017-05-12 19:28:13 -0700 | [diff] [blame] | 428 | func (c *configImpl) TargetDevice() string { | 
|  | 429 | return c.targetDevice | 
|  | 430 | } | 
|  | 431 |  | 
|  | 432 | func (c *configImpl) SetTargetDevice(device string) { | 
|  | 433 | c.targetDevice = device | 
|  | 434 | } | 
|  | 435 |  | 
|  | 436 | func (c *configImpl) TargetBuildVariant() string { | 
|  | 437 | if v, ok := c.environ.Get("TARGET_BUILD_VARIANT"); ok { | 
|  | 438 | return v | 
|  | 439 | } | 
|  | 440 | panic("TARGET_BUILD_VARIANT is not defined") | 
|  | 441 | } | 
|  | 442 |  | 
| Dan Willemsen | 1e70446 | 2016-08-21 15:17:17 -0700 | [diff] [blame] | 443 | func (c *configImpl) KatiArgs() []string { | 
|  | 444 | return c.katiArgs | 
|  | 445 | } | 
|  | 446 |  | 
|  | 447 | func (c *configImpl) Parallel() int { | 
|  | 448 | return c.parallel | 
|  | 449 | } | 
|  | 450 |  | 
|  | 451 | func (c *configImpl) UseGoma() bool { | 
|  | 452 | if v, ok := c.environ.Get("USE_GOMA"); ok { | 
|  | 453 | v = strings.TrimSpace(v) | 
|  | 454 | if v != "" && v != "false" { | 
|  | 455 | return true | 
|  | 456 | } | 
|  | 457 | } | 
|  | 458 | return false | 
|  | 459 | } | 
|  | 460 |  | 
|  | 461 | // RemoteParallel controls how many remote jobs (i.e., commands which contain | 
| Jeff Gaston | efc1b41 | 2017-03-29 17:29:06 -0700 | [diff] [blame] | 462 | // gomacc) are run in parallel.  Note the parallelism of all other jobs is | 
| Dan Willemsen | 1e70446 | 2016-08-21 15:17:17 -0700 | [diff] [blame] | 463 | // still limited by Parallel() | 
|  | 464 | func (c *configImpl) RemoteParallel() int { | 
|  | 465 | if v, ok := c.environ.Get("NINJA_REMOTE_NUM_JOBS"); ok { | 
|  | 466 | if i, err := strconv.Atoi(v); err == nil { | 
|  | 467 | return i | 
|  | 468 | } | 
|  | 469 | } | 
|  | 470 | return 500 | 
|  | 471 | } | 
|  | 472 |  | 
|  | 473 | func (c *configImpl) SetKatiArgs(args []string) { | 
|  | 474 | c.katiArgs = args | 
|  | 475 | } | 
|  | 476 |  | 
|  | 477 | func (c *configImpl) SetNinjaArgs(args []string) { | 
|  | 478 | c.ninjaArgs = args | 
|  | 479 | } | 
|  | 480 |  | 
|  | 481 | func (c *configImpl) SetKatiSuffix(suffix string) { | 
|  | 482 | c.katiSuffix = suffix | 
|  | 483 | } | 
|  | 484 |  | 
| Dan Willemsen | e0879fc | 2017-08-04 15:06:27 -0700 | [diff] [blame] | 485 | func (c *configImpl) LastKatiSuffixFile() string { | 
|  | 486 | return filepath.Join(c.OutDir(), "last_kati_suffix") | 
|  | 487 | } | 
|  | 488 |  | 
|  | 489 | func (c *configImpl) HasKatiSuffix() bool { | 
|  | 490 | return c.katiSuffix != "" | 
|  | 491 | } | 
|  | 492 |  | 
| Dan Willemsen | 1e70446 | 2016-08-21 15:17:17 -0700 | [diff] [blame] | 493 | func (c *configImpl) KatiEnvFile() string { | 
|  | 494 | return filepath.Join(c.OutDir(), "env"+c.KatiSuffix()+".sh") | 
|  | 495 | } | 
|  | 496 |  | 
|  | 497 | func (c *configImpl) KatiNinjaFile() string { | 
|  | 498 | return filepath.Join(c.OutDir(), "build"+c.KatiSuffix()+".ninja") | 
|  | 499 | } | 
|  | 500 |  | 
|  | 501 | func (c *configImpl) SoongNinjaFile() string { | 
|  | 502 | return filepath.Join(c.SoongOutDir(), "build.ninja") | 
|  | 503 | } | 
|  | 504 |  | 
|  | 505 | func (c *configImpl) CombinedNinjaFile() string { | 
| Dan Willemsen | e0879fc | 2017-08-04 15:06:27 -0700 | [diff] [blame] | 506 | if c.katiSuffix == "" { | 
|  | 507 | return filepath.Join(c.OutDir(), "combined.ninja") | 
|  | 508 | } | 
| Dan Willemsen | 1e70446 | 2016-08-21 15:17:17 -0700 | [diff] [blame] | 509 | return filepath.Join(c.OutDir(), "combined"+c.KatiSuffix()+".ninja") | 
|  | 510 | } | 
|  | 511 |  | 
|  | 512 | func (c *configImpl) SoongAndroidMk() string { | 
|  | 513 | return filepath.Join(c.SoongOutDir(), "Android-"+c.TargetProduct()+".mk") | 
|  | 514 | } | 
|  | 515 |  | 
|  | 516 | func (c *configImpl) SoongMakeVarsMk() string { | 
|  | 517 | return filepath.Join(c.SoongOutDir(), "make_vars-"+c.TargetProduct()+".mk") | 
|  | 518 | } | 
|  | 519 |  | 
| Dan Willemsen | f052f78 | 2017-05-18 15:29:04 -0700 | [diff] [blame] | 520 | func (c *configImpl) ProductOut() string { | 
| Dan Willemsen | 4dc4e14 | 2017-09-08 14:35:43 -0700 | [diff] [blame] | 521 | return filepath.Join(c.OutDir(), "target", "product", c.TargetDevice()) | 
| Dan Willemsen | f052f78 | 2017-05-18 15:29:04 -0700 | [diff] [blame] | 522 | } | 
|  | 523 |  | 
| Dan Willemsen | 02781d5 | 2017-05-12 19:28:13 -0700 | [diff] [blame] | 524 | func (c *configImpl) DevicePreviousProductConfig() string { | 
| Dan Willemsen | f052f78 | 2017-05-18 15:29:04 -0700 | [diff] [blame] | 525 | return filepath.Join(c.ProductOut(), "previous_build_config.mk") | 
|  | 526 | } | 
|  | 527 |  | 
|  | 528 | func (c *configImpl) hostOutRoot() string { | 
| Dan Willemsen | 4dc4e14 | 2017-09-08 14:35:43 -0700 | [diff] [blame] | 529 | return filepath.Join(c.OutDir(), "host") | 
| Dan Willemsen | f052f78 | 2017-05-18 15:29:04 -0700 | [diff] [blame] | 530 | } | 
|  | 531 |  | 
|  | 532 | func (c *configImpl) HostOut() string { | 
|  | 533 | return filepath.Join(c.hostOutRoot(), c.HostPrebuiltTag()) | 
|  | 534 | } | 
|  | 535 |  | 
|  | 536 | // This probably needs to be multi-valued, so not exporting it for now | 
|  | 537 | func (c *configImpl) hostCrossOut() string { | 
|  | 538 | if runtime.GOOS == "linux" { | 
|  | 539 | return filepath.Join(c.hostOutRoot(), "windows-x86") | 
|  | 540 | } else { | 
|  | 541 | return "" | 
|  | 542 | } | 
| Dan Willemsen | 02781d5 | 2017-05-12 19:28:13 -0700 | [diff] [blame] | 543 | } | 
|  | 544 |  | 
| Dan Willemsen | 1e70446 | 2016-08-21 15:17:17 -0700 | [diff] [blame] | 545 | func (c *configImpl) HostPrebuiltTag() string { | 
|  | 546 | if runtime.GOOS == "linux" { | 
|  | 547 | return "linux-x86" | 
|  | 548 | } else if runtime.GOOS == "darwin" { | 
|  | 549 | return "darwin-x86" | 
|  | 550 | } else { | 
|  | 551 | panic("Unsupported OS") | 
|  | 552 | } | 
|  | 553 | } | 
| Dan Willemsen | f173d59 | 2017-04-27 14:28:00 -0700 | [diff] [blame] | 554 |  | 
| Dan Willemsen | 8122bd5 | 2017-10-12 20:20:41 -0700 | [diff] [blame] | 555 | func (c *configImpl) PrebuiltBuildTool(name string) string { | 
| Dan Willemsen | f173d59 | 2017-04-27 14:28:00 -0700 | [diff] [blame] | 556 | if v, ok := c.environ.Get("SANITIZE_HOST"); ok { | 
|  | 557 | if sanitize := strings.Fields(v); inList("address", sanitize) { | 
| Dan Willemsen | 8122bd5 | 2017-10-12 20:20:41 -0700 | [diff] [blame] | 558 | asan := filepath.Join("prebuilts/build-tools", c.HostPrebuiltTag(), "asan/bin", name) | 
|  | 559 | if _, err := os.Stat(asan); err == nil { | 
|  | 560 | return asan | 
|  | 561 | } | 
| Dan Willemsen | f173d59 | 2017-04-27 14:28:00 -0700 | [diff] [blame] | 562 | } | 
|  | 563 | } | 
|  | 564 | return filepath.Join("prebuilts/build-tools", c.HostPrebuiltTag(), "bin", name) | 
|  | 565 | } | 
| Dan Willemsen | 3d60b11 | 2018-04-04 22:25:56 -0700 | [diff] [blame] | 566 |  | 
|  | 567 | func (c *configImpl) SetBuildBrokenDupRules(val bool) { | 
|  | 568 | c.brokenDupRules = val | 
|  | 569 | } | 
|  | 570 |  | 
|  | 571 | func (c *configImpl) BuildBrokenDupRules() bool { | 
|  | 572 | return c.brokenDupRules | 
|  | 573 | } | 
| Dan Willemsen | 6ab79db | 2018-05-02 00:06:28 -0700 | [diff] [blame] | 574 |  | 
|  | 575 | func (c *configImpl) SetTargetDeviceDir(dir string) { | 
|  | 576 | c.targetDeviceDir = dir | 
|  | 577 | } | 
|  | 578 |  | 
|  | 579 | func (c *configImpl) TargetDeviceDir() string { | 
|  | 580 | return c.targetDeviceDir | 
|  | 581 | } |