blob: e0c9e6d14760f1c2050f1329e91e4444560d24a5 [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")
Cole Faust88f469e2025-01-21 13:05:05 -080041 if config.SkipKati() || config.SkipKatiNinja() {
Anton Hansson17fc5a02021-06-18 16:37:14 +010042 os.Remove(katiEnabledMarker)
Cole Faust88f469e2025-01-21 13:05:05 -080043 } else {
Anton Hansson17fc5a02021-06-18 16:37:14 +010044 ensureEmptyFileExists(ctx, katiEnabledMarker)
Dan Willemsene0879fc2017-08-04 15:06:27 -070045 }
Anton Hansson17fc5a02021-06-18 16:37:14 +010046
Dan Willemsen1e704462016-08-21 15:17:17 -070047 // The ninja_build file is used by our buildbots to understand that the output
48 // can be parsed as ninja output.
49 ensureEmptyFileExists(ctx, filepath.Join(config.OutDir(), "ninja_build"))
Jeff Gastonb64fc1c2017-08-04 12:30:12 -070050 ensureEmptyFileExists(ctx, filepath.Join(config.OutDir(), ".out-dir"))
Colin Cross28f527c2019-11-26 16:19:04 -080051
52 if buildDateTimeFile, ok := config.environ.Get("BUILD_DATETIME_FILE"); ok {
Cole Faust88f469e2025-01-21 13:05:05 -080053 err := os.WriteFile(buildDateTimeFile, []byte(config.buildDateTime), 0666) // a+rw
Colin Cross28f527c2019-11-26 16:19:04 -080054 if err != nil {
55 ctx.Fatalln("Failed to write BUILD_DATETIME to file:", err)
56 }
57 } else {
58 ctx.Fatalln("Missing BUILD_DATETIME_FILE")
59 }
Cole Faust583dfb42023-09-28 13:56:30 -070060
61 // BUILD_NUMBER should be set to the source control value that
62 // represents the current state of the source code. E.g., a
63 // perforce changelist number or a git hash. Can be an arbitrary string
64 // (to allow for source control that uses something other than numbers),
65 // but must be a single word and a valid file name.
66 //
Cole Faust1ae7b772024-06-12 18:08:44 -070067 // If no BUILD_NUMBER is set, create a useful "I am an engineering build"
68 // value. Make it start with a non-digit so that anyone trying to parse
69 // it as an integer will probably get "0". This value used to contain
70 // a timestamp, but now that more dependencies are tracked in order to
71 // reduce the importance of `m installclean`, changing it every build
72 // causes unnecessary rebuilds for local development.
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 }
Cole Faust3ae36f42024-09-09 16:54:16 -070081 buildNumber = fmt.Sprintf("eng.%.6s", username)
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)
Cole Fauste14082c2025-01-06 15:38:34 -080088
89 hostname, ok := config.environ.Get("BUILD_HOSTNAME")
90 if !ok {
91 var err error
92 hostname, err = os.Hostname()
93 if err != nil {
94 ctx.Println("Failed to read hostname:", err)
95 hostname = "unknown"
96 }
97 }
98 writeValueIfChanged(ctx, config, config.SoongOutDir(), "build_hostname.txt", hostname)
Dan Willemsen1e704462016-08-21 15:17:17 -070099}
100
101var combinedBuildNinjaTemplate = template.Must(template.New("combined").Parse(`
102builddir = {{.OutDir}}
Colin Cross8b8bec32019-11-15 13:18:43 -0800103{{if .UseRemoteBuild }}pool local_pool
Dan Willemsen29971232018-09-26 14:58:30 -0700104 depth = {{.Parallel}}
Colin Cross8b8bec32019-11-15 13:18:43 -0800105{{end -}}
106pool highmem_pool
107 depth = {{.HighmemParallel}}
Cole Faustc5bfbdd2025-01-08 13:05:40 -0800108{{if and (not .SkipKatiNinja) .HasKatiSuffix}}
109subninja {{.KatiBuildNinjaFile}}
Dan Willemsenfb1271a2018-09-26 15:00:42 -0700110subninja {{.KatiPackageNinjaFile}}
Cole Faustc5bfbdd2025-01-08 13:05:40 -0800111{{else}}
112subninja {{.KatiSoongOnlyPackageNinjaFile}}
Dan Willemsene0879fc2017-08-04 15:06:27 -0700113{{end -}}
Dan Willemsenfb1271a2018-09-26 15:00:42 -0700114subninja {{.SoongNinjaFile}}
Dan Willemsen1e704462016-08-21 15:17:17 -0700115`))
116
117func createCombinedBuildNinjaFile(ctx Context, config Config) {
Anton Hansson0b55bdb2021-06-04 10:08:08 +0100118 // If we're in SkipKati mode but want to run kati ninja, skip creating this file if it already exists
119 if config.SkipKati() && !config.SkipKatiNinja() {
Dan Willemsene0879fc2017-08-04 15:06:27 -0700120 if _, err := os.Stat(config.CombinedNinjaFile()); err == nil || !os.IsNotExist(err) {
121 return
122 }
123 }
124
Dan Willemsen1e704462016-08-21 15:17:17 -0700125 file, err := os.Create(config.CombinedNinjaFile())
126 if err != nil {
127 ctx.Fatalln("Failed to create combined ninja file:", err)
128 }
129 defer file.Close()
130
131 if err := combinedBuildNinjaTemplate.Execute(file, config); err != nil {
132 ctx.Fatalln("Failed to write combined ninja file:", err)
133 }
134}
135
Sam Delmericod9a34352022-11-15 17:27:21 -0500136// These are bitmasks which can be used to check whether various flags are set
Dan Willemsen1e704462016-08-21 15:17:17 -0700137const (
Anton Hansson5a7861a2021-06-04 10:09:01 +0100138 _ = iota
139 // Whether to run the kati config step.
140 RunProductConfig = 1 << iota
141 // Whether to run soong to generate a ninja file.
142 RunSoong = 1 << iota
143 // Whether to run kati to generate a ninja file.
144 RunKati = 1 << iota
Anton Hansson0b55bdb2021-06-04 10:08:08 +0100145 // Whether to include the kati-generated ninja file in the combined ninja.
146 RunKatiNinja = 1 << iota
Anton Hansson5a7861a2021-06-04 10:09:01 +0100147 // Whether to run ninja on the combined ninja.
Joe Onorato7f29a662023-02-23 15:47:06 -0800148 RunNinja = 1 << iota
149 RunDistActions = 1 << iota
150 RunBuildTests = 1 << iota
Dan Willemsen1e704462016-08-21 15:17:17 -0700151)
152
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000153// 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 +0100154func checkProblematicFiles(ctx Context) {
155 files := []string{"Android.mk", "CleanSpec.mk"}
156 for _, file := range files {
157 if _, err := os.Stat(file); !os.IsNotExist(err) {
158 absolute := absPath(ctx, file)
159 ctx.Printf("Found %s in tree root. This file needs to be removed to build.\n", file)
160 ctx.Fatalf(" rm %s\n", absolute)
161 }
162 }
163}
164
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000165// checkCaseSensitivity issues a warning if a case-insensitive file system is being used.
Dan Willemsendb8457c2017-05-12 16:38:17 -0700166func checkCaseSensitivity(ctx Context, config Config) {
167 outDir := config.OutDir()
168 lowerCase := filepath.Join(outDir, "casecheck.txt")
169 upperCase := filepath.Join(outDir, "CaseCheck.txt")
170 lowerData := "a"
171 upperData := "B"
172
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000173 if err := ioutil.WriteFile(lowerCase, []byte(lowerData), 0666); err != nil { // a+rw
Dan Willemsendb8457c2017-05-12 16:38:17 -0700174 ctx.Fatalln("Failed to check case sensitivity:", err)
175 }
176
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000177 if err := ioutil.WriteFile(upperCase, []byte(upperData), 0666); err != nil { // a+rw
Dan Willemsendb8457c2017-05-12 16:38:17 -0700178 ctx.Fatalln("Failed to check case sensitivity:", err)
179 }
180
181 res, err := ioutil.ReadFile(lowerCase)
182 if err != nil {
183 ctx.Fatalln("Failed to check case sensitivity:", err)
184 }
185
186 if string(res) != lowerData {
187 ctx.Println("************************************************************")
188 ctx.Println("You are building on a case-insensitive filesystem.")
189 ctx.Println("Please move your source tree to a case-sensitive filesystem.")
190 ctx.Println("************************************************************")
191 ctx.Fatalln("Case-insensitive filesystems not supported")
192 }
193}
194
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000195// help prints a help/usage message, via the build/make/help.sh script.
196func help(ctx Context, config Config) {
Jeff Gastondf4a0812017-05-30 20:11:20 -0700197 cmd := Command(ctx, config, "help.sh", "build/make/help.sh")
Dan Willemsenb2e6c2e2017-07-13 17:24:44 -0700198 cmd.Sandbox = dumpvarsSandbox
Dan Willemsenb82471a2018-05-17 16:37:09 -0700199 cmd.RunAndPrintOrFatal()
Dan Willemsen02781d52017-05-12 19:28:13 -0700200}
201
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000202// checkRAM warns if there probably isn't enough RAM to complete a build.
203func checkRAM(ctx Context, config Config) {
Dan Willemsen570a2922020-05-26 23:02:29 -0700204 if totalRAM := config.TotalRAM(); totalRAM != 0 {
205 ram := float32(totalRAM) / (1024 * 1024 * 1024)
206 ctx.Verbosef("Total RAM: %.3vGB", ram)
207
208 if ram <= 16 {
209 ctx.Println("************************************************************")
210 ctx.Printf("You are building on a machine with %.3vGB of RAM\n", ram)
211 ctx.Println("")
212 ctx.Println("The minimum required amount of free memory is around 16GB,")
213 ctx.Println("and even with that, some configurations may not work.")
214 ctx.Println("")
215 ctx.Println("If you run into segfaults or other errors, try reducing your")
216 ctx.Println("-j value.")
217 ctx.Println("************************************************************")
218 } else if ram <= float32(config.Parallel()) {
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000219 // Want at least 1GB of RAM per job.
Dan Willemsen570a2922020-05-26 23:02:29 -0700220 ctx.Printf("Warning: high -j%d count compared to %.3vGB of RAM", config.Parallel(), ram)
221 ctx.Println("If you run into segfaults or other errors, try a lower -j value")
222 }
223 }
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000224}
225
Taylor Santiago3c16e612024-05-30 14:41:31 -0700226func abfsBuildStarted(ctx Context, config Config) {
227 abfsBox := config.PrebuiltBuildTool("abfsbox")
228 cmdArgs := []string{"build-started", "--"}
229 cmdArgs = append(cmdArgs, config.Arguments()...)
230 cmd := Command(ctx, config, "abfsbox", abfsBox, cmdArgs...)
231 cmd.Sandbox = noSandbox
232 cmd.RunAndPrintOrFatal()
233}
234
235func abfsBuildFinished(ctx Context, config Config, finished bool) {
236 var errMsg string
237 if !finished {
238 errMsg = "build was interrupted"
239 }
240 abfsBox := config.PrebuiltBuildTool("abfsbox")
241 cmdArgs := []string{"build-finished", "-e", errMsg, "--"}
242 cmdArgs = append(cmdArgs, config.Arguments()...)
243 cmd := Command(ctx, config, "abfsbox", abfsBox, cmdArgs...)
244 cmd.RunAndPrintOrFatal()
245}
246
Usta Shresthadb46a9b2022-07-11 11:29:56 -0400247// Build the tree. Various flags in `config` govern which components of
248// the build to run.
Anton Hansson5a7861a2021-06-04 10:09:01 +0100249func Build(ctx Context, config Config) {
Taylor Santiago3c16e612024-05-30 14:41:31 -0700250 done := false
251 if config.UseABFS() {
252 abfsBuildStarted(ctx, config)
253 defer func() {
254 abfsBuildFinished(ctx, config, done)
255 }()
256 }
257
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000258 ctx.Verboseln("Starting build with args:", config.Arguments())
259 ctx.Verboseln("Environment:", config.Environment().Environ())
Dan Willemsen1e704462016-08-21 15:17:17 -0700260
Colin Cross74cda722020-01-16 15:25:50 -0800261 ctx.BeginTrace(metrics.Total, "total")
262 defer ctx.EndTrace()
263
Dan Willemsen1e704462016-08-21 15:17:17 -0700264 if inList("help", config.Arguments()) {
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000265 help(ctx, config)
Dan Willemsen0b73b4b2017-05-12 19:28:13 -0700266 return
Dan Willemsen1e704462016-08-21 15:17:17 -0700267 }
268
Jeff Gaston3615fe82017-05-24 13:14:34 -0700269 // Make sure that no other Soong process is running with the same output directory
270 buildLock := BecomeSingletonOrFail(ctx, config)
271 defer buildLock.Unlock()
272
Usta Shrestha675564d2022-08-09 18:03:23 -0400273 logArgsOtherThan := func(specialTargets ...string) {
274 var ignored []string
275 for _, a := range config.Arguments() {
276 if !inList(a, specialTargets) {
277 ignored = append(ignored, a)
278 }
279 }
280 if len(ignored) > 0 {
281 ctx.Printf("ignoring arguments %q", ignored)
282 }
283 }
284
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000285 if inList("clean", config.Arguments()) || inList("clobber", config.Arguments()) {
Usta Shrestha675564d2022-08-09 18:03:23 -0400286 logArgsOtherThan("clean", "clobber")
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000287 clean(ctx, config)
288 return
289 }
290
Dan Willemsen80d72612022-04-20 21:45:00 -0700291 defer waitForDist(ctx)
292
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000293 // 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 +0100294 checkProblematicFiles(ctx)
295
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000296 checkRAM(ctx, config)
297
Dan Willemsen1e704462016-08-21 15:17:17 -0700298 SetupOutDir(ctx, config)
299
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000300 // checkCaseSensitivity issues a warning if a case-insensitive file system is being used.
Dan Willemsendb8457c2017-05-12 16:38:17 -0700301 checkCaseSensitivity(ctx, config)
302
Dan Willemsen18490112018-05-25 16:30:04 -0700303 SetupPath(ctx, config)
304
usta6fffdd52022-09-19 13:16:18 -0400305 what := evaluateWhatToRun(config, ctx.Verboseln)
Lukacs T. Berkia1b93722021-09-02 17:23:06 +0200306
Yoshisato Yanagisawa2cb0e5d2019-01-10 10:14:16 +0900307 if config.StartGoma() {
Yoshisato Yanagisawa2cb0e5d2019-01-10 10:14:16 +0900308 startGoma(ctx, config)
309 }
310
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400311 rbeCh := make(chan bool)
Colin Crosse7151f92023-11-28 14:18:12 -0800312 var rbePanic any
Ramy Medhatbbf25672019-07-17 12:30:04 +0000313 if config.StartRBE() {
Kousik Kumar4c180ad2022-05-27 07:48:37 -0400314 cleanupRBELogsDir(ctx, config)
Colin Crosse7151f92023-11-28 14:18:12 -0800315 checkRBERequirements(ctx, config)
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400316 go func() {
Colin Crosse7151f92023-11-28 14:18:12 -0800317 defer func() {
318 rbePanic = recover()
319 close(rbeCh)
320 }()
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400321 startRBE(ctx, config)
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400322 }()
Kousik Kumara1d8fa92022-03-18 02:50:31 -0400323 defer DumpRBEMetrics(ctx, config, filepath.Join(config.LogsDir(), "rbe_metrics.pb"))
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400324 } else {
325 close(rbeCh)
Ramy Medhatbbf25672019-07-17 12:30:04 +0000326 }
327
Anton Hansson5a7861a2021-06-04 10:09:01 +0100328 if what&RunProductConfig != 0 {
Dan Willemsen1e704462016-08-21 15:17:17 -0700329 runMakeProductConfig(ctx, config)
330 }
331
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000332 // Everything below here depends on product config.
333
Colin Cross806fd942019-05-03 13:35:58 -0700334 if inList("installclean", config.Arguments()) ||
335 inList("install-clean", config.Arguments()) {
Usta Shrestha675564d2022-08-09 18:03:23 -0400336 logArgsOtherThan("installclean", "install-clean")
Rupert Shuttleworth1f304e62020-11-24 14:13:41 +0000337 installClean(ctx, config)
Dan Willemsenf052f782017-05-18 15:29:04 -0700338 ctx.Println("Deleted images and staging directories.")
339 return
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000340 }
341
342 if inList("dataclean", config.Arguments()) ||
Colin Cross806fd942019-05-03 13:35:58 -0700343 inList("data-clean", config.Arguments()) {
Usta Shrestha675564d2022-08-09 18:03:23 -0400344 logArgsOtherThan("dataclean", "data-clean")
Rupert Shuttleworth1f304e62020-11-24 14:13:41 +0000345 dataClean(ctx, config)
Dan Willemsenf052f782017-05-18 15:29:04 -0700346 ctx.Println("Deleted data files.")
347 return
348 }
349
Cole Faustc5bfbdd2025-01-08 13:05:40 -0800350 // Still generate the kati suffix in soong-only builds because soong-only still uses kati for
351 // the packaging step. Also, the kati suffix is used for the combined ninja file.
352 genKatiSuffix(ctx, config)
353
Anton Hansson5a7861a2021-06-04 10:09:01 +0100354 if what&RunSoong != 0 {
Dan Willemsen1e704462016-08-21 15:17:17 -0700355 runSoong(ctx, config)
356 }
357
Anton Hansson5a7861a2021-06-04 10:09:01 +0100358 if what&RunKati != 0 {
Dan Willemsen29971232018-09-26 14:58:30 -0700359 runKatiCleanSpec(ctx, config)
360 runKatiBuild(ctx, config)
Cole Faustc5bfbdd2025-01-08 13:05:40 -0800361 runKatiPackage(ctx, config, false)
Dan Willemsene0879fc2017-08-04 15:06:27 -0700362
Anton Hansson0b55bdb2021-06-04 10:08:08 +0100363 } else if what&RunKatiNinja != 0 {
Dan Willemsene0879fc2017-08-04 15:06:27 -0700364 // Load last Kati Suffix if it exists
Cole Faustc5bfbdd2025-01-08 13:05:40 -0800365 if katiSuffix, err := os.ReadFile(config.LastKatiSuffixFile()); err == nil {
Dan Willemsene0879fc2017-08-04 15:06:27 -0700366 ctx.Verboseln("Loaded previous kati config:", string(katiSuffix))
367 config.SetKatiSuffix(string(katiSuffix))
368 }
Cole Faustc5bfbdd2025-01-08 13:05:40 -0800369 } else if what&RunSoong != 0 {
370 runKatiPackage(ctx, config, true)
Dan Willemsen1e704462016-08-21 15:17:17 -0700371 }
372
Cole Faustc5bfbdd2025-01-08 13:05:40 -0800373 os.WriteFile(config.LastKatiSuffixFile(), []byte(config.KatiSuffix()), 0666) // a+rw
374
Colin Cross37193492017-11-16 17:55:00 -0800375 // Write combined ninja file
376 createCombinedBuildNinjaFile(ctx, config)
377
Colin Cross8ba7d472020-06-25 11:27:52 -0700378 distGzipFile(ctx, config, config.CombinedNinjaFile())
379
Colin Cross37193492017-11-16 17:55:00 -0800380 if what&RunBuildTests != 0 {
381 testForDanglingRules(ctx, config)
382 }
383
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400384 <-rbeCh
Colin Crosse7151f92023-11-28 14:18:12 -0800385 if rbePanic != nil {
386 // If there was a ctx.Fatal in startRBE, rethrow it.
387 panic(rbePanic)
388 }
389
Anton Hansson5a7861a2021-06-04 10:09:01 +0100390 if what&RunNinja != 0 {
391 if what&RunKati != 0 {
Dan Willemsene0879fc2017-08-04 15:06:27 -0700392 installCleanIfNecessary(ctx, config)
393 }
Lukacs T. Berkid1e3f1f2021-03-16 08:55:23 +0100394 runNinjaForBuild(ctx, config)
Peter Collingbourneb805c612024-03-14 21:59:57 -0700395 updateBuildIdDir(ctx, config)
Dan Willemsen1e704462016-08-21 15:17:17 -0700396 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800397
398 if what&RunDistActions != 0 {
399 runDistActions(ctx, config)
400 }
Taylor Santiago3c16e612024-05-30 14:41:31 -0700401 done = true
Dan Willemsen1e704462016-08-21 15:17:17 -0700402}
Colin Cross8ba7d472020-06-25 11:27:52 -0700403
Peter Collingbourneb805c612024-03-14 21:59:57 -0700404func updateBuildIdDir(ctx Context, config Config) {
405 ctx.BeginTrace(metrics.RunShutdownTool, "update_build_id_dir")
406 defer ctx.EndTrace()
407
408 symbolsDir := filepath.Join(config.ProductOut(), "symbols")
409 if err := elf.UpdateBuildIdDir(symbolsDir); err != nil {
410 ctx.Printf("failed to update %s/.build-id: %v", symbolsDir, err)
411 }
412}
413
usta6fffdd52022-09-19 13:16:18 -0400414func evaluateWhatToRun(config Config, verboseln func(v ...interface{})) int {
415 //evaluate what to run
Joe Onorato7f29a662023-02-23 15:47:06 -0800416 what := 0
usta6fffdd52022-09-19 13:16:18 -0400417 if config.Checkbuild() {
418 what |= RunBuildTests
419 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800420 if !config.SkipConfig() {
421 what |= RunProductConfig
422 } else {
usta6fffdd52022-09-19 13:16:18 -0400423 verboseln("Skipping Config as requested")
usta6fffdd52022-09-19 13:16:18 -0400424 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800425 if !config.SkipSoong() {
426 what |= RunSoong
427 } else {
usta6fffdd52022-09-19 13:16:18 -0400428 verboseln("Skipping use of Soong as requested")
usta6fffdd52022-09-19 13:16:18 -0400429 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800430 if !config.SkipKati() {
431 what |= RunKati
432 } else {
433 verboseln("Skipping Kati as requested")
434 }
435 if !config.SkipKatiNinja() {
436 what |= RunKatiNinja
437 } else {
438 verboseln("Skipping use of Kati ninja as requested")
439 }
440 if !config.SkipNinja() {
441 what |= RunNinja
442 } else {
usta6fffdd52022-09-19 13:16:18 -0400443 verboseln("Skipping Ninja as requested")
usta6fffdd52022-09-19 13:16:18 -0400444 }
445
446 if !config.SoongBuildInvocationNeeded() {
447 // This means that the output of soong_build is not needed and thus it would
448 // run unnecessarily. In addition, if this code wasn't there invocations
Joe Onorato35f300d2024-10-21 15:02:44 -0700449 // with only special-cased target names would result in
usta6fffdd52022-09-19 13:16:18 -0400450 // passing Ninja the empty target list and it would then build the default
451 // targets which is not what the user asked for.
452 what = what &^ RunNinja
453 what = what &^ RunKati
454 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800455
456 if config.Dist() {
457 what |= RunDistActions
458 }
459
usta6fffdd52022-09-19 13:16:18 -0400460 return what
461}
462
Dan Willemsen80d72612022-04-20 21:45:00 -0700463var distWaitGroup sync.WaitGroup
464
465// waitForDist waits for all backgrounded distGzipFile and distFile writes to finish
466func waitForDist(ctx Context) {
467 ctx.BeginTrace("soong_ui", "dist")
468 defer ctx.EndTrace()
469
470 distWaitGroup.Wait()
471}
472
Colin Cross8ba7d472020-06-25 11:27:52 -0700473// distGzipFile writes a compressed copy of src to the distDir if dist is enabled. Failures
Dan Willemsen80d72612022-04-20 21:45:00 -0700474// are printed but non-fatal. Uses the distWaitGroup func for backgrounding (optimization).
Colin Cross8ba7d472020-06-25 11:27:52 -0700475func distGzipFile(ctx Context, config Config, src string, subDirs ...string) {
476 if !config.Dist() {
477 return
478 }
479
480 subDir := filepath.Join(subDirs...)
Rupert Shuttleworth3c9f5ac2020-12-10 11:32:38 +0000481 destDir := filepath.Join(config.RealDistDir(), "soong_ui", subDir)
Colin Cross8ba7d472020-06-25 11:27:52 -0700482
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000483 if err := os.MkdirAll(destDir, 0777); err != nil { // a+rwx
Colin Cross8ba7d472020-06-25 11:27:52 -0700484 ctx.Printf("failed to mkdir %s: %s", destDir, err.Error())
Colin Cross8ba7d472020-06-25 11:27:52 -0700485 }
486
Dan Willemsen80d72612022-04-20 21:45:00 -0700487 distWaitGroup.Add(1)
488 go func() {
489 defer distWaitGroup.Done()
490 if err := gzipFileToDir(src, destDir); err != nil {
491 ctx.Printf("failed to dist %s: %s", filepath.Base(src), err.Error())
492 }
493 }()
Colin Cross8ba7d472020-06-25 11:27:52 -0700494}
495
496// distFile writes a copy of src to the distDir if dist is enabled. Failures are printed but
Dan Willemsen80d72612022-04-20 21:45:00 -0700497// non-fatal. Uses the distWaitGroup func for backgrounding (optimization).
Colin Cross8ba7d472020-06-25 11:27:52 -0700498func distFile(ctx Context, config Config, src string, subDirs ...string) {
499 if !config.Dist() {
500 return
501 }
502
503 subDir := filepath.Join(subDirs...)
Rupert Shuttleworth3c9f5ac2020-12-10 11:32:38 +0000504 destDir := filepath.Join(config.RealDistDir(), "soong_ui", subDir)
Colin Cross8ba7d472020-06-25 11:27:52 -0700505
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000506 if err := os.MkdirAll(destDir, 0777); err != nil { // a+rwx
Colin Cross8ba7d472020-06-25 11:27:52 -0700507 ctx.Printf("failed to mkdir %s: %s", destDir, err.Error())
Colin Cross8ba7d472020-06-25 11:27:52 -0700508 }
509
Dan Willemsen80d72612022-04-20 21:45:00 -0700510 distWaitGroup.Add(1)
511 go func() {
512 defer distWaitGroup.Done()
513 if _, err := copyFile(src, filepath.Join(destDir, filepath.Base(src))); err != nil {
514 ctx.Printf("failed to dist %s: %s", filepath.Base(src), err.Error())
515 }
516 }()
Colin Cross8ba7d472020-06-25 11:27:52 -0700517}
Joe Onorato7f29a662023-02-23 15:47:06 -0800518
519// Actions to run on every build where 'dist' is in the actions.
520// Be careful, anything added here slows down EVERY CI build
521func runDistActions(ctx Context, config Config) {
522 runStagingSnapshot(ctx, config)
Joe Onoratod6a29992024-12-06 12:55:41 -0800523 runSourceInputs(ctx, config)
Joe Onorato7f29a662023-02-23 15:47:06 -0800524}