blob: 781ca182f76beb3d9df44cd31ac4a42eb3bd93fb [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
Dan Willemsen1e704462016-08-21 15:17:17 -070036 // The ninja_build file is used by our buildbots to understand that the output
37 // can be parsed as ninja output.
38 ensureEmptyFileExists(ctx, filepath.Join(config.OutDir(), "ninja_build"))
Jeff Gastonb64fc1c2017-08-04 12:30:12 -070039 ensureEmptyFileExists(ctx, filepath.Join(config.OutDir(), ".out-dir"))
Colin Cross28f527c2019-11-26 16:19:04 -080040
41 if buildDateTimeFile, ok := config.environ.Get("BUILD_DATETIME_FILE"); ok {
Cole Faust88f469e2025-01-21 13:05:05 -080042 err := os.WriteFile(buildDateTimeFile, []byte(config.buildDateTime), 0666) // a+rw
Colin Cross28f527c2019-11-26 16:19:04 -080043 if err != nil {
44 ctx.Fatalln("Failed to write BUILD_DATETIME to file:", err)
45 }
46 } else {
47 ctx.Fatalln("Missing BUILD_DATETIME_FILE")
48 }
Cole Faust583dfb42023-09-28 13:56:30 -070049
50 // BUILD_NUMBER should be set to the source control value that
51 // represents the current state of the source code. E.g., a
52 // perforce changelist number or a git hash. Can be an arbitrary string
53 // (to allow for source control that uses something other than numbers),
54 // but must be a single word and a valid file name.
55 //
Cole Faust1ae7b772024-06-12 18:08:44 -070056 // If no BUILD_NUMBER is set, create a useful "I am an engineering build"
57 // value. Make it start with a non-digit so that anyone trying to parse
58 // it as an integer will probably get "0". This value used to contain
59 // a timestamp, but now that more dependencies are tracked in order to
60 // reduce the importance of `m installclean`, changing it every build
61 // causes unnecessary rebuilds for local development.
Cole Faust583dfb42023-09-28 13:56:30 -070062 buildNumber, ok := config.environ.Get("BUILD_NUMBER")
63 if ok {
64 writeValueIfChanged(ctx, config, config.OutDir(), "file_name_tag.txt", buildNumber)
65 } else {
66 var username string
67 if username, ok = config.environ.Get("BUILD_USERNAME"); !ok {
68 ctx.Fatalln("Missing BUILD_USERNAME")
69 }
Cole Faust3ae36f42024-09-09 16:54:16 -070070 buildNumber = fmt.Sprintf("eng.%.6s", username)
Cole Faust583dfb42023-09-28 13:56:30 -070071 writeValueIfChanged(ctx, config, config.OutDir(), "file_name_tag.txt", username)
72 }
73 // Write the build number to a file so it can be read back in
74 // without changing the command line every time. Avoids rebuilds
75 // when using ninja.
76 writeValueIfChanged(ctx, config, config.SoongOutDir(), "build_number.txt", buildNumber)
Cole Fauste14082c2025-01-06 15:38:34 -080077
78 hostname, ok := config.environ.Get("BUILD_HOSTNAME")
79 if !ok {
80 var err error
81 hostname, err = os.Hostname()
82 if err != nil {
83 ctx.Println("Failed to read hostname:", err)
84 hostname = "unknown"
85 }
86 }
87 writeValueIfChanged(ctx, config, config.SoongOutDir(), "build_hostname.txt", hostname)
Dan Willemsen1e704462016-08-21 15:17:17 -070088}
89
Cole Faust3740b282025-01-21 15:59:50 -080090// SetupKatiEnabledMarker creates or delets a file that tells soong_build if we're running with
91// kati.
92func SetupKatiEnabledMarker(ctx Context, config Config) {
93 // Potentially write a marker file for whether kati is enabled. This is used by soong_build to
94 // potentially run the AndroidMk singleton and postinstall commands.
95 // Note that the absence of the file does not preclude running Kati for product
96 // configuration purposes.
97 katiEnabledMarker := filepath.Join(config.SoongOutDir(), ".soong.kati_enabled")
98 if config.SkipKati() || config.SkipKatiNinja() {
99 os.Remove(katiEnabledMarker)
100 } else {
101 ensureEmptyFileExists(ctx, katiEnabledMarker)
102 }
103}
104
Dan Willemsen1e704462016-08-21 15:17:17 -0700105var combinedBuildNinjaTemplate = template.Must(template.New("combined").Parse(`
106builddir = {{.OutDir}}
Colin Cross8b8bec32019-11-15 13:18:43 -0800107{{if .UseRemoteBuild }}pool local_pool
Dan Willemsen29971232018-09-26 14:58:30 -0700108 depth = {{.Parallel}}
Colin Cross8b8bec32019-11-15 13:18:43 -0800109{{end -}}
110pool highmem_pool
111 depth = {{.HighmemParallel}}
Cole Faustc5bfbdd2025-01-08 13:05:40 -0800112{{if and (not .SkipKatiNinja) .HasKatiSuffix}}
113subninja {{.KatiBuildNinjaFile}}
Dan Willemsenfb1271a2018-09-26 15:00:42 -0700114subninja {{.KatiPackageNinjaFile}}
Cole Faustc5bfbdd2025-01-08 13:05:40 -0800115{{else}}
116subninja {{.KatiSoongOnlyPackageNinjaFile}}
Dan Willemsene0879fc2017-08-04 15:06:27 -0700117{{end -}}
Dan Willemsenfb1271a2018-09-26 15:00:42 -0700118subninja {{.SoongNinjaFile}}
Dan Willemsen1e704462016-08-21 15:17:17 -0700119`))
120
121func createCombinedBuildNinjaFile(ctx Context, config Config) {
Anton Hansson0b55bdb2021-06-04 10:08:08 +0100122 // If we're in SkipKati mode but want to run kati ninja, skip creating this file if it already exists
123 if config.SkipKati() && !config.SkipKatiNinja() {
Dan Willemsene0879fc2017-08-04 15:06:27 -0700124 if _, err := os.Stat(config.CombinedNinjaFile()); err == nil || !os.IsNotExist(err) {
125 return
126 }
127 }
128
Dan Willemsen1e704462016-08-21 15:17:17 -0700129 file, err := os.Create(config.CombinedNinjaFile())
130 if err != nil {
131 ctx.Fatalln("Failed to create combined ninja file:", err)
132 }
133 defer file.Close()
134
135 if err := combinedBuildNinjaTemplate.Execute(file, config); err != nil {
136 ctx.Fatalln("Failed to write combined ninja file:", err)
137 }
138}
139
Sam Delmericod9a34352022-11-15 17:27:21 -0500140// These are bitmasks which can be used to check whether various flags are set
Dan Willemsen1e704462016-08-21 15:17:17 -0700141const (
Anton Hansson5a7861a2021-06-04 10:09:01 +0100142 _ = iota
143 // Whether to run the kati config step.
144 RunProductConfig = 1 << iota
145 // Whether to run soong to generate a ninja file.
146 RunSoong = 1 << iota
147 // Whether to run kati to generate a ninja file.
148 RunKati = 1 << iota
Anton Hansson0b55bdb2021-06-04 10:08:08 +0100149 // Whether to include the kati-generated ninja file in the combined ninja.
150 RunKatiNinja = 1 << iota
Anton Hansson5a7861a2021-06-04 10:09:01 +0100151 // Whether to run ninja on the combined ninja.
Joe Onorato7f29a662023-02-23 15:47:06 -0800152 RunNinja = 1 << iota
153 RunDistActions = 1 << iota
154 RunBuildTests = 1 << iota
Dan Willemsen1e704462016-08-21 15:17:17 -0700155)
156
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000157// 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 +0100158func checkProblematicFiles(ctx Context) {
159 files := []string{"Android.mk", "CleanSpec.mk"}
160 for _, file := range files {
161 if _, err := os.Stat(file); !os.IsNotExist(err) {
162 absolute := absPath(ctx, file)
163 ctx.Printf("Found %s in tree root. This file needs to be removed to build.\n", file)
164 ctx.Fatalf(" rm %s\n", absolute)
165 }
166 }
167}
168
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000169// checkCaseSensitivity issues a warning if a case-insensitive file system is being used.
Dan Willemsendb8457c2017-05-12 16:38:17 -0700170func checkCaseSensitivity(ctx Context, config Config) {
171 outDir := config.OutDir()
172 lowerCase := filepath.Join(outDir, "casecheck.txt")
173 upperCase := filepath.Join(outDir, "CaseCheck.txt")
174 lowerData := "a"
175 upperData := "B"
176
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000177 if err := ioutil.WriteFile(lowerCase, []byte(lowerData), 0666); err != nil { // a+rw
Dan Willemsendb8457c2017-05-12 16:38:17 -0700178 ctx.Fatalln("Failed to check case sensitivity:", err)
179 }
180
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000181 if err := ioutil.WriteFile(upperCase, []byte(upperData), 0666); err != nil { // a+rw
Dan Willemsendb8457c2017-05-12 16:38:17 -0700182 ctx.Fatalln("Failed to check case sensitivity:", err)
183 }
184
185 res, err := ioutil.ReadFile(lowerCase)
186 if err != nil {
187 ctx.Fatalln("Failed to check case sensitivity:", err)
188 }
189
190 if string(res) != lowerData {
191 ctx.Println("************************************************************")
192 ctx.Println("You are building on a case-insensitive filesystem.")
193 ctx.Println("Please move your source tree to a case-sensitive filesystem.")
194 ctx.Println("************************************************************")
195 ctx.Fatalln("Case-insensitive filesystems not supported")
196 }
197}
198
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000199// help prints a help/usage message, via the build/make/help.sh script.
200func help(ctx Context, config Config) {
Jeff Gastondf4a0812017-05-30 20:11:20 -0700201 cmd := Command(ctx, config, "help.sh", "build/make/help.sh")
Dan Willemsenb2e6c2e2017-07-13 17:24:44 -0700202 cmd.Sandbox = dumpvarsSandbox
Dan Willemsenb82471a2018-05-17 16:37:09 -0700203 cmd.RunAndPrintOrFatal()
Dan Willemsen02781d52017-05-12 19:28:13 -0700204}
205
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000206// checkRAM warns if there probably isn't enough RAM to complete a build.
207func checkRAM(ctx Context, config Config) {
Dan Willemsen570a2922020-05-26 23:02:29 -0700208 if totalRAM := config.TotalRAM(); totalRAM != 0 {
209 ram := float32(totalRAM) / (1024 * 1024 * 1024)
210 ctx.Verbosef("Total RAM: %.3vGB", ram)
211
212 if ram <= 16 {
213 ctx.Println("************************************************************")
214 ctx.Printf("You are building on a machine with %.3vGB of RAM\n", ram)
215 ctx.Println("")
216 ctx.Println("The minimum required amount of free memory is around 16GB,")
217 ctx.Println("and even with that, some configurations may not work.")
218 ctx.Println("")
219 ctx.Println("If you run into segfaults or other errors, try reducing your")
220 ctx.Println("-j value.")
221 ctx.Println("************************************************************")
222 } else if ram <= float32(config.Parallel()) {
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000223 // Want at least 1GB of RAM per job.
Dan Willemsen570a2922020-05-26 23:02:29 -0700224 ctx.Printf("Warning: high -j%d count compared to %.3vGB of RAM", config.Parallel(), ram)
225 ctx.Println("If you run into segfaults or other errors, try a lower -j value")
226 }
227 }
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000228}
229
Taylor Santiago3c16e612024-05-30 14:41:31 -0700230func abfsBuildStarted(ctx Context, config Config) {
231 abfsBox := config.PrebuiltBuildTool("abfsbox")
232 cmdArgs := []string{"build-started", "--"}
233 cmdArgs = append(cmdArgs, config.Arguments()...)
234 cmd := Command(ctx, config, "abfsbox", abfsBox, cmdArgs...)
235 cmd.Sandbox = noSandbox
236 cmd.RunAndPrintOrFatal()
237}
238
239func abfsBuildFinished(ctx Context, config Config, finished bool) {
240 var errMsg string
241 if !finished {
242 errMsg = "build was interrupted"
243 }
244 abfsBox := config.PrebuiltBuildTool("abfsbox")
245 cmdArgs := []string{"build-finished", "-e", errMsg, "--"}
246 cmdArgs = append(cmdArgs, config.Arguments()...)
247 cmd := Command(ctx, config, "abfsbox", abfsBox, cmdArgs...)
248 cmd.RunAndPrintOrFatal()
249}
250
Usta Shresthadb46a9b2022-07-11 11:29:56 -0400251// Build the tree. Various flags in `config` govern which components of
252// the build to run.
Anton Hansson5a7861a2021-06-04 10:09:01 +0100253func Build(ctx Context, config Config) {
Taylor Santiago3c16e612024-05-30 14:41:31 -0700254 done := false
255 if config.UseABFS() {
256 abfsBuildStarted(ctx, config)
257 defer func() {
258 abfsBuildFinished(ctx, config, done)
259 }()
260 }
261
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000262 ctx.Verboseln("Starting build with args:", config.Arguments())
263 ctx.Verboseln("Environment:", config.Environment().Environ())
Dan Willemsen1e704462016-08-21 15:17:17 -0700264
Colin Cross74cda722020-01-16 15:25:50 -0800265 ctx.BeginTrace(metrics.Total, "total")
266 defer ctx.EndTrace()
267
Dan Willemsen1e704462016-08-21 15:17:17 -0700268 if inList("help", config.Arguments()) {
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000269 help(ctx, config)
Dan Willemsen0b73b4b2017-05-12 19:28:13 -0700270 return
Dan Willemsen1e704462016-08-21 15:17:17 -0700271 }
272
Jeff Gaston3615fe82017-05-24 13:14:34 -0700273 // Make sure that no other Soong process is running with the same output directory
274 buildLock := BecomeSingletonOrFail(ctx, config)
275 defer buildLock.Unlock()
276
Usta Shrestha675564d2022-08-09 18:03:23 -0400277 logArgsOtherThan := func(specialTargets ...string) {
278 var ignored []string
279 for _, a := range config.Arguments() {
280 if !inList(a, specialTargets) {
281 ignored = append(ignored, a)
282 }
283 }
284 if len(ignored) > 0 {
285 ctx.Printf("ignoring arguments %q", ignored)
286 }
287 }
288
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000289 if inList("clean", config.Arguments()) || inList("clobber", config.Arguments()) {
Usta Shrestha675564d2022-08-09 18:03:23 -0400290 logArgsOtherThan("clean", "clobber")
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000291 clean(ctx, config)
292 return
293 }
294
Dan Willemsen80d72612022-04-20 21:45:00 -0700295 defer waitForDist(ctx)
296
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000297 // 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 +0100298 checkProblematicFiles(ctx)
299
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000300 checkRAM(ctx, config)
301
Dan Willemsen1e704462016-08-21 15:17:17 -0700302 SetupOutDir(ctx, config)
303
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000304 // checkCaseSensitivity issues a warning if a case-insensitive file system is being used.
Dan Willemsendb8457c2017-05-12 16:38:17 -0700305 checkCaseSensitivity(ctx, config)
306
Dan Willemsen18490112018-05-25 16:30:04 -0700307 SetupPath(ctx, config)
308
usta6fffdd52022-09-19 13:16:18 -0400309 what := evaluateWhatToRun(config, ctx.Verboseln)
Lukacs T. Berkia1b93722021-09-02 17:23:06 +0200310
Yoshisato Yanagisawa2cb0e5d2019-01-10 10:14:16 +0900311 if config.StartGoma() {
Yoshisato Yanagisawa2cb0e5d2019-01-10 10:14:16 +0900312 startGoma(ctx, config)
313 }
314
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400315 rbeCh := make(chan bool)
Colin Crosse7151f92023-11-28 14:18:12 -0800316 var rbePanic any
Ramy Medhatbbf25672019-07-17 12:30:04 +0000317 if config.StartRBE() {
Kousik Kumar4c180ad2022-05-27 07:48:37 -0400318 cleanupRBELogsDir(ctx, config)
Colin Crosse7151f92023-11-28 14:18:12 -0800319 checkRBERequirements(ctx, config)
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400320 go func() {
Colin Crosse7151f92023-11-28 14:18:12 -0800321 defer func() {
322 rbePanic = recover()
323 close(rbeCh)
324 }()
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400325 startRBE(ctx, config)
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400326 }()
Kousik Kumara1d8fa92022-03-18 02:50:31 -0400327 defer DumpRBEMetrics(ctx, config, filepath.Join(config.LogsDir(), "rbe_metrics.pb"))
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400328 } else {
329 close(rbeCh)
Ramy Medhatbbf25672019-07-17 12:30:04 +0000330 }
331
Anton Hansson5a7861a2021-06-04 10:09:01 +0100332 if what&RunProductConfig != 0 {
Dan Willemsen1e704462016-08-21 15:17:17 -0700333 runMakeProductConfig(ctx, config)
Cole Faust3740b282025-01-21 15:59:50 -0800334
335 // Re-evaluate what to run because there are product variables that control how
336 // soong and make are run.
337 what = evaluateWhatToRun(config, ctx.Verboseln)
Dan Willemsen1e704462016-08-21 15:17:17 -0700338 }
339
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000340 // Everything below here depends on product config.
341
Cole Faust3740b282025-01-21 15:59:50 -0800342 SetupKatiEnabledMarker(ctx, config)
343
Colin Cross806fd942019-05-03 13:35:58 -0700344 if inList("installclean", config.Arguments()) ||
345 inList("install-clean", config.Arguments()) {
Usta Shrestha675564d2022-08-09 18:03:23 -0400346 logArgsOtherThan("installclean", "install-clean")
Rupert Shuttleworth1f304e62020-11-24 14:13:41 +0000347 installClean(ctx, config)
Dan Willemsenf052f782017-05-18 15:29:04 -0700348 ctx.Println("Deleted images and staging directories.")
349 return
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000350 }
351
352 if inList("dataclean", config.Arguments()) ||
Colin Cross806fd942019-05-03 13:35:58 -0700353 inList("data-clean", config.Arguments()) {
Usta Shrestha675564d2022-08-09 18:03:23 -0400354 logArgsOtherThan("dataclean", "data-clean")
Rupert Shuttleworth1f304e62020-11-24 14:13:41 +0000355 dataClean(ctx, config)
Dan Willemsenf052f782017-05-18 15:29:04 -0700356 ctx.Println("Deleted data files.")
357 return
358 }
359
Cole Faustc5bfbdd2025-01-08 13:05:40 -0800360 // Still generate the kati suffix in soong-only builds because soong-only still uses kati for
361 // the packaging step. Also, the kati suffix is used for the combined ninja file.
362 genKatiSuffix(ctx, config)
363
Anton Hansson5a7861a2021-06-04 10:09:01 +0100364 if what&RunSoong != 0 {
Dan Willemsen1e704462016-08-21 15:17:17 -0700365 runSoong(ctx, config)
366 }
367
Anton Hansson5a7861a2021-06-04 10:09:01 +0100368 if what&RunKati != 0 {
Dan Willemsen29971232018-09-26 14:58:30 -0700369 runKatiCleanSpec(ctx, config)
370 runKatiBuild(ctx, config)
Cole Faustc5bfbdd2025-01-08 13:05:40 -0800371 runKatiPackage(ctx, config, false)
Dan Willemsene0879fc2017-08-04 15:06:27 -0700372
Anton Hansson0b55bdb2021-06-04 10:08:08 +0100373 } else if what&RunKatiNinja != 0 {
Dan Willemsene0879fc2017-08-04 15:06:27 -0700374 // Load last Kati Suffix if it exists
Cole Faustc5bfbdd2025-01-08 13:05:40 -0800375 if katiSuffix, err := os.ReadFile(config.LastKatiSuffixFile()); err == nil {
Dan Willemsene0879fc2017-08-04 15:06:27 -0700376 ctx.Verboseln("Loaded previous kati config:", string(katiSuffix))
377 config.SetKatiSuffix(string(katiSuffix))
378 }
Cole Faustc5bfbdd2025-01-08 13:05:40 -0800379 } else if what&RunSoong != 0 {
380 runKatiPackage(ctx, config, true)
Dan Willemsen1e704462016-08-21 15:17:17 -0700381 }
382
Cole Faustc5bfbdd2025-01-08 13:05:40 -0800383 os.WriteFile(config.LastKatiSuffixFile(), []byte(config.KatiSuffix()), 0666) // a+rw
384
Colin Cross37193492017-11-16 17:55:00 -0800385 // Write combined ninja file
386 createCombinedBuildNinjaFile(ctx, config)
387
Colin Cross8ba7d472020-06-25 11:27:52 -0700388 distGzipFile(ctx, config, config.CombinedNinjaFile())
389
Colin Cross37193492017-11-16 17:55:00 -0800390 if what&RunBuildTests != 0 {
391 testForDanglingRules(ctx, config)
392 }
393
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400394 <-rbeCh
Colin Crosse7151f92023-11-28 14:18:12 -0800395 if rbePanic != nil {
396 // If there was a ctx.Fatal in startRBE, rethrow it.
397 panic(rbePanic)
398 }
399
Anton Hansson5a7861a2021-06-04 10:09:01 +0100400 if what&RunNinja != 0 {
401 if what&RunKati != 0 {
Dan Willemsene0879fc2017-08-04 15:06:27 -0700402 installCleanIfNecessary(ctx, config)
403 }
LaMont Jones825f8ff2025-02-12 11:52:00 -0800404 partialCompileCleanIfNecessary(ctx, config)
Lukacs T. Berkid1e3f1f2021-03-16 08:55:23 +0100405 runNinjaForBuild(ctx, config)
Peter Collingbourneb805c612024-03-14 21:59:57 -0700406 updateBuildIdDir(ctx, config)
Dan Willemsen1e704462016-08-21 15:17:17 -0700407 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800408
409 if what&RunDistActions != 0 {
410 runDistActions(ctx, config)
411 }
Taylor Santiago3c16e612024-05-30 14:41:31 -0700412 done = true
Dan Willemsen1e704462016-08-21 15:17:17 -0700413}
Colin Cross8ba7d472020-06-25 11:27:52 -0700414
Peter Collingbourneb805c612024-03-14 21:59:57 -0700415func updateBuildIdDir(ctx Context, config Config) {
416 ctx.BeginTrace(metrics.RunShutdownTool, "update_build_id_dir")
417 defer ctx.EndTrace()
418
419 symbolsDir := filepath.Join(config.ProductOut(), "symbols")
420 if err := elf.UpdateBuildIdDir(symbolsDir); err != nil {
421 ctx.Printf("failed to update %s/.build-id: %v", symbolsDir, err)
422 }
423}
424
usta6fffdd52022-09-19 13:16:18 -0400425func evaluateWhatToRun(config Config, verboseln func(v ...interface{})) int {
426 //evaluate what to run
Joe Onorato7f29a662023-02-23 15:47:06 -0800427 what := 0
usta6fffdd52022-09-19 13:16:18 -0400428 if config.Checkbuild() {
429 what |= RunBuildTests
430 }
Spandan Dasace33912025-02-05 22:34:27 +0000431 if value, ok := config.environ.Get("RUN_BUILD_TESTS"); ok && value == "true" {
432 what |= RunBuildTests
433 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800434 if !config.SkipConfig() {
435 what |= RunProductConfig
436 } else {
usta6fffdd52022-09-19 13:16:18 -0400437 verboseln("Skipping Config as requested")
usta6fffdd52022-09-19 13:16:18 -0400438 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800439 if !config.SkipSoong() {
440 what |= RunSoong
441 } else {
usta6fffdd52022-09-19 13:16:18 -0400442 verboseln("Skipping use of Soong as requested")
usta6fffdd52022-09-19 13:16:18 -0400443 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800444 if !config.SkipKati() {
445 what |= RunKati
446 } else {
447 verboseln("Skipping Kati as requested")
448 }
449 if !config.SkipKatiNinja() {
450 what |= RunKatiNinja
451 } else {
452 verboseln("Skipping use of Kati ninja as requested")
453 }
454 if !config.SkipNinja() {
455 what |= RunNinja
456 } else {
usta6fffdd52022-09-19 13:16:18 -0400457 verboseln("Skipping Ninja as requested")
usta6fffdd52022-09-19 13:16:18 -0400458 }
459
460 if !config.SoongBuildInvocationNeeded() {
461 // This means that the output of soong_build is not needed and thus it would
462 // run unnecessarily. In addition, if this code wasn't there invocations
Joe Onorato35f300d2024-10-21 15:02:44 -0700463 // with only special-cased target names would result in
usta6fffdd52022-09-19 13:16:18 -0400464 // passing Ninja the empty target list and it would then build the default
465 // targets which is not what the user asked for.
466 what = what &^ RunNinja
467 what = what &^ RunKati
468 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800469
470 if config.Dist() {
471 what |= RunDistActions
472 }
473
usta6fffdd52022-09-19 13:16:18 -0400474 return what
475}
476
Dan Willemsen80d72612022-04-20 21:45:00 -0700477var distWaitGroup sync.WaitGroup
478
479// waitForDist waits for all backgrounded distGzipFile and distFile writes to finish
480func waitForDist(ctx Context) {
481 ctx.BeginTrace("soong_ui", "dist")
482 defer ctx.EndTrace()
483
484 distWaitGroup.Wait()
485}
486
Colin Cross8ba7d472020-06-25 11:27:52 -0700487// distGzipFile writes a compressed copy of src to the distDir if dist is enabled. Failures
Dan Willemsen80d72612022-04-20 21:45:00 -0700488// are printed but non-fatal. Uses the distWaitGroup func for backgrounding (optimization).
Colin Cross8ba7d472020-06-25 11:27:52 -0700489func distGzipFile(ctx Context, config Config, src string, subDirs ...string) {
490 if !config.Dist() {
491 return
492 }
493
494 subDir := filepath.Join(subDirs...)
Rupert Shuttleworth3c9f5ac2020-12-10 11:32:38 +0000495 destDir := filepath.Join(config.RealDistDir(), "soong_ui", subDir)
Colin Cross8ba7d472020-06-25 11:27:52 -0700496
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000497 if err := os.MkdirAll(destDir, 0777); err != nil { // a+rwx
Colin Cross8ba7d472020-06-25 11:27:52 -0700498 ctx.Printf("failed to mkdir %s: %s", destDir, err.Error())
Colin Cross8ba7d472020-06-25 11:27:52 -0700499 }
500
Dan Willemsen80d72612022-04-20 21:45:00 -0700501 distWaitGroup.Add(1)
502 go func() {
503 defer distWaitGroup.Done()
504 if err := gzipFileToDir(src, destDir); err != nil {
505 ctx.Printf("failed to dist %s: %s", filepath.Base(src), err.Error())
506 }
507 }()
Colin Cross8ba7d472020-06-25 11:27:52 -0700508}
509
510// distFile writes a copy of src to the distDir if dist is enabled. Failures are printed but
Dan Willemsen80d72612022-04-20 21:45:00 -0700511// non-fatal. Uses the distWaitGroup func for backgrounding (optimization).
Colin Cross8ba7d472020-06-25 11:27:52 -0700512func distFile(ctx Context, config Config, src string, subDirs ...string) {
513 if !config.Dist() {
514 return
515 }
516
517 subDir := filepath.Join(subDirs...)
Rupert Shuttleworth3c9f5ac2020-12-10 11:32:38 +0000518 destDir := filepath.Join(config.RealDistDir(), "soong_ui", subDir)
Colin Cross8ba7d472020-06-25 11:27:52 -0700519
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000520 if err := os.MkdirAll(destDir, 0777); err != nil { // a+rwx
Colin Cross8ba7d472020-06-25 11:27:52 -0700521 ctx.Printf("failed to mkdir %s: %s", destDir, err.Error())
Colin Cross8ba7d472020-06-25 11:27:52 -0700522 }
523
Dan Willemsen80d72612022-04-20 21:45:00 -0700524 distWaitGroup.Add(1)
525 go func() {
526 defer distWaitGroup.Done()
527 if _, err := copyFile(src, filepath.Join(destDir, filepath.Base(src))); err != nil {
528 ctx.Printf("failed to dist %s: %s", filepath.Base(src), err.Error())
529 }
530 }()
Colin Cross8ba7d472020-06-25 11:27:52 -0700531}
Joe Onorato7f29a662023-02-23 15:47:06 -0800532
533// Actions to run on every build where 'dist' is in the actions.
534// Be careful, anything added here slows down EVERY CI build
535func runDistActions(ctx Context, config Config) {
536 runStagingSnapshot(ctx, config)
Joe Onoratod6a29992024-12-06 12:55:41 -0800537 runSourceInputs(ctx, config)
Joe Onorato7f29a662023-02-23 15:47:06 -0800538}