blob: 72865700643d878f8b1a8ae1e32e344d76ad69ff [file] [log] [blame]
Dan Willemsen1e704462016-08-21 15:17:17 -07001// 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
15package build
16
17import (
Cole Faust583dfb42023-09-28 13:56:30 -070018 "fmt"
Dan Willemsendb8457c2017-05-12 16:38:17 -070019 "io/ioutil"
Dan Willemsen1e704462016-08-21 15:17:17 -070020 "os"
Dan Willemsen1e704462016-08-21 15:17:17 -070021 "path/filepath"
Dan Willemsen80d72612022-04-20 21:45:00 -070022 "sync"
Dan Willemsen1e704462016-08-21 15:17:17 -070023 "text/template"
Ido Ben-Hurba3afa62024-09-09 03:12:57 +030024 "time"
Colin Cross74cda722020-01-16 15:25:50 -080025
Peter Collingbourneb805c612024-03-14 21:59:57 -070026 "android/soong/elf"
Colin Cross74cda722020-01-16 15:25:50 -080027 "android/soong/ui/metrics"
Dan Willemsen1e704462016-08-21 15:17:17 -070028)
29
Jingwen Chencda22c92020-11-23 00:22:30 -050030// SetupOutDir ensures the out directory exists, and has the proper files to
31// prevent kati from recursing into it.
Dan Willemsen1e704462016-08-21 15:17:17 -070032func SetupOutDir(ctx Context, config Config) {
33 ensureEmptyFileExists(ctx, filepath.Join(config.OutDir(), "Android.mk"))
34 ensureEmptyFileExists(ctx, filepath.Join(config.OutDir(), "CleanSpec.mk"))
Cole Faust583dfb42023-09-28 13:56:30 -070035 ensureEmptyDirectoriesExist(ctx, config.TempDir())
Anton Hansson17fc5a02021-06-18 16:37:14 +010036
37 // Potentially write a marker file for whether kati is enabled. This is used by soong_build to
38 // potentially run the AndroidMk singleton and postinstall commands.
39 // Note that the absence of the file does not not preclude running Kati for product
40 // configuration purposes.
41 katiEnabledMarker := filepath.Join(config.SoongOutDir(), ".soong.kati_enabled")
42 if config.SkipKatiNinja() {
43 os.Remove(katiEnabledMarker)
44 // Note that we can not remove the file for SkipKati builds yet -- some continuous builds
45 // --skip-make builds rely on kati targets being defined.
46 } else if !config.SkipKati() {
47 ensureEmptyFileExists(ctx, katiEnabledMarker)
Dan Willemsene0879fc2017-08-04 15:06:27 -070048 }
Anton Hansson17fc5a02021-06-18 16:37:14 +010049
Dan Willemsen1e704462016-08-21 15:17:17 -070050 // The ninja_build file is used by our buildbots to understand that the output
51 // can be parsed as ninja output.
52 ensureEmptyFileExists(ctx, filepath.Join(config.OutDir(), "ninja_build"))
Jeff Gastonb64fc1c2017-08-04 12:30:12 -070053 ensureEmptyFileExists(ctx, filepath.Join(config.OutDir(), ".out-dir"))
Colin Cross28f527c2019-11-26 16:19:04 -080054
55 if buildDateTimeFile, ok := config.environ.Get("BUILD_DATETIME_FILE"); ok {
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +000056 err := ioutil.WriteFile(buildDateTimeFile, []byte(config.buildDateTime), 0666) // a+rw
Colin Cross28f527c2019-11-26 16:19:04 -080057 if err != nil {
58 ctx.Fatalln("Failed to write BUILD_DATETIME to file:", err)
59 }
60 } else {
61 ctx.Fatalln("Missing BUILD_DATETIME_FILE")
62 }
Cole Faust583dfb42023-09-28 13:56:30 -070063
64 // BUILD_NUMBER should be set to the source control value that
65 // represents the current state of the source code. E.g., a
66 // perforce changelist number or a git hash. Can be an arbitrary string
67 // (to allow for source control that uses something other than numbers),
68 // but must be a single word and a valid file name.
69 //
Ido Ben-Hurba3afa62024-09-09 03:12:57 +030070 // If no BUILD_NUMBER is set, create a useful "I am an engineering build
71 // from this date/time" value. Make it start with a non-digit so that
72 // anyone trying to parse it as an integer will probably get "0".
Cole Faust583dfb42023-09-28 13:56:30 -070073 buildNumber, ok := config.environ.Get("BUILD_NUMBER")
74 if ok {
75 writeValueIfChanged(ctx, config, config.OutDir(), "file_name_tag.txt", buildNumber)
76 } else {
77 var username string
78 if username, ok = config.environ.Get("BUILD_USERNAME"); !ok {
79 ctx.Fatalln("Missing BUILD_USERNAME")
80 }
Ido Ben-Hurba3afa62024-09-09 03:12:57 +030081 buildNumber = fmt.Sprintf("eng.%.6s.%s", username, time.Now().Format("20060102.150405" /* YYYYMMDD.HHMMSS */))
Cole Faust583dfb42023-09-28 13:56:30 -070082 writeValueIfChanged(ctx, config, config.OutDir(), "file_name_tag.txt", username)
83 }
84 // Write the build number to a file so it can be read back in
85 // without changing the command line every time. Avoids rebuilds
86 // when using ninja.
87 writeValueIfChanged(ctx, config, config.SoongOutDir(), "build_number.txt", buildNumber)
Dan Willemsen1e704462016-08-21 15:17:17 -070088}
89
90var combinedBuildNinjaTemplate = template.Must(template.New("combined").Parse(`
91builddir = {{.OutDir}}
Colin Cross8b8bec32019-11-15 13:18:43 -080092{{if .UseRemoteBuild }}pool local_pool
Dan Willemsen29971232018-09-26 14:58:30 -070093 depth = {{.Parallel}}
Colin Cross8b8bec32019-11-15 13:18:43 -080094{{end -}}
95pool highmem_pool
96 depth = {{.HighmemParallel}}
Anton Hansson0b55bdb2021-06-04 10:08:08 +010097{{if and (not .SkipKatiNinja) .HasKatiSuffix}}subninja {{.KatiBuildNinjaFile}}
Dan Willemsenfb1271a2018-09-26 15:00:42 -070098subninja {{.KatiPackageNinjaFile}}
Dan Willemsene0879fc2017-08-04 15:06:27 -070099{{end -}}
Dan Willemsenfb1271a2018-09-26 15:00:42 -0700100subninja {{.SoongNinjaFile}}
Dan Willemsen1e704462016-08-21 15:17:17 -0700101`))
102
103func createCombinedBuildNinjaFile(ctx Context, config Config) {
Anton Hansson0b55bdb2021-06-04 10:08:08 +0100104 // If we're in SkipKati mode but want to run kati ninja, skip creating this file if it already exists
105 if config.SkipKati() && !config.SkipKatiNinja() {
Dan Willemsene0879fc2017-08-04 15:06:27 -0700106 if _, err := os.Stat(config.CombinedNinjaFile()); err == nil || !os.IsNotExist(err) {
107 return
108 }
109 }
110
Dan Willemsen1e704462016-08-21 15:17:17 -0700111 file, err := os.Create(config.CombinedNinjaFile())
112 if err != nil {
113 ctx.Fatalln("Failed to create combined ninja file:", err)
114 }
115 defer file.Close()
116
117 if err := combinedBuildNinjaTemplate.Execute(file, config); err != nil {
118 ctx.Fatalln("Failed to write combined ninja file:", err)
119 }
120}
121
Sam Delmericod9a34352022-11-15 17:27:21 -0500122// These are bitmasks which can be used to check whether various flags are set
Dan Willemsen1e704462016-08-21 15:17:17 -0700123const (
Anton Hansson5a7861a2021-06-04 10:09:01 +0100124 _ = iota
125 // Whether to run the kati config step.
126 RunProductConfig = 1 << iota
127 // Whether to run soong to generate a ninja file.
128 RunSoong = 1 << iota
129 // Whether to run kati to generate a ninja file.
130 RunKati = 1 << iota
Anton Hansson0b55bdb2021-06-04 10:08:08 +0100131 // Whether to include the kati-generated ninja file in the combined ninja.
132 RunKatiNinja = 1 << iota
Anton Hansson5a7861a2021-06-04 10:09:01 +0100133 // Whether to run ninja on the combined ninja.
Joe Onorato7f29a662023-02-23 15:47:06 -0800134 RunNinja = 1 << iota
135 RunDistActions = 1 << iota
136 RunBuildTests = 1 << iota
Dan Willemsen1e704462016-08-21 15:17:17 -0700137)
138
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000139// checkProblematicFiles fails the build if existing Android.mk or CleanSpec.mk files are found at the root of the tree.
Anton Hanssonecf0f102018-09-19 22:14:17 +0100140func checkProblematicFiles(ctx Context) {
141 files := []string{"Android.mk", "CleanSpec.mk"}
142 for _, file := range files {
143 if _, err := os.Stat(file); !os.IsNotExist(err) {
144 absolute := absPath(ctx, file)
145 ctx.Printf("Found %s in tree root. This file needs to be removed to build.\n", file)
146 ctx.Fatalf(" rm %s\n", absolute)
147 }
148 }
149}
150
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000151// checkCaseSensitivity issues a warning if a case-insensitive file system is being used.
Dan Willemsendb8457c2017-05-12 16:38:17 -0700152func checkCaseSensitivity(ctx Context, config Config) {
153 outDir := config.OutDir()
154 lowerCase := filepath.Join(outDir, "casecheck.txt")
155 upperCase := filepath.Join(outDir, "CaseCheck.txt")
156 lowerData := "a"
157 upperData := "B"
158
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000159 if err := ioutil.WriteFile(lowerCase, []byte(lowerData), 0666); err != nil { // a+rw
Dan Willemsendb8457c2017-05-12 16:38:17 -0700160 ctx.Fatalln("Failed to check case sensitivity:", err)
161 }
162
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000163 if err := ioutil.WriteFile(upperCase, []byte(upperData), 0666); err != nil { // a+rw
Dan Willemsendb8457c2017-05-12 16:38:17 -0700164 ctx.Fatalln("Failed to check case sensitivity:", err)
165 }
166
167 res, err := ioutil.ReadFile(lowerCase)
168 if err != nil {
169 ctx.Fatalln("Failed to check case sensitivity:", err)
170 }
171
172 if string(res) != lowerData {
173 ctx.Println("************************************************************")
174 ctx.Println("You are building on a case-insensitive filesystem.")
175 ctx.Println("Please move your source tree to a case-sensitive filesystem.")
176 ctx.Println("************************************************************")
177 ctx.Fatalln("Case-insensitive filesystems not supported")
178 }
179}
180
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000181// help prints a help/usage message, via the build/make/help.sh script.
182func help(ctx Context, config Config) {
Jeff Gastondf4a0812017-05-30 20:11:20 -0700183 cmd := Command(ctx, config, "help.sh", "build/make/help.sh")
Dan Willemsenb2e6c2e2017-07-13 17:24:44 -0700184 cmd.Sandbox = dumpvarsSandbox
Dan Willemsenb82471a2018-05-17 16:37:09 -0700185 cmd.RunAndPrintOrFatal()
Dan Willemsen02781d52017-05-12 19:28:13 -0700186}
187
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000188// checkRAM warns if there probably isn't enough RAM to complete a build.
189func checkRAM(ctx Context, config Config) {
Dan Willemsen570a2922020-05-26 23:02:29 -0700190 if totalRAM := config.TotalRAM(); totalRAM != 0 {
191 ram := float32(totalRAM) / (1024 * 1024 * 1024)
192 ctx.Verbosef("Total RAM: %.3vGB", ram)
193
194 if ram <= 16 {
195 ctx.Println("************************************************************")
196 ctx.Printf("You are building on a machine with %.3vGB of RAM\n", ram)
197 ctx.Println("")
198 ctx.Println("The minimum required amount of free memory is around 16GB,")
199 ctx.Println("and even with that, some configurations may not work.")
200 ctx.Println("")
201 ctx.Println("If you run into segfaults or other errors, try reducing your")
202 ctx.Println("-j value.")
203 ctx.Println("************************************************************")
204 } else if ram <= float32(config.Parallel()) {
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000205 // Want at least 1GB of RAM per job.
Dan Willemsen570a2922020-05-26 23:02:29 -0700206 ctx.Printf("Warning: high -j%d count compared to %.3vGB of RAM", config.Parallel(), ram)
207 ctx.Println("If you run into segfaults or other errors, try a lower -j value")
208 }
209 }
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000210}
211
Taylor Santiago3c16e612024-05-30 14:41:31 -0700212func abfsBuildStarted(ctx Context, config Config) {
213 abfsBox := config.PrebuiltBuildTool("abfsbox")
214 cmdArgs := []string{"build-started", "--"}
215 cmdArgs = append(cmdArgs, config.Arguments()...)
216 cmd := Command(ctx, config, "abfsbox", abfsBox, cmdArgs...)
217 cmd.Sandbox = noSandbox
218 cmd.RunAndPrintOrFatal()
219}
220
221func abfsBuildFinished(ctx Context, config Config, finished bool) {
222 var errMsg string
223 if !finished {
224 errMsg = "build was interrupted"
225 }
226 abfsBox := config.PrebuiltBuildTool("abfsbox")
227 cmdArgs := []string{"build-finished", "-e", errMsg, "--"}
228 cmdArgs = append(cmdArgs, config.Arguments()...)
229 cmd := Command(ctx, config, "abfsbox", abfsBox, cmdArgs...)
230 cmd.RunAndPrintOrFatal()
231}
232
Usta Shresthadb46a9b2022-07-11 11:29:56 -0400233// Build the tree. Various flags in `config` govern which components of
234// the build to run.
Anton Hansson5a7861a2021-06-04 10:09:01 +0100235func Build(ctx Context, config Config) {
Taylor Santiago3c16e612024-05-30 14:41:31 -0700236 done := false
237 if config.UseABFS() {
238 abfsBuildStarted(ctx, config)
239 defer func() {
240 abfsBuildFinished(ctx, config, done)
241 }()
242 }
243
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000244 ctx.Verboseln("Starting build with args:", config.Arguments())
245 ctx.Verboseln("Environment:", config.Environment().Environ())
Dan Willemsen1e704462016-08-21 15:17:17 -0700246
Colin Cross74cda722020-01-16 15:25:50 -0800247 ctx.BeginTrace(metrics.Total, "total")
248 defer ctx.EndTrace()
249
Dan Willemsen1e704462016-08-21 15:17:17 -0700250 if inList("help", config.Arguments()) {
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000251 help(ctx, config)
Dan Willemsen0b73b4b2017-05-12 19:28:13 -0700252 return
Dan Willemsen1e704462016-08-21 15:17:17 -0700253 }
254
Jeff Gaston3615fe82017-05-24 13:14:34 -0700255 // Make sure that no other Soong process is running with the same output directory
256 buildLock := BecomeSingletonOrFail(ctx, config)
257 defer buildLock.Unlock()
258
Usta Shrestha675564d2022-08-09 18:03:23 -0400259 logArgsOtherThan := func(specialTargets ...string) {
260 var ignored []string
261 for _, a := range config.Arguments() {
262 if !inList(a, specialTargets) {
263 ignored = append(ignored, a)
264 }
265 }
266 if len(ignored) > 0 {
267 ctx.Printf("ignoring arguments %q", ignored)
268 }
269 }
270
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000271 if inList("clean", config.Arguments()) || inList("clobber", config.Arguments()) {
Usta Shrestha675564d2022-08-09 18:03:23 -0400272 logArgsOtherThan("clean", "clobber")
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000273 clean(ctx, config)
274 return
275 }
276
Dan Willemsen80d72612022-04-20 21:45:00 -0700277 defer waitForDist(ctx)
278
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000279 // checkProblematicFiles aborts the build if Android.mk or CleanSpec.mk are found at the root of the tree.
Anton Hanssonecf0f102018-09-19 22:14:17 +0100280 checkProblematicFiles(ctx)
281
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000282 checkRAM(ctx, config)
283
Dan Willemsen1e704462016-08-21 15:17:17 -0700284 SetupOutDir(ctx, config)
285
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000286 // checkCaseSensitivity issues a warning if a case-insensitive file system is being used.
Dan Willemsendb8457c2017-05-12 16:38:17 -0700287 checkCaseSensitivity(ctx, config)
288
Dan Willemsen18490112018-05-25 16:30:04 -0700289 SetupPath(ctx, config)
290
usta6fffdd52022-09-19 13:16:18 -0400291 what := evaluateWhatToRun(config, ctx.Verboseln)
Lukacs T. Berkia1b93722021-09-02 17:23:06 +0200292
Yoshisato Yanagisawa2cb0e5d2019-01-10 10:14:16 +0900293 if config.StartGoma() {
Yoshisato Yanagisawa2cb0e5d2019-01-10 10:14:16 +0900294 startGoma(ctx, config)
295 }
296
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400297 rbeCh := make(chan bool)
Colin Crosse7151f92023-11-28 14:18:12 -0800298 var rbePanic any
Ramy Medhatbbf25672019-07-17 12:30:04 +0000299 if config.StartRBE() {
Kousik Kumar4c180ad2022-05-27 07:48:37 -0400300 cleanupRBELogsDir(ctx, config)
Colin Crosse7151f92023-11-28 14:18:12 -0800301 checkRBERequirements(ctx, config)
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400302 go func() {
Colin Crosse7151f92023-11-28 14:18:12 -0800303 defer func() {
304 rbePanic = recover()
305 close(rbeCh)
306 }()
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400307 startRBE(ctx, config)
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400308 }()
Kousik Kumara1d8fa92022-03-18 02:50:31 -0400309 defer DumpRBEMetrics(ctx, config, filepath.Join(config.LogsDir(), "rbe_metrics.pb"))
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400310 } else {
311 close(rbeCh)
Ramy Medhatbbf25672019-07-17 12:30:04 +0000312 }
313
Anton Hansson5a7861a2021-06-04 10:09:01 +0100314 if what&RunProductConfig != 0 {
Dan Willemsen1e704462016-08-21 15:17:17 -0700315 runMakeProductConfig(ctx, config)
316 }
317
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000318 // Everything below here depends on product config.
319
Colin Cross806fd942019-05-03 13:35:58 -0700320 if inList("installclean", config.Arguments()) ||
321 inList("install-clean", config.Arguments()) {
Usta Shrestha675564d2022-08-09 18:03:23 -0400322 logArgsOtherThan("installclean", "install-clean")
Rupert Shuttleworth1f304e62020-11-24 14:13:41 +0000323 installClean(ctx, config)
Dan Willemsenf052f782017-05-18 15:29:04 -0700324 ctx.Println("Deleted images and staging directories.")
325 return
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000326 }
327
328 if inList("dataclean", config.Arguments()) ||
Colin Cross806fd942019-05-03 13:35:58 -0700329 inList("data-clean", config.Arguments()) {
Usta Shrestha675564d2022-08-09 18:03:23 -0400330 logArgsOtherThan("dataclean", "data-clean")
Rupert Shuttleworth1f304e62020-11-24 14:13:41 +0000331 dataClean(ctx, config)
Dan Willemsenf052f782017-05-18 15:29:04 -0700332 ctx.Println("Deleted data files.")
333 return
Alberto973e3fe332018-05-05 22:01:02 +0200334 } else if inList("deviceclean", config.Arguments()) {
335 deviceClean(ctx, config, what)
Harsh Shandilyabbed28c2019-05-12 05:48:29 +0530336 ctx.Println(config.ProductOut(), "removed.")
Alberto973e3fe332018-05-05 22:01:02 +0200337 return
Dan Willemsenf052f782017-05-18 15:29:04 -0700338 }
339
Anton Hansson5a7861a2021-06-04 10:09:01 +0100340 if what&RunSoong != 0 {
Dan Willemsen1e704462016-08-21 15:17:17 -0700341 runSoong(ctx, config)
342 }
343
Anton Hansson5a7861a2021-06-04 10:09:01 +0100344 if what&RunKati != 0 {
Dan Willemsen29971232018-09-26 14:58:30 -0700345 genKatiSuffix(ctx, config)
346 runKatiCleanSpec(ctx, config)
347 runKatiBuild(ctx, config)
Dan Willemsenfb1271a2018-09-26 15:00:42 -0700348 runKatiPackage(ctx, config)
Dan Willemsene0879fc2017-08-04 15:06:27 -0700349
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000350 ioutil.WriteFile(config.LastKatiSuffixFile(), []byte(config.KatiSuffix()), 0666) // a+rw
Anton Hansson0b55bdb2021-06-04 10:08:08 +0100351 } else if what&RunKatiNinja != 0 {
Dan Willemsene0879fc2017-08-04 15:06:27 -0700352 // Load last Kati Suffix if it exists
353 if katiSuffix, err := ioutil.ReadFile(config.LastKatiSuffixFile()); err == nil {
354 ctx.Verboseln("Loaded previous kati config:", string(katiSuffix))
355 config.SetKatiSuffix(string(katiSuffix))
356 }
Dan Willemsen1e704462016-08-21 15:17:17 -0700357 }
358
Colin Cross37193492017-11-16 17:55:00 -0800359 // Write combined ninja file
360 createCombinedBuildNinjaFile(ctx, config)
361
Colin Cross8ba7d472020-06-25 11:27:52 -0700362 distGzipFile(ctx, config, config.CombinedNinjaFile())
363
Colin Cross37193492017-11-16 17:55:00 -0800364 if what&RunBuildTests != 0 {
365 testForDanglingRules(ctx, config)
366 }
367
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400368 <-rbeCh
Colin Crosse7151f92023-11-28 14:18:12 -0800369 if rbePanic != nil {
370 // If there was a ctx.Fatal in startRBE, rethrow it.
371 panic(rbePanic)
372 }
373
Anton Hansson5a7861a2021-06-04 10:09:01 +0100374 if what&RunNinja != 0 {
375 if what&RunKati != 0 {
Dan Willemsene0879fc2017-08-04 15:06:27 -0700376 installCleanIfNecessary(ctx, config)
377 }
Lukacs T. Berkid1e3f1f2021-03-16 08:55:23 +0100378 runNinjaForBuild(ctx, config)
Peter Collingbourneb805c612024-03-14 21:59:57 -0700379 updateBuildIdDir(ctx, config)
Dan Willemsen1e704462016-08-21 15:17:17 -0700380 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800381
382 if what&RunDistActions != 0 {
383 runDistActions(ctx, config)
384 }
Taylor Santiago3c16e612024-05-30 14:41:31 -0700385 done = true
Dan Willemsen1e704462016-08-21 15:17:17 -0700386}
Colin Cross8ba7d472020-06-25 11:27:52 -0700387
Peter Collingbourneb805c612024-03-14 21:59:57 -0700388func updateBuildIdDir(ctx Context, config Config) {
389 ctx.BeginTrace(metrics.RunShutdownTool, "update_build_id_dir")
390 defer ctx.EndTrace()
391
392 symbolsDir := filepath.Join(config.ProductOut(), "symbols")
393 if err := elf.UpdateBuildIdDir(symbolsDir); err != nil {
394 ctx.Printf("failed to update %s/.build-id: %v", symbolsDir, err)
395 }
396}
397
usta6fffdd52022-09-19 13:16:18 -0400398func evaluateWhatToRun(config Config, verboseln func(v ...interface{})) int {
399 //evaluate what to run
Joe Onorato7f29a662023-02-23 15:47:06 -0800400 what := 0
usta6fffdd52022-09-19 13:16:18 -0400401 if config.Checkbuild() {
402 what |= RunBuildTests
403 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800404 if !config.SkipConfig() {
405 what |= RunProductConfig
406 } else {
usta6fffdd52022-09-19 13:16:18 -0400407 verboseln("Skipping Config as requested")
usta6fffdd52022-09-19 13:16:18 -0400408 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800409 if !config.SkipSoong() {
410 what |= RunSoong
411 } else {
usta6fffdd52022-09-19 13:16:18 -0400412 verboseln("Skipping use of Soong as requested")
usta6fffdd52022-09-19 13:16:18 -0400413 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800414 if !config.SkipKati() {
415 what |= RunKati
416 } else {
417 verboseln("Skipping Kati as requested")
418 }
419 if !config.SkipKatiNinja() {
420 what |= RunKatiNinja
421 } else {
422 verboseln("Skipping use of Kati ninja as requested")
423 }
424 if !config.SkipNinja() {
425 what |= RunNinja
426 } else {
usta6fffdd52022-09-19 13:16:18 -0400427 verboseln("Skipping Ninja as requested")
usta6fffdd52022-09-19 13:16:18 -0400428 }
429
430 if !config.SoongBuildInvocationNeeded() {
431 // This means that the output of soong_build is not needed and thus it would
432 // run unnecessarily. In addition, if this code wasn't there invocations
Joe Onorato35f300d2024-10-21 15:02:44 -0700433 // with only special-cased target names would result in
usta6fffdd52022-09-19 13:16:18 -0400434 // passing Ninja the empty target list and it would then build the default
435 // targets which is not what the user asked for.
436 what = what &^ RunNinja
437 what = what &^ RunKati
438 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800439
440 if config.Dist() {
441 what |= RunDistActions
442 }
443
usta6fffdd52022-09-19 13:16:18 -0400444 return what
445}
446
Dan Willemsen80d72612022-04-20 21:45:00 -0700447var distWaitGroup sync.WaitGroup
448
449// waitForDist waits for all backgrounded distGzipFile and distFile writes to finish
450func waitForDist(ctx Context) {
451 ctx.BeginTrace("soong_ui", "dist")
452 defer ctx.EndTrace()
453
454 distWaitGroup.Wait()
455}
456
Colin Cross8ba7d472020-06-25 11:27:52 -0700457// distGzipFile writes a compressed copy of src to the distDir if dist is enabled. Failures
Dan Willemsen80d72612022-04-20 21:45:00 -0700458// are printed but non-fatal. Uses the distWaitGroup func for backgrounding (optimization).
Colin Cross8ba7d472020-06-25 11:27:52 -0700459func distGzipFile(ctx Context, config Config, src string, subDirs ...string) {
460 if !config.Dist() {
461 return
462 }
463
464 subDir := filepath.Join(subDirs...)
Rupert Shuttleworth3c9f5ac2020-12-10 11:32:38 +0000465 destDir := filepath.Join(config.RealDistDir(), "soong_ui", subDir)
Colin Cross8ba7d472020-06-25 11:27:52 -0700466
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000467 if err := os.MkdirAll(destDir, 0777); err != nil { // a+rwx
Colin Cross8ba7d472020-06-25 11:27:52 -0700468 ctx.Printf("failed to mkdir %s: %s", destDir, err.Error())
Colin Cross8ba7d472020-06-25 11:27:52 -0700469 }
470
Dan Willemsen80d72612022-04-20 21:45:00 -0700471 distWaitGroup.Add(1)
472 go func() {
473 defer distWaitGroup.Done()
474 if err := gzipFileToDir(src, destDir); err != nil {
475 ctx.Printf("failed to dist %s: %s", filepath.Base(src), err.Error())
476 }
477 }()
Colin Cross8ba7d472020-06-25 11:27:52 -0700478}
479
480// distFile writes a copy of src to the distDir if dist is enabled. Failures are printed but
Dan Willemsen80d72612022-04-20 21:45:00 -0700481// non-fatal. Uses the distWaitGroup func for backgrounding (optimization).
Colin Cross8ba7d472020-06-25 11:27:52 -0700482func distFile(ctx Context, config Config, src string, subDirs ...string) {
483 if !config.Dist() {
484 return
485 }
486
487 subDir := filepath.Join(subDirs...)
Rupert Shuttleworth3c9f5ac2020-12-10 11:32:38 +0000488 destDir := filepath.Join(config.RealDistDir(), "soong_ui", subDir)
Colin Cross8ba7d472020-06-25 11:27:52 -0700489
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000490 if err := os.MkdirAll(destDir, 0777); err != nil { // a+rwx
Colin Cross8ba7d472020-06-25 11:27:52 -0700491 ctx.Printf("failed to mkdir %s: %s", destDir, err.Error())
Colin Cross8ba7d472020-06-25 11:27:52 -0700492 }
493
Dan Willemsen80d72612022-04-20 21:45:00 -0700494 distWaitGroup.Add(1)
495 go func() {
496 defer distWaitGroup.Done()
497 if _, err := copyFile(src, filepath.Join(destDir, filepath.Base(src))); err != nil {
498 ctx.Printf("failed to dist %s: %s", filepath.Base(src), err.Error())
499 }
500 }()
Colin Cross8ba7d472020-06-25 11:27:52 -0700501}
Joe Onorato7f29a662023-02-23 15:47:06 -0800502
503// Actions to run on every build where 'dist' is in the actions.
504// Be careful, anything added here slows down EVERY CI build
505func runDistActions(ctx Context, config Config) {
506 runStagingSnapshot(ctx, config)
507}