blob: 1dc6dbd8b64a0e6c1bb6f8f1df70521dd504ddcd [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)
Cole Fauste14082c2025-01-06 15:38:34 -080090
91 hostname, ok := config.environ.Get("BUILD_HOSTNAME")
92 if !ok {
93 var err error
94 hostname, err = os.Hostname()
95 if err != nil {
96 ctx.Println("Failed to read hostname:", err)
97 hostname = "unknown"
98 }
99 }
100 writeValueIfChanged(ctx, config, config.SoongOutDir(), "build_hostname.txt", hostname)
Dan Willemsen1e704462016-08-21 15:17:17 -0700101}
102
103var combinedBuildNinjaTemplate = template.Must(template.New("combined").Parse(`
104builddir = {{.OutDir}}
Colin Cross8b8bec32019-11-15 13:18:43 -0800105{{if .UseRemoteBuild }}pool local_pool
Dan Willemsen29971232018-09-26 14:58:30 -0700106 depth = {{.Parallel}}
Colin Cross8b8bec32019-11-15 13:18:43 -0800107{{end -}}
108pool highmem_pool
109 depth = {{.HighmemParallel}}
Anton Hansson0b55bdb2021-06-04 10:08:08 +0100110{{if and (not .SkipKatiNinja) .HasKatiSuffix}}subninja {{.KatiBuildNinjaFile}}
Dan Willemsenfb1271a2018-09-26 15:00:42 -0700111subninja {{.KatiPackageNinjaFile}}
Dan Willemsene0879fc2017-08-04 15:06:27 -0700112{{end -}}
Dan Willemsenfb1271a2018-09-26 15:00:42 -0700113subninja {{.SoongNinjaFile}}
Dan Willemsen1e704462016-08-21 15:17:17 -0700114`))
115
116func createCombinedBuildNinjaFile(ctx Context, config Config) {
Anton Hansson0b55bdb2021-06-04 10:08:08 +0100117 // If we're in SkipKati mode but want to run kati ninja, skip creating this file if it already exists
118 if config.SkipKati() && !config.SkipKatiNinja() {
Dan Willemsene0879fc2017-08-04 15:06:27 -0700119 if _, err := os.Stat(config.CombinedNinjaFile()); err == nil || !os.IsNotExist(err) {
120 return
121 }
122 }
123
Dan Willemsen1e704462016-08-21 15:17:17 -0700124 file, err := os.Create(config.CombinedNinjaFile())
125 if err != nil {
126 ctx.Fatalln("Failed to create combined ninja file:", err)
127 }
128 defer file.Close()
129
130 if err := combinedBuildNinjaTemplate.Execute(file, config); err != nil {
131 ctx.Fatalln("Failed to write combined ninja file:", err)
132 }
133}
134
Sam Delmericod9a34352022-11-15 17:27:21 -0500135// These are bitmasks which can be used to check whether various flags are set
Dan Willemsen1e704462016-08-21 15:17:17 -0700136const (
Anton Hansson5a7861a2021-06-04 10:09:01 +0100137 _ = iota
138 // Whether to run the kati config step.
139 RunProductConfig = 1 << iota
140 // Whether to run soong to generate a ninja file.
141 RunSoong = 1 << iota
142 // Whether to run kati to generate a ninja file.
143 RunKati = 1 << iota
Anton Hansson0b55bdb2021-06-04 10:08:08 +0100144 // Whether to include the kati-generated ninja file in the combined ninja.
145 RunKatiNinja = 1 << iota
Anton Hansson5a7861a2021-06-04 10:09:01 +0100146 // Whether to run ninja on the combined ninja.
Joe Onorato7f29a662023-02-23 15:47:06 -0800147 RunNinja = 1 << iota
148 RunDistActions = 1 << iota
149 RunBuildTests = 1 << iota
Dan Willemsen1e704462016-08-21 15:17:17 -0700150)
151
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000152// 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 +0100153func checkProblematicFiles(ctx Context) {
154 files := []string{"Android.mk", "CleanSpec.mk"}
155 for _, file := range files {
156 if _, err := os.Stat(file); !os.IsNotExist(err) {
157 absolute := absPath(ctx, file)
158 ctx.Printf("Found %s in tree root. This file needs to be removed to build.\n", file)
159 ctx.Fatalf(" rm %s\n", absolute)
160 }
161 }
162}
163
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000164// checkCaseSensitivity issues a warning if a case-insensitive file system is being used.
Dan Willemsendb8457c2017-05-12 16:38:17 -0700165func checkCaseSensitivity(ctx Context, config Config) {
166 outDir := config.OutDir()
167 lowerCase := filepath.Join(outDir, "casecheck.txt")
168 upperCase := filepath.Join(outDir, "CaseCheck.txt")
169 lowerData := "a"
170 upperData := "B"
171
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000172 if err := ioutil.WriteFile(lowerCase, []byte(lowerData), 0666); err != nil { // a+rw
Dan Willemsendb8457c2017-05-12 16:38:17 -0700173 ctx.Fatalln("Failed to check case sensitivity:", err)
174 }
175
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000176 if err := ioutil.WriteFile(upperCase, []byte(upperData), 0666); err != nil { // a+rw
Dan Willemsendb8457c2017-05-12 16:38:17 -0700177 ctx.Fatalln("Failed to check case sensitivity:", err)
178 }
179
180 res, err := ioutil.ReadFile(lowerCase)
181 if err != nil {
182 ctx.Fatalln("Failed to check case sensitivity:", err)
183 }
184
185 if string(res) != lowerData {
186 ctx.Println("************************************************************")
187 ctx.Println("You are building on a case-insensitive filesystem.")
188 ctx.Println("Please move your source tree to a case-sensitive filesystem.")
189 ctx.Println("************************************************************")
190 ctx.Fatalln("Case-insensitive filesystems not supported")
191 }
192}
193
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000194// help prints a help/usage message, via the build/make/help.sh script.
195func help(ctx Context, config Config) {
Jeff Gastondf4a0812017-05-30 20:11:20 -0700196 cmd := Command(ctx, config, "help.sh", "build/make/help.sh")
Dan Willemsenb2e6c2e2017-07-13 17:24:44 -0700197 cmd.Sandbox = dumpvarsSandbox
Dan Willemsenb82471a2018-05-17 16:37:09 -0700198 cmd.RunAndPrintOrFatal()
Dan Willemsen02781d52017-05-12 19:28:13 -0700199}
200
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000201// checkRAM warns if there probably isn't enough RAM to complete a build.
202func checkRAM(ctx Context, config Config) {
Dan Willemsen570a2922020-05-26 23:02:29 -0700203 if totalRAM := config.TotalRAM(); totalRAM != 0 {
204 ram := float32(totalRAM) / (1024 * 1024 * 1024)
205 ctx.Verbosef("Total RAM: %.3vGB", ram)
206
207 if ram <= 16 {
208 ctx.Println("************************************************************")
209 ctx.Printf("You are building on a machine with %.3vGB of RAM\n", ram)
210 ctx.Println("")
211 ctx.Println("The minimum required amount of free memory is around 16GB,")
212 ctx.Println("and even with that, some configurations may not work.")
213 ctx.Println("")
214 ctx.Println("If you run into segfaults or other errors, try reducing your")
215 ctx.Println("-j value.")
216 ctx.Println("************************************************************")
217 } else if ram <= float32(config.Parallel()) {
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000218 // Want at least 1GB of RAM per job.
Dan Willemsen570a2922020-05-26 23:02:29 -0700219 ctx.Printf("Warning: high -j%d count compared to %.3vGB of RAM", config.Parallel(), ram)
220 ctx.Println("If you run into segfaults or other errors, try a lower -j value")
221 }
222 }
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000223}
224
Taylor Santiago3c16e612024-05-30 14:41:31 -0700225func abfsBuildStarted(ctx Context, config Config) {
226 abfsBox := config.PrebuiltBuildTool("abfsbox")
227 cmdArgs := []string{"build-started", "--"}
228 cmdArgs = append(cmdArgs, config.Arguments()...)
229 cmd := Command(ctx, config, "abfsbox", abfsBox, cmdArgs...)
230 cmd.Sandbox = noSandbox
231 cmd.RunAndPrintOrFatal()
232}
233
234func abfsBuildFinished(ctx Context, config Config, finished bool) {
235 var errMsg string
236 if !finished {
237 errMsg = "build was interrupted"
238 }
239 abfsBox := config.PrebuiltBuildTool("abfsbox")
240 cmdArgs := []string{"build-finished", "-e", errMsg, "--"}
241 cmdArgs = append(cmdArgs, config.Arguments()...)
242 cmd := Command(ctx, config, "abfsbox", abfsBox, cmdArgs...)
243 cmd.RunAndPrintOrFatal()
244}
245
Usta Shresthadb46a9b2022-07-11 11:29:56 -0400246// Build the tree. Various flags in `config` govern which components of
247// the build to run.
Anton Hansson5a7861a2021-06-04 10:09:01 +0100248func Build(ctx Context, config Config) {
Taylor Santiago3c16e612024-05-30 14:41:31 -0700249 done := false
250 if config.UseABFS() {
251 abfsBuildStarted(ctx, config)
252 defer func() {
253 abfsBuildFinished(ctx, config, done)
254 }()
255 }
256
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000257 ctx.Verboseln("Starting build with args:", config.Arguments())
258 ctx.Verboseln("Environment:", config.Environment().Environ())
Dan Willemsen1e704462016-08-21 15:17:17 -0700259
Colin Cross74cda722020-01-16 15:25:50 -0800260 ctx.BeginTrace(metrics.Total, "total")
261 defer ctx.EndTrace()
262
Dan Willemsen1e704462016-08-21 15:17:17 -0700263 if inList("help", config.Arguments()) {
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000264 help(ctx, config)
Dan Willemsen0b73b4b2017-05-12 19:28:13 -0700265 return
Dan Willemsen1e704462016-08-21 15:17:17 -0700266 }
267
Jeff Gaston3615fe82017-05-24 13:14:34 -0700268 // Make sure that no other Soong process is running with the same output directory
269 buildLock := BecomeSingletonOrFail(ctx, config)
270 defer buildLock.Unlock()
271
Usta Shrestha675564d2022-08-09 18:03:23 -0400272 logArgsOtherThan := func(specialTargets ...string) {
273 var ignored []string
274 for _, a := range config.Arguments() {
275 if !inList(a, specialTargets) {
276 ignored = append(ignored, a)
277 }
278 }
279 if len(ignored) > 0 {
280 ctx.Printf("ignoring arguments %q", ignored)
281 }
282 }
283
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000284 if inList("clean", config.Arguments()) || inList("clobber", config.Arguments()) {
Usta Shrestha675564d2022-08-09 18:03:23 -0400285 logArgsOtherThan("clean", "clobber")
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000286 clean(ctx, config)
287 return
288 }
289
Dan Willemsen80d72612022-04-20 21:45:00 -0700290 defer waitForDist(ctx)
291
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000292 // 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 +0100293 checkProblematicFiles(ctx)
294
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000295 checkRAM(ctx, config)
296
Dan Willemsen1e704462016-08-21 15:17:17 -0700297 SetupOutDir(ctx, config)
298
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000299 // checkCaseSensitivity issues a warning if a case-insensitive file system is being used.
Dan Willemsendb8457c2017-05-12 16:38:17 -0700300 checkCaseSensitivity(ctx, config)
301
Dan Willemsen18490112018-05-25 16:30:04 -0700302 SetupPath(ctx, config)
303
usta6fffdd52022-09-19 13:16:18 -0400304 what := evaluateWhatToRun(config, ctx.Verboseln)
Lukacs T. Berkia1b93722021-09-02 17:23:06 +0200305
Yoshisato Yanagisawa2cb0e5d2019-01-10 10:14:16 +0900306 if config.StartGoma() {
Yoshisato Yanagisawa2cb0e5d2019-01-10 10:14:16 +0900307 startGoma(ctx, config)
308 }
309
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400310 rbeCh := make(chan bool)
Colin Crosse7151f92023-11-28 14:18:12 -0800311 var rbePanic any
Ramy Medhatbbf25672019-07-17 12:30:04 +0000312 if config.StartRBE() {
Kousik Kumar4c180ad2022-05-27 07:48:37 -0400313 cleanupRBELogsDir(ctx, config)
Colin Crosse7151f92023-11-28 14:18:12 -0800314 checkRBERequirements(ctx, config)
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400315 go func() {
Colin Crosse7151f92023-11-28 14:18:12 -0800316 defer func() {
317 rbePanic = recover()
318 close(rbeCh)
319 }()
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400320 startRBE(ctx, config)
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400321 }()
Kousik Kumara1d8fa92022-03-18 02:50:31 -0400322 defer DumpRBEMetrics(ctx, config, filepath.Join(config.LogsDir(), "rbe_metrics.pb"))
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400323 } else {
324 close(rbeCh)
Ramy Medhatbbf25672019-07-17 12:30:04 +0000325 }
326
Anton Hansson5a7861a2021-06-04 10:09:01 +0100327 if what&RunProductConfig != 0 {
Dan Willemsen1e704462016-08-21 15:17:17 -0700328 runMakeProductConfig(ctx, config)
329 }
330
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000331 // Everything below here depends on product config.
332
Colin Cross806fd942019-05-03 13:35:58 -0700333 if inList("installclean", config.Arguments()) ||
334 inList("install-clean", config.Arguments()) {
Usta Shrestha675564d2022-08-09 18:03:23 -0400335 logArgsOtherThan("installclean", "install-clean")
Rupert Shuttleworth1f304e62020-11-24 14:13:41 +0000336 installClean(ctx, config)
Dan Willemsenf052f782017-05-18 15:29:04 -0700337 ctx.Println("Deleted images and staging directories.")
338 return
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000339 }
340
341 if inList("dataclean", config.Arguments()) ||
Colin Cross806fd942019-05-03 13:35:58 -0700342 inList("data-clean", config.Arguments()) {
Usta Shrestha675564d2022-08-09 18:03:23 -0400343 logArgsOtherThan("dataclean", "data-clean")
Rupert Shuttleworth1f304e62020-11-24 14:13:41 +0000344 dataClean(ctx, config)
Dan Willemsenf052f782017-05-18 15:29:04 -0700345 ctx.Println("Deleted data files.")
346 return
347 }
348
Anton Hansson5a7861a2021-06-04 10:09:01 +0100349 if what&RunSoong != 0 {
Dan Willemsen1e704462016-08-21 15:17:17 -0700350 runSoong(ctx, config)
351 }
352
Anton Hansson5a7861a2021-06-04 10:09:01 +0100353 if what&RunKati != 0 {
Dan Willemsen29971232018-09-26 14:58:30 -0700354 genKatiSuffix(ctx, config)
355 runKatiCleanSpec(ctx, config)
356 runKatiBuild(ctx, config)
Dan Willemsenfb1271a2018-09-26 15:00:42 -0700357 runKatiPackage(ctx, config)
Dan Willemsene0879fc2017-08-04 15:06:27 -0700358
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000359 ioutil.WriteFile(config.LastKatiSuffixFile(), []byte(config.KatiSuffix()), 0666) // a+rw
Anton Hansson0b55bdb2021-06-04 10:08:08 +0100360 } else if what&RunKatiNinja != 0 {
Dan Willemsene0879fc2017-08-04 15:06:27 -0700361 // Load last Kati Suffix if it exists
362 if katiSuffix, err := ioutil.ReadFile(config.LastKatiSuffixFile()); err == nil {
363 ctx.Verboseln("Loaded previous kati config:", string(katiSuffix))
364 config.SetKatiSuffix(string(katiSuffix))
365 }
Dan Willemsen1e704462016-08-21 15:17:17 -0700366 }
367
Colin Cross37193492017-11-16 17:55:00 -0800368 // Write combined ninja file
369 createCombinedBuildNinjaFile(ctx, config)
370
Colin Cross8ba7d472020-06-25 11:27:52 -0700371 distGzipFile(ctx, config, config.CombinedNinjaFile())
372
Colin Cross37193492017-11-16 17:55:00 -0800373 if what&RunBuildTests != 0 {
374 testForDanglingRules(ctx, config)
375 }
376
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400377 <-rbeCh
Colin Crosse7151f92023-11-28 14:18:12 -0800378 if rbePanic != nil {
379 // If there was a ctx.Fatal in startRBE, rethrow it.
380 panic(rbePanic)
381 }
382
Anton Hansson5a7861a2021-06-04 10:09:01 +0100383 if what&RunNinja != 0 {
384 if what&RunKati != 0 {
Dan Willemsene0879fc2017-08-04 15:06:27 -0700385 installCleanIfNecessary(ctx, config)
386 }
Lukacs T. Berkid1e3f1f2021-03-16 08:55:23 +0100387 runNinjaForBuild(ctx, config)
Peter Collingbourneb805c612024-03-14 21:59:57 -0700388 updateBuildIdDir(ctx, config)
Dan Willemsen1e704462016-08-21 15:17:17 -0700389 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800390
391 if what&RunDistActions != 0 {
392 runDistActions(ctx, config)
393 }
Taylor Santiago3c16e612024-05-30 14:41:31 -0700394 done = true
Dan Willemsen1e704462016-08-21 15:17:17 -0700395}
Colin Cross8ba7d472020-06-25 11:27:52 -0700396
Peter Collingbourneb805c612024-03-14 21:59:57 -0700397func updateBuildIdDir(ctx Context, config Config) {
398 ctx.BeginTrace(metrics.RunShutdownTool, "update_build_id_dir")
399 defer ctx.EndTrace()
400
401 symbolsDir := filepath.Join(config.ProductOut(), "symbols")
402 if err := elf.UpdateBuildIdDir(symbolsDir); err != nil {
403 ctx.Printf("failed to update %s/.build-id: %v", symbolsDir, err)
404 }
405}
406
usta6fffdd52022-09-19 13:16:18 -0400407func evaluateWhatToRun(config Config, verboseln func(v ...interface{})) int {
408 //evaluate what to run
Joe Onorato7f29a662023-02-23 15:47:06 -0800409 what := 0
usta6fffdd52022-09-19 13:16:18 -0400410 if config.Checkbuild() {
411 what |= RunBuildTests
412 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800413 if !config.SkipConfig() {
414 what |= RunProductConfig
415 } else {
usta6fffdd52022-09-19 13:16:18 -0400416 verboseln("Skipping Config as requested")
usta6fffdd52022-09-19 13:16:18 -0400417 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800418 if !config.SkipSoong() {
419 what |= RunSoong
420 } else {
usta6fffdd52022-09-19 13:16:18 -0400421 verboseln("Skipping use of Soong as requested")
usta6fffdd52022-09-19 13:16:18 -0400422 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800423 if !config.SkipKati() {
424 what |= RunKati
425 } else {
426 verboseln("Skipping Kati as requested")
427 }
428 if !config.SkipKatiNinja() {
429 what |= RunKatiNinja
430 } else {
431 verboseln("Skipping use of Kati ninja as requested")
432 }
433 if !config.SkipNinja() {
434 what |= RunNinja
435 } else {
usta6fffdd52022-09-19 13:16:18 -0400436 verboseln("Skipping Ninja as requested")
usta6fffdd52022-09-19 13:16:18 -0400437 }
438
439 if !config.SoongBuildInvocationNeeded() {
440 // This means that the output of soong_build is not needed and thus it would
441 // run unnecessarily. In addition, if this code wasn't there invocations
Joe Onorato35f300d2024-10-21 15:02:44 -0700442 // with only special-cased target names would result in
usta6fffdd52022-09-19 13:16:18 -0400443 // passing Ninja the empty target list and it would then build the default
444 // targets which is not what the user asked for.
445 what = what &^ RunNinja
446 what = what &^ RunKati
447 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800448
449 if config.Dist() {
450 what |= RunDistActions
451 }
452
usta6fffdd52022-09-19 13:16:18 -0400453 return what
454}
455
Dan Willemsen80d72612022-04-20 21:45:00 -0700456var distWaitGroup sync.WaitGroup
457
458// waitForDist waits for all backgrounded distGzipFile and distFile writes to finish
459func waitForDist(ctx Context) {
460 ctx.BeginTrace("soong_ui", "dist")
461 defer ctx.EndTrace()
462
463 distWaitGroup.Wait()
464}
465
Colin Cross8ba7d472020-06-25 11:27:52 -0700466// distGzipFile writes a compressed copy of src to the distDir if dist is enabled. Failures
Dan Willemsen80d72612022-04-20 21:45:00 -0700467// are printed but non-fatal. Uses the distWaitGroup func for backgrounding (optimization).
Colin Cross8ba7d472020-06-25 11:27:52 -0700468func distGzipFile(ctx Context, config Config, src string, subDirs ...string) {
469 if !config.Dist() {
470 return
471 }
472
473 subDir := filepath.Join(subDirs...)
Rupert Shuttleworth3c9f5ac2020-12-10 11:32:38 +0000474 destDir := filepath.Join(config.RealDistDir(), "soong_ui", subDir)
Colin Cross8ba7d472020-06-25 11:27:52 -0700475
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000476 if err := os.MkdirAll(destDir, 0777); err != nil { // a+rwx
Colin Cross8ba7d472020-06-25 11:27:52 -0700477 ctx.Printf("failed to mkdir %s: %s", destDir, err.Error())
Colin Cross8ba7d472020-06-25 11:27:52 -0700478 }
479
Dan Willemsen80d72612022-04-20 21:45:00 -0700480 distWaitGroup.Add(1)
481 go func() {
482 defer distWaitGroup.Done()
483 if err := gzipFileToDir(src, destDir); err != nil {
484 ctx.Printf("failed to dist %s: %s", filepath.Base(src), err.Error())
485 }
486 }()
Colin Cross8ba7d472020-06-25 11:27:52 -0700487}
488
489// distFile writes a copy of src to the distDir if dist is enabled. Failures are printed but
Dan Willemsen80d72612022-04-20 21:45:00 -0700490// non-fatal. Uses the distWaitGroup func for backgrounding (optimization).
Colin Cross8ba7d472020-06-25 11:27:52 -0700491func distFile(ctx Context, config Config, src string, subDirs ...string) {
492 if !config.Dist() {
493 return
494 }
495
496 subDir := filepath.Join(subDirs...)
Rupert Shuttleworth3c9f5ac2020-12-10 11:32:38 +0000497 destDir := filepath.Join(config.RealDistDir(), "soong_ui", subDir)
Colin Cross8ba7d472020-06-25 11:27:52 -0700498
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000499 if err := os.MkdirAll(destDir, 0777); err != nil { // a+rwx
Colin Cross8ba7d472020-06-25 11:27:52 -0700500 ctx.Printf("failed to mkdir %s: %s", destDir, err.Error())
Colin Cross8ba7d472020-06-25 11:27:52 -0700501 }
502
Dan Willemsen80d72612022-04-20 21:45:00 -0700503 distWaitGroup.Add(1)
504 go func() {
505 defer distWaitGroup.Done()
506 if _, err := copyFile(src, filepath.Join(destDir, filepath.Base(src))); err != nil {
507 ctx.Printf("failed to dist %s: %s", filepath.Base(src), err.Error())
508 }
509 }()
Colin Cross8ba7d472020-06-25 11:27:52 -0700510}
Joe Onorato7f29a662023-02-23 15:47:06 -0800511
512// Actions to run on every build where 'dist' is in the actions.
513// Be careful, anything added here slows down EVERY CI build
514func runDistActions(ctx Context, config Config) {
515 runStagingSnapshot(ctx, config)
Joe Onoratod6a29992024-12-06 12:55:41 -0800516 runSourceInputs(ctx, config)
Joe Onorato7f29a662023-02-23 15:47:06 -0800517}