blob: fee6c3195840cce002c4c5138c1c437863d37a1c [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"
Colin Cross74cda722020-01-16 15:25:50 -080024
Peter Collingbourneb805c612024-03-14 21:59:57 -070025 "android/soong/elf"
Colin Cross74cda722020-01-16 15:25:50 -080026 "android/soong/ui/metrics"
Dan Willemsen1e704462016-08-21 15:17:17 -070027)
28
Jingwen Chencda22c92020-11-23 00:22:30 -050029// SetupOutDir ensures the out directory exists, and has the proper files to
30// prevent kati from recursing into it.
Dan Willemsen1e704462016-08-21 15:17:17 -070031func SetupOutDir(ctx Context, config Config) {
32 ensureEmptyFileExists(ctx, filepath.Join(config.OutDir(), "Android.mk"))
33 ensureEmptyFileExists(ctx, filepath.Join(config.OutDir(), "CleanSpec.mk"))
Cole Faust583dfb42023-09-28 13:56:30 -070034 ensureEmptyDirectoriesExist(ctx, config.TempDir())
Anton Hansson17fc5a02021-06-18 16:37:14 +010035
36 // Potentially write a marker file for whether kati is enabled. This is used by soong_build to
37 // potentially run the AndroidMk singleton and postinstall commands.
38 // Note that the absence of the file does not not preclude running Kati for product
39 // configuration purposes.
40 katiEnabledMarker := filepath.Join(config.SoongOutDir(), ".soong.kati_enabled")
41 if config.SkipKatiNinja() {
42 os.Remove(katiEnabledMarker)
43 // Note that we can not remove the file for SkipKati builds yet -- some continuous builds
44 // --skip-make builds rely on kati targets being defined.
45 } else if !config.SkipKati() {
46 ensureEmptyFileExists(ctx, katiEnabledMarker)
Dan Willemsene0879fc2017-08-04 15:06:27 -070047 }
Anton Hansson17fc5a02021-06-18 16:37:14 +010048
Dan Willemsen1e704462016-08-21 15:17:17 -070049 // The ninja_build file is used by our buildbots to understand that the output
50 // can be parsed as ninja output.
51 ensureEmptyFileExists(ctx, filepath.Join(config.OutDir(), "ninja_build"))
Jeff Gastonb64fc1c2017-08-04 12:30:12 -070052 ensureEmptyFileExists(ctx, filepath.Join(config.OutDir(), ".out-dir"))
Colin Cross28f527c2019-11-26 16:19:04 -080053
54 if buildDateTimeFile, ok := config.environ.Get("BUILD_DATETIME_FILE"); ok {
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +000055 err := ioutil.WriteFile(buildDateTimeFile, []byte(config.buildDateTime), 0666) // a+rw
Colin Cross28f527c2019-11-26 16:19:04 -080056 if err != nil {
57 ctx.Fatalln("Failed to write BUILD_DATETIME to file:", err)
58 }
59 } else {
60 ctx.Fatalln("Missing BUILD_DATETIME_FILE")
61 }
Cole Faust583dfb42023-09-28 13:56:30 -070062
63 // BUILD_NUMBER should be set to the source control value that
64 // represents the current state of the source code. E.g., a
65 // perforce changelist number or a git hash. Can be an arbitrary string
66 // (to allow for source control that uses something other than numbers),
67 // but must be a single word and a valid file name.
68 //
Cole Faust1ae7b772024-06-12 18:08:44 -070069 // If no BUILD_NUMBER is set, create a useful "I am an engineering build"
70 // value. Make it start with a non-digit so that anyone trying to parse
71 // it as an integer will probably get "0". This value used to contain
72 // a timestamp, but now that more dependencies are tracked in order to
73 // reduce the importance of `m installclean`, changing it every build
74 // causes unnecessary rebuilds for local development.
Cole Faust583dfb42023-09-28 13:56:30 -070075 buildNumber, ok := config.environ.Get("BUILD_NUMBER")
76 if ok {
77 writeValueIfChanged(ctx, config, config.OutDir(), "file_name_tag.txt", buildNumber)
78 } else {
79 var username string
80 if username, ok = config.environ.Get("BUILD_USERNAME"); !ok {
81 ctx.Fatalln("Missing BUILD_USERNAME")
82 }
Cole Faust3ae36f42024-09-09 16:54:16 -070083 buildNumber = fmt.Sprintf("eng.%.6s", username)
Cole Faust583dfb42023-09-28 13:56:30 -070084 writeValueIfChanged(ctx, config, config.OutDir(), "file_name_tag.txt", username)
85 }
86 // Write the build number to a file so it can be read back in
87 // without changing the command line every time. Avoids rebuilds
88 // when using ninja.
89 writeValueIfChanged(ctx, config, config.SoongOutDir(), "build_number.txt", buildNumber)
Dan Willemsen1e704462016-08-21 15:17:17 -070090}
91
92var combinedBuildNinjaTemplate = template.Must(template.New("combined").Parse(`
93builddir = {{.OutDir}}
Colin Cross8b8bec32019-11-15 13:18:43 -080094{{if .UseRemoteBuild }}pool local_pool
Dan Willemsen29971232018-09-26 14:58:30 -070095 depth = {{.Parallel}}
Colin Cross8b8bec32019-11-15 13:18:43 -080096{{end -}}
97pool highmem_pool
98 depth = {{.HighmemParallel}}
Anton Hansson0b55bdb2021-06-04 10:08:08 +010099{{if and (not .SkipKatiNinja) .HasKatiSuffix}}subninja {{.KatiBuildNinjaFile}}
Dan Willemsenfb1271a2018-09-26 15:00:42 -0700100subninja {{.KatiPackageNinjaFile}}
Dan Willemsene0879fc2017-08-04 15:06:27 -0700101{{end -}}
Dan Willemsenfb1271a2018-09-26 15:00:42 -0700102subninja {{.SoongNinjaFile}}
Dan Willemsen1e704462016-08-21 15:17:17 -0700103`))
104
105func createCombinedBuildNinjaFile(ctx Context, config Config) {
Anton Hansson0b55bdb2021-06-04 10:08:08 +0100106 // If we're in SkipKati mode but want to run kati ninja, skip creating this file if it already exists
107 if config.SkipKati() && !config.SkipKatiNinja() {
Dan Willemsene0879fc2017-08-04 15:06:27 -0700108 if _, err := os.Stat(config.CombinedNinjaFile()); err == nil || !os.IsNotExist(err) {
109 return
110 }
111 }
112
Dan Willemsen1e704462016-08-21 15:17:17 -0700113 file, err := os.Create(config.CombinedNinjaFile())
114 if err != nil {
115 ctx.Fatalln("Failed to create combined ninja file:", err)
116 }
117 defer file.Close()
118
119 if err := combinedBuildNinjaTemplate.Execute(file, config); err != nil {
120 ctx.Fatalln("Failed to write combined ninja file:", err)
121 }
122}
123
Sam Delmericod9a34352022-11-15 17:27:21 -0500124// These are bitmasks which can be used to check whether various flags are set
Dan Willemsen1e704462016-08-21 15:17:17 -0700125const (
Anton Hansson5a7861a2021-06-04 10:09:01 +0100126 _ = iota
127 // Whether to run the kati config step.
128 RunProductConfig = 1 << iota
129 // Whether to run soong to generate a ninja file.
130 RunSoong = 1 << iota
131 // Whether to run kati to generate a ninja file.
132 RunKati = 1 << iota
Anton Hansson0b55bdb2021-06-04 10:08:08 +0100133 // Whether to include the kati-generated ninja file in the combined ninja.
134 RunKatiNinja = 1 << iota
Anton Hansson5a7861a2021-06-04 10:09:01 +0100135 // Whether to run ninja on the combined ninja.
Joe Onorato7f29a662023-02-23 15:47:06 -0800136 RunNinja = 1 << iota
137 RunDistActions = 1 << iota
138 RunBuildTests = 1 << iota
Dan Willemsen1e704462016-08-21 15:17:17 -0700139)
140
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000141// 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 +0100142func checkProblematicFiles(ctx Context) {
143 files := []string{"Android.mk", "CleanSpec.mk"}
144 for _, file := range files {
145 if _, err := os.Stat(file); !os.IsNotExist(err) {
146 absolute := absPath(ctx, file)
147 ctx.Printf("Found %s in tree root. This file needs to be removed to build.\n", file)
148 ctx.Fatalf(" rm %s\n", absolute)
149 }
150 }
151}
152
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000153// checkCaseSensitivity issues a warning if a case-insensitive file system is being used.
Dan Willemsendb8457c2017-05-12 16:38:17 -0700154func checkCaseSensitivity(ctx Context, config Config) {
155 outDir := config.OutDir()
156 lowerCase := filepath.Join(outDir, "casecheck.txt")
157 upperCase := filepath.Join(outDir, "CaseCheck.txt")
158 lowerData := "a"
159 upperData := "B"
160
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000161 if err := ioutil.WriteFile(lowerCase, []byte(lowerData), 0666); err != nil { // a+rw
Dan Willemsendb8457c2017-05-12 16:38:17 -0700162 ctx.Fatalln("Failed to check case sensitivity:", err)
163 }
164
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000165 if err := ioutil.WriteFile(upperCase, []byte(upperData), 0666); err != nil { // a+rw
Dan Willemsendb8457c2017-05-12 16:38:17 -0700166 ctx.Fatalln("Failed to check case sensitivity:", err)
167 }
168
169 res, err := ioutil.ReadFile(lowerCase)
170 if err != nil {
171 ctx.Fatalln("Failed to check case sensitivity:", err)
172 }
173
174 if string(res) != lowerData {
175 ctx.Println("************************************************************")
176 ctx.Println("You are building on a case-insensitive filesystem.")
177 ctx.Println("Please move your source tree to a case-sensitive filesystem.")
178 ctx.Println("************************************************************")
179 ctx.Fatalln("Case-insensitive filesystems not supported")
180 }
181}
182
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000183// help prints a help/usage message, via the build/make/help.sh script.
184func help(ctx Context, config Config) {
Jeff Gastondf4a0812017-05-30 20:11:20 -0700185 cmd := Command(ctx, config, "help.sh", "build/make/help.sh")
Dan Willemsenb2e6c2e2017-07-13 17:24:44 -0700186 cmd.Sandbox = dumpvarsSandbox
Dan Willemsenb82471a2018-05-17 16:37:09 -0700187 cmd.RunAndPrintOrFatal()
Dan Willemsen02781d52017-05-12 19:28:13 -0700188}
189
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000190// checkRAM warns if there probably isn't enough RAM to complete a build.
191func checkRAM(ctx Context, config Config) {
Dan Willemsen570a2922020-05-26 23:02:29 -0700192 if totalRAM := config.TotalRAM(); totalRAM != 0 {
193 ram := float32(totalRAM) / (1024 * 1024 * 1024)
194 ctx.Verbosef("Total RAM: %.3vGB", ram)
195
196 if ram <= 16 {
197 ctx.Println("************************************************************")
198 ctx.Printf("You are building on a machine with %.3vGB of RAM\n", ram)
199 ctx.Println("")
200 ctx.Println("The minimum required amount of free memory is around 16GB,")
201 ctx.Println("and even with that, some configurations may not work.")
202 ctx.Println("")
203 ctx.Println("If you run into segfaults or other errors, try reducing your")
204 ctx.Println("-j value.")
205 ctx.Println("************************************************************")
206 } else if ram <= float32(config.Parallel()) {
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000207 // Want at least 1GB of RAM per job.
Dan Willemsen570a2922020-05-26 23:02:29 -0700208 ctx.Printf("Warning: high -j%d count compared to %.3vGB of RAM", config.Parallel(), ram)
209 ctx.Println("If you run into segfaults or other errors, try a lower -j value")
210 }
211 }
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000212}
213
Taylor Santiago3c16e612024-05-30 14:41:31 -0700214func abfsBuildStarted(ctx Context, config Config) {
215 abfsBox := config.PrebuiltBuildTool("abfsbox")
216 cmdArgs := []string{"build-started", "--"}
217 cmdArgs = append(cmdArgs, config.Arguments()...)
218 cmd := Command(ctx, config, "abfsbox", abfsBox, cmdArgs...)
219 cmd.Sandbox = noSandbox
220 cmd.RunAndPrintOrFatal()
221}
222
223func abfsBuildFinished(ctx Context, config Config, finished bool) {
224 var errMsg string
225 if !finished {
226 errMsg = "build was interrupted"
227 }
228 abfsBox := config.PrebuiltBuildTool("abfsbox")
229 cmdArgs := []string{"build-finished", "-e", errMsg, "--"}
230 cmdArgs = append(cmdArgs, config.Arguments()...)
231 cmd := Command(ctx, config, "abfsbox", abfsBox, cmdArgs...)
232 cmd.RunAndPrintOrFatal()
233}
234
Usta Shresthadb46a9b2022-07-11 11:29:56 -0400235// Build the tree. Various flags in `config` govern which components of
236// the build to run.
Anton Hansson5a7861a2021-06-04 10:09:01 +0100237func Build(ctx Context, config Config) {
Taylor Santiago3c16e612024-05-30 14:41:31 -0700238 done := false
239 if config.UseABFS() {
240 abfsBuildStarted(ctx, config)
241 defer func() {
242 abfsBuildFinished(ctx, config, done)
243 }()
244 }
245
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000246 ctx.Verboseln("Starting build with args:", config.Arguments())
247 ctx.Verboseln("Environment:", config.Environment().Environ())
Dan Willemsen1e704462016-08-21 15:17:17 -0700248
Colin Cross74cda722020-01-16 15:25:50 -0800249 ctx.BeginTrace(metrics.Total, "total")
250 defer ctx.EndTrace()
251
Dan Willemsen1e704462016-08-21 15:17:17 -0700252 if inList("help", config.Arguments()) {
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000253 help(ctx, config)
Dan Willemsen0b73b4b2017-05-12 19:28:13 -0700254 return
Dan Willemsen1e704462016-08-21 15:17:17 -0700255 }
256
Jeff Gaston3615fe82017-05-24 13:14:34 -0700257 // Make sure that no other Soong process is running with the same output directory
258 buildLock := BecomeSingletonOrFail(ctx, config)
259 defer buildLock.Unlock()
260
Usta Shrestha675564d2022-08-09 18:03:23 -0400261 logArgsOtherThan := func(specialTargets ...string) {
262 var ignored []string
263 for _, a := range config.Arguments() {
264 if !inList(a, specialTargets) {
265 ignored = append(ignored, a)
266 }
267 }
268 if len(ignored) > 0 {
269 ctx.Printf("ignoring arguments %q", ignored)
270 }
271 }
272
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000273 if inList("clean", config.Arguments()) || inList("clobber", config.Arguments()) {
Usta Shrestha675564d2022-08-09 18:03:23 -0400274 logArgsOtherThan("clean", "clobber")
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000275 clean(ctx, config)
276 return
277 }
278
Dan Willemsen80d72612022-04-20 21:45:00 -0700279 defer waitForDist(ctx)
280
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000281 // 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 +0100282 checkProblematicFiles(ctx)
283
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000284 checkRAM(ctx, config)
285
Dan Willemsen1e704462016-08-21 15:17:17 -0700286 SetupOutDir(ctx, config)
287
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000288 // checkCaseSensitivity issues a warning if a case-insensitive file system is being used.
Dan Willemsendb8457c2017-05-12 16:38:17 -0700289 checkCaseSensitivity(ctx, config)
290
Dan Willemsen18490112018-05-25 16:30:04 -0700291 SetupPath(ctx, config)
292
usta6fffdd52022-09-19 13:16:18 -0400293 what := evaluateWhatToRun(config, ctx.Verboseln)
Lukacs T. Berkia1b93722021-09-02 17:23:06 +0200294
Yoshisato Yanagisawa2cb0e5d2019-01-10 10:14:16 +0900295 if config.StartGoma() {
Yoshisato Yanagisawa2cb0e5d2019-01-10 10:14:16 +0900296 startGoma(ctx, config)
297 }
298
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400299 rbeCh := make(chan bool)
Colin Crosse7151f92023-11-28 14:18:12 -0800300 var rbePanic any
Ramy Medhatbbf25672019-07-17 12:30:04 +0000301 if config.StartRBE() {
Kousik Kumar4c180ad2022-05-27 07:48:37 -0400302 cleanupRBELogsDir(ctx, config)
Colin Crosse7151f92023-11-28 14:18:12 -0800303 checkRBERequirements(ctx, config)
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400304 go func() {
Colin Crosse7151f92023-11-28 14:18:12 -0800305 defer func() {
306 rbePanic = recover()
307 close(rbeCh)
308 }()
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400309 startRBE(ctx, config)
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400310 }()
Kousik Kumara1d8fa92022-03-18 02:50:31 -0400311 defer DumpRBEMetrics(ctx, config, filepath.Join(config.LogsDir(), "rbe_metrics.pb"))
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400312 } else {
313 close(rbeCh)
Ramy Medhatbbf25672019-07-17 12:30:04 +0000314 }
315
Anton Hansson5a7861a2021-06-04 10:09:01 +0100316 if what&RunProductConfig != 0 {
Dan Willemsen1e704462016-08-21 15:17:17 -0700317 runMakeProductConfig(ctx, config)
318 }
319
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000320 // Everything below here depends on product config.
321
Colin Cross806fd942019-05-03 13:35:58 -0700322 if inList("installclean", config.Arguments()) ||
323 inList("install-clean", config.Arguments()) {
Usta Shrestha675564d2022-08-09 18:03:23 -0400324 logArgsOtherThan("installclean", "install-clean")
Rupert Shuttleworth1f304e62020-11-24 14:13:41 +0000325 installClean(ctx, config)
Dan Willemsenf052f782017-05-18 15:29:04 -0700326 ctx.Println("Deleted images and staging directories.")
327 return
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000328 }
329
330 if inList("dataclean", config.Arguments()) ||
Colin Cross806fd942019-05-03 13:35:58 -0700331 inList("data-clean", config.Arguments()) {
Usta Shrestha675564d2022-08-09 18:03:23 -0400332 logArgsOtherThan("dataclean", "data-clean")
Rupert Shuttleworth1f304e62020-11-24 14:13:41 +0000333 dataClean(ctx, config)
Dan Willemsenf052f782017-05-18 15:29:04 -0700334 ctx.Println("Deleted data files.")
335 return
Alberto973b51b562018-05-05 22:01:02 +0200336 } else if inList("deviceclean", config.Arguments()) {
337 deviceClean(ctx, config, what)
Harsh Shandilyacca7a842019-05-12 05:48:29 +0530338 ctx.Println(config.ProductOut(), "removed.")
Alberto973b51b562018-05-05 22:01:02 +0200339 return
Dan Willemsenf052f782017-05-18 15:29:04 -0700340 }
341
Anton Hansson5a7861a2021-06-04 10:09:01 +0100342 if what&RunSoong != 0 {
Dan Willemsen1e704462016-08-21 15:17:17 -0700343 runSoong(ctx, config)
344 }
345
Anton Hansson5a7861a2021-06-04 10:09:01 +0100346 if what&RunKati != 0 {
Dan Willemsen29971232018-09-26 14:58:30 -0700347 genKatiSuffix(ctx, config)
348 runKatiCleanSpec(ctx, config)
349 runKatiBuild(ctx, config)
Dan Willemsenfb1271a2018-09-26 15:00:42 -0700350 runKatiPackage(ctx, config)
Dan Willemsene0879fc2017-08-04 15:06:27 -0700351
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000352 ioutil.WriteFile(config.LastKatiSuffixFile(), []byte(config.KatiSuffix()), 0666) // a+rw
Anton Hansson0b55bdb2021-06-04 10:08:08 +0100353 } else if what&RunKatiNinja != 0 {
Dan Willemsene0879fc2017-08-04 15:06:27 -0700354 // Load last Kati Suffix if it exists
355 if katiSuffix, err := ioutil.ReadFile(config.LastKatiSuffixFile()); err == nil {
356 ctx.Verboseln("Loaded previous kati config:", string(katiSuffix))
357 config.SetKatiSuffix(string(katiSuffix))
358 }
Dan Willemsen1e704462016-08-21 15:17:17 -0700359 }
360
Colin Cross37193492017-11-16 17:55:00 -0800361 // Write combined ninja file
362 createCombinedBuildNinjaFile(ctx, config)
363
Colin Cross8ba7d472020-06-25 11:27:52 -0700364 distGzipFile(ctx, config, config.CombinedNinjaFile())
365
Colin Cross37193492017-11-16 17:55:00 -0800366 if what&RunBuildTests != 0 {
367 testForDanglingRules(ctx, config)
368 }
369
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400370 <-rbeCh
Colin Crosse7151f92023-11-28 14:18:12 -0800371 if rbePanic != nil {
372 // If there was a ctx.Fatal in startRBE, rethrow it.
373 panic(rbePanic)
374 }
375
Anton Hansson5a7861a2021-06-04 10:09:01 +0100376 if what&RunNinja != 0 {
377 if what&RunKati != 0 {
Dan Willemsene0879fc2017-08-04 15:06:27 -0700378 installCleanIfNecessary(ctx, config)
379 }
Lukacs T. Berkid1e3f1f2021-03-16 08:55:23 +0100380 runNinjaForBuild(ctx, config)
Peter Collingbourneb805c612024-03-14 21:59:57 -0700381 updateBuildIdDir(ctx, config)
Dan Willemsen1e704462016-08-21 15:17:17 -0700382 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800383
384 if what&RunDistActions != 0 {
385 runDistActions(ctx, config)
386 }
Taylor Santiago3c16e612024-05-30 14:41:31 -0700387 done = true
Dan Willemsen1e704462016-08-21 15:17:17 -0700388}
Colin Cross8ba7d472020-06-25 11:27:52 -0700389
Peter Collingbourneb805c612024-03-14 21:59:57 -0700390func updateBuildIdDir(ctx Context, config Config) {
391 ctx.BeginTrace(metrics.RunShutdownTool, "update_build_id_dir")
392 defer ctx.EndTrace()
393
394 symbolsDir := filepath.Join(config.ProductOut(), "symbols")
395 if err := elf.UpdateBuildIdDir(symbolsDir); err != nil {
396 ctx.Printf("failed to update %s/.build-id: %v", symbolsDir, err)
397 }
398}
399
usta6fffdd52022-09-19 13:16:18 -0400400func evaluateWhatToRun(config Config, verboseln func(v ...interface{})) int {
401 //evaluate what to run
Joe Onorato7f29a662023-02-23 15:47:06 -0800402 what := 0
usta6fffdd52022-09-19 13:16:18 -0400403 if config.Checkbuild() {
404 what |= RunBuildTests
405 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800406 if !config.SkipConfig() {
407 what |= RunProductConfig
408 } else {
usta6fffdd52022-09-19 13:16:18 -0400409 verboseln("Skipping Config as requested")
usta6fffdd52022-09-19 13:16:18 -0400410 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800411 if !config.SkipSoong() {
412 what |= RunSoong
413 } else {
usta6fffdd52022-09-19 13:16:18 -0400414 verboseln("Skipping use of Soong as requested")
usta6fffdd52022-09-19 13:16:18 -0400415 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800416 if !config.SkipKati() {
417 what |= RunKati
418 } else {
419 verboseln("Skipping Kati as requested")
420 }
421 if !config.SkipKatiNinja() {
422 what |= RunKatiNinja
423 } else {
424 verboseln("Skipping use of Kati ninja as requested")
425 }
426 if !config.SkipNinja() {
427 what |= RunNinja
428 } else {
usta6fffdd52022-09-19 13:16:18 -0400429 verboseln("Skipping Ninja as requested")
usta6fffdd52022-09-19 13:16:18 -0400430 }
431
432 if !config.SoongBuildInvocationNeeded() {
433 // This means that the output of soong_build is not needed and thus it would
434 // run unnecessarily. In addition, if this code wasn't there invocations
435 // with only special-cased target names like "m bp2build" would result in
436 // passing Ninja the empty target list and it would then build the default
437 // targets which is not what the user asked for.
438 what = what &^ RunNinja
439 what = what &^ RunKati
440 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800441
442 if config.Dist() {
443 what |= RunDistActions
444 }
445
usta6fffdd52022-09-19 13:16:18 -0400446 return what
447}
448
Dan Willemsen80d72612022-04-20 21:45:00 -0700449var distWaitGroup sync.WaitGroup
450
451// waitForDist waits for all backgrounded distGzipFile and distFile writes to finish
452func waitForDist(ctx Context) {
453 ctx.BeginTrace("soong_ui", "dist")
454 defer ctx.EndTrace()
455
456 distWaitGroup.Wait()
457}
458
Colin Cross8ba7d472020-06-25 11:27:52 -0700459// distGzipFile writes a compressed copy of src to the distDir if dist is enabled. Failures
Dan Willemsen80d72612022-04-20 21:45:00 -0700460// are printed but non-fatal. Uses the distWaitGroup func for backgrounding (optimization).
Colin Cross8ba7d472020-06-25 11:27:52 -0700461func distGzipFile(ctx Context, config Config, src string, subDirs ...string) {
462 if !config.Dist() {
463 return
464 }
465
466 subDir := filepath.Join(subDirs...)
Rupert Shuttleworth3c9f5ac2020-12-10 11:32:38 +0000467 destDir := filepath.Join(config.RealDistDir(), "soong_ui", subDir)
Colin Cross8ba7d472020-06-25 11:27:52 -0700468
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000469 if err := os.MkdirAll(destDir, 0777); err != nil { // a+rwx
Colin Cross8ba7d472020-06-25 11:27:52 -0700470 ctx.Printf("failed to mkdir %s: %s", destDir, err.Error())
Colin Cross8ba7d472020-06-25 11:27:52 -0700471 }
472
Dan Willemsen80d72612022-04-20 21:45:00 -0700473 distWaitGroup.Add(1)
474 go func() {
475 defer distWaitGroup.Done()
476 if err := gzipFileToDir(src, destDir); err != nil {
477 ctx.Printf("failed to dist %s: %s", filepath.Base(src), err.Error())
478 }
479 }()
Colin Cross8ba7d472020-06-25 11:27:52 -0700480}
481
482// distFile writes a copy of src to the distDir if dist is enabled. Failures are printed but
Dan Willemsen80d72612022-04-20 21:45:00 -0700483// non-fatal. Uses the distWaitGroup func for backgrounding (optimization).
Colin Cross8ba7d472020-06-25 11:27:52 -0700484func distFile(ctx Context, config Config, src string, subDirs ...string) {
485 if !config.Dist() {
486 return
487 }
488
489 subDir := filepath.Join(subDirs...)
Rupert Shuttleworth3c9f5ac2020-12-10 11:32:38 +0000490 destDir := filepath.Join(config.RealDistDir(), "soong_ui", subDir)
Colin Cross8ba7d472020-06-25 11:27:52 -0700491
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000492 if err := os.MkdirAll(destDir, 0777); err != nil { // a+rwx
Colin Cross8ba7d472020-06-25 11:27:52 -0700493 ctx.Printf("failed to mkdir %s: %s", destDir, err.Error())
Colin Cross8ba7d472020-06-25 11:27:52 -0700494 }
495
Dan Willemsen80d72612022-04-20 21:45:00 -0700496 distWaitGroup.Add(1)
497 go func() {
498 defer distWaitGroup.Done()
499 if _, err := copyFile(src, filepath.Join(destDir, filepath.Base(src))); err != nil {
500 ctx.Printf("failed to dist %s: %s", filepath.Base(src), err.Error())
501 }
502 }()
Colin Cross8ba7d472020-06-25 11:27:52 -0700503}
Joe Onorato7f29a662023-02-23 15:47:06 -0800504
505// Actions to run on every build where 'dist' is in the actions.
506// Be careful, anything added here slows down EVERY CI build
507func runDistActions(ctx Context, config Config) {
508 runStagingSnapshot(ctx, config)
509}