blob: 26f59692f44a8b1da3e829756b3a782e0c410022 [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}}
Cole Faustc5bfbdd2025-01-08 13:05:40 -0800110{{if and (not .SkipKatiNinja) .HasKatiSuffix}}
111subninja {{.KatiBuildNinjaFile}}
Dan Willemsenfb1271a2018-09-26 15:00:42 -0700112subninja {{.KatiPackageNinjaFile}}
Cole Faustc5bfbdd2025-01-08 13:05:40 -0800113{{else}}
114subninja {{.KatiSoongOnlyPackageNinjaFile}}
Dan Willemsene0879fc2017-08-04 15:06:27 -0700115{{end -}}
Dan Willemsenfb1271a2018-09-26 15:00:42 -0700116subninja {{.SoongNinjaFile}}
Dan Willemsen1e704462016-08-21 15:17:17 -0700117`))
118
119func createCombinedBuildNinjaFile(ctx Context, config Config) {
Anton Hansson0b55bdb2021-06-04 10:08:08 +0100120 // If we're in SkipKati mode but want to run kati ninja, skip creating this file if it already exists
121 if config.SkipKati() && !config.SkipKatiNinja() {
Dan Willemsene0879fc2017-08-04 15:06:27 -0700122 if _, err := os.Stat(config.CombinedNinjaFile()); err == nil || !os.IsNotExist(err) {
123 return
124 }
125 }
126
Dan Willemsen1e704462016-08-21 15:17:17 -0700127 file, err := os.Create(config.CombinedNinjaFile())
128 if err != nil {
129 ctx.Fatalln("Failed to create combined ninja file:", err)
130 }
131 defer file.Close()
132
133 if err := combinedBuildNinjaTemplate.Execute(file, config); err != nil {
134 ctx.Fatalln("Failed to write combined ninja file:", err)
135 }
136}
137
Sam Delmericod9a34352022-11-15 17:27:21 -0500138// These are bitmasks which can be used to check whether various flags are set
Dan Willemsen1e704462016-08-21 15:17:17 -0700139const (
Anton Hansson5a7861a2021-06-04 10:09:01 +0100140 _ = iota
141 // Whether to run the kati config step.
142 RunProductConfig = 1 << iota
143 // Whether to run soong to generate a ninja file.
144 RunSoong = 1 << iota
145 // Whether to run kati to generate a ninja file.
146 RunKati = 1 << iota
Anton Hansson0b55bdb2021-06-04 10:08:08 +0100147 // Whether to include the kati-generated ninja file in the combined ninja.
148 RunKatiNinja = 1 << iota
Anton Hansson5a7861a2021-06-04 10:09:01 +0100149 // Whether to run ninja on the combined ninja.
Joe Onorato7f29a662023-02-23 15:47:06 -0800150 RunNinja = 1 << iota
151 RunDistActions = 1 << iota
152 RunBuildTests = 1 << iota
Dan Willemsen1e704462016-08-21 15:17:17 -0700153)
154
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000155// 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 +0100156func checkProblematicFiles(ctx Context) {
157 files := []string{"Android.mk", "CleanSpec.mk"}
158 for _, file := range files {
159 if _, err := os.Stat(file); !os.IsNotExist(err) {
160 absolute := absPath(ctx, file)
161 ctx.Printf("Found %s in tree root. This file needs to be removed to build.\n", file)
162 ctx.Fatalf(" rm %s\n", absolute)
163 }
164 }
165}
166
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000167// checkCaseSensitivity issues a warning if a case-insensitive file system is being used.
Dan Willemsendb8457c2017-05-12 16:38:17 -0700168func checkCaseSensitivity(ctx Context, config Config) {
169 outDir := config.OutDir()
170 lowerCase := filepath.Join(outDir, "casecheck.txt")
171 upperCase := filepath.Join(outDir, "CaseCheck.txt")
172 lowerData := "a"
173 upperData := "B"
174
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000175 if err := ioutil.WriteFile(lowerCase, []byte(lowerData), 0666); err != nil { // a+rw
Dan Willemsendb8457c2017-05-12 16:38:17 -0700176 ctx.Fatalln("Failed to check case sensitivity:", err)
177 }
178
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000179 if err := ioutil.WriteFile(upperCase, []byte(upperData), 0666); err != nil { // a+rw
Dan Willemsendb8457c2017-05-12 16:38:17 -0700180 ctx.Fatalln("Failed to check case sensitivity:", err)
181 }
182
183 res, err := ioutil.ReadFile(lowerCase)
184 if err != nil {
185 ctx.Fatalln("Failed to check case sensitivity:", err)
186 }
187
188 if string(res) != lowerData {
189 ctx.Println("************************************************************")
190 ctx.Println("You are building on a case-insensitive filesystem.")
191 ctx.Println("Please move your source tree to a case-sensitive filesystem.")
192 ctx.Println("************************************************************")
193 ctx.Fatalln("Case-insensitive filesystems not supported")
194 }
195}
196
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000197// help prints a help/usage message, via the build/make/help.sh script.
198func help(ctx Context, config Config) {
Jeff Gastondf4a0812017-05-30 20:11:20 -0700199 cmd := Command(ctx, config, "help.sh", "build/make/help.sh")
Dan Willemsenb2e6c2e2017-07-13 17:24:44 -0700200 cmd.Sandbox = dumpvarsSandbox
Dan Willemsenb82471a2018-05-17 16:37:09 -0700201 cmd.RunAndPrintOrFatal()
Dan Willemsen02781d52017-05-12 19:28:13 -0700202}
203
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000204// checkRAM warns if there probably isn't enough RAM to complete a build.
205func checkRAM(ctx Context, config Config) {
Dan Willemsen570a2922020-05-26 23:02:29 -0700206 if totalRAM := config.TotalRAM(); totalRAM != 0 {
207 ram := float32(totalRAM) / (1024 * 1024 * 1024)
208 ctx.Verbosef("Total RAM: %.3vGB", ram)
209
210 if ram <= 16 {
211 ctx.Println("************************************************************")
212 ctx.Printf("You are building on a machine with %.3vGB of RAM\n", ram)
213 ctx.Println("")
214 ctx.Println("The minimum required amount of free memory is around 16GB,")
215 ctx.Println("and even with that, some configurations may not work.")
216 ctx.Println("")
217 ctx.Println("If you run into segfaults or other errors, try reducing your")
218 ctx.Println("-j value.")
219 ctx.Println("************************************************************")
220 } else if ram <= float32(config.Parallel()) {
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000221 // Want at least 1GB of RAM per job.
Dan Willemsen570a2922020-05-26 23:02:29 -0700222 ctx.Printf("Warning: high -j%d count compared to %.3vGB of RAM", config.Parallel(), ram)
223 ctx.Println("If you run into segfaults or other errors, try a lower -j value")
224 }
225 }
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000226}
227
Taylor Santiago3c16e612024-05-30 14:41:31 -0700228func abfsBuildStarted(ctx Context, config Config) {
229 abfsBox := config.PrebuiltBuildTool("abfsbox")
230 cmdArgs := []string{"build-started", "--"}
231 cmdArgs = append(cmdArgs, config.Arguments()...)
232 cmd := Command(ctx, config, "abfsbox", abfsBox, cmdArgs...)
233 cmd.Sandbox = noSandbox
234 cmd.RunAndPrintOrFatal()
235}
236
237func abfsBuildFinished(ctx Context, config Config, finished bool) {
238 var errMsg string
239 if !finished {
240 errMsg = "build was interrupted"
241 }
242 abfsBox := config.PrebuiltBuildTool("abfsbox")
243 cmdArgs := []string{"build-finished", "-e", errMsg, "--"}
244 cmdArgs = append(cmdArgs, config.Arguments()...)
245 cmd := Command(ctx, config, "abfsbox", abfsBox, cmdArgs...)
246 cmd.RunAndPrintOrFatal()
247}
248
Usta Shresthadb46a9b2022-07-11 11:29:56 -0400249// Build the tree. Various flags in `config` govern which components of
250// the build to run.
Anton Hansson5a7861a2021-06-04 10:09:01 +0100251func Build(ctx Context, config Config) {
Taylor Santiago3c16e612024-05-30 14:41:31 -0700252 done := false
253 if config.UseABFS() {
254 abfsBuildStarted(ctx, config)
255 defer func() {
256 abfsBuildFinished(ctx, config, done)
257 }()
258 }
259
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000260 ctx.Verboseln("Starting build with args:", config.Arguments())
261 ctx.Verboseln("Environment:", config.Environment().Environ())
Dan Willemsen1e704462016-08-21 15:17:17 -0700262
Colin Cross74cda722020-01-16 15:25:50 -0800263 ctx.BeginTrace(metrics.Total, "total")
264 defer ctx.EndTrace()
265
Dan Willemsen1e704462016-08-21 15:17:17 -0700266 if inList("help", config.Arguments()) {
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000267 help(ctx, config)
Dan Willemsen0b73b4b2017-05-12 19:28:13 -0700268 return
Dan Willemsen1e704462016-08-21 15:17:17 -0700269 }
270
Jeff Gaston3615fe82017-05-24 13:14:34 -0700271 // Make sure that no other Soong process is running with the same output directory
272 buildLock := BecomeSingletonOrFail(ctx, config)
273 defer buildLock.Unlock()
274
Usta Shrestha675564d2022-08-09 18:03:23 -0400275 logArgsOtherThan := func(specialTargets ...string) {
276 var ignored []string
277 for _, a := range config.Arguments() {
278 if !inList(a, specialTargets) {
279 ignored = append(ignored, a)
280 }
281 }
282 if len(ignored) > 0 {
283 ctx.Printf("ignoring arguments %q", ignored)
284 }
285 }
286
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000287 if inList("clean", config.Arguments()) || inList("clobber", config.Arguments()) {
Usta Shrestha675564d2022-08-09 18:03:23 -0400288 logArgsOtherThan("clean", "clobber")
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000289 clean(ctx, config)
290 return
291 }
292
Dan Willemsen80d72612022-04-20 21:45:00 -0700293 defer waitForDist(ctx)
294
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000295 // 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 +0100296 checkProblematicFiles(ctx)
297
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000298 checkRAM(ctx, config)
299
Dan Willemsen1e704462016-08-21 15:17:17 -0700300 SetupOutDir(ctx, config)
301
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000302 // checkCaseSensitivity issues a warning if a case-insensitive file system is being used.
Dan Willemsendb8457c2017-05-12 16:38:17 -0700303 checkCaseSensitivity(ctx, config)
304
Dan Willemsen18490112018-05-25 16:30:04 -0700305 SetupPath(ctx, config)
306
usta6fffdd52022-09-19 13:16:18 -0400307 what := evaluateWhatToRun(config, ctx.Verboseln)
Lukacs T. Berkia1b93722021-09-02 17:23:06 +0200308
Yoshisato Yanagisawa2cb0e5d2019-01-10 10:14:16 +0900309 if config.StartGoma() {
Yoshisato Yanagisawa2cb0e5d2019-01-10 10:14:16 +0900310 startGoma(ctx, config)
311 }
312
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400313 rbeCh := make(chan bool)
Colin Crosse7151f92023-11-28 14:18:12 -0800314 var rbePanic any
Ramy Medhatbbf25672019-07-17 12:30:04 +0000315 if config.StartRBE() {
Kousik Kumar4c180ad2022-05-27 07:48:37 -0400316 cleanupRBELogsDir(ctx, config)
Colin Crosse7151f92023-11-28 14:18:12 -0800317 checkRBERequirements(ctx, config)
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400318 go func() {
Colin Crosse7151f92023-11-28 14:18:12 -0800319 defer func() {
320 rbePanic = recover()
321 close(rbeCh)
322 }()
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400323 startRBE(ctx, config)
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400324 }()
Kousik Kumara1d8fa92022-03-18 02:50:31 -0400325 defer DumpRBEMetrics(ctx, config, filepath.Join(config.LogsDir(), "rbe_metrics.pb"))
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400326 } else {
327 close(rbeCh)
Ramy Medhatbbf25672019-07-17 12:30:04 +0000328 }
329
Anton Hansson5a7861a2021-06-04 10:09:01 +0100330 if what&RunProductConfig != 0 {
Dan Willemsen1e704462016-08-21 15:17:17 -0700331 runMakeProductConfig(ctx, config)
332 }
333
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000334 // Everything below here depends on product config.
335
Colin Cross806fd942019-05-03 13:35:58 -0700336 if inList("installclean", config.Arguments()) ||
337 inList("install-clean", config.Arguments()) {
Usta Shrestha675564d2022-08-09 18:03:23 -0400338 logArgsOtherThan("installclean", "install-clean")
Rupert Shuttleworth1f304e62020-11-24 14:13:41 +0000339 installClean(ctx, config)
Dan Willemsenf052f782017-05-18 15:29:04 -0700340 ctx.Println("Deleted images and staging directories.")
341 return
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000342 }
343
344 if inList("dataclean", config.Arguments()) ||
Colin Cross806fd942019-05-03 13:35:58 -0700345 inList("data-clean", config.Arguments()) {
Usta Shrestha675564d2022-08-09 18:03:23 -0400346 logArgsOtherThan("dataclean", "data-clean")
Rupert Shuttleworth1f304e62020-11-24 14:13:41 +0000347 dataClean(ctx, config)
Dan Willemsenf052f782017-05-18 15:29:04 -0700348 ctx.Println("Deleted data files.")
349 return
350 }
351
Cole Faustc5bfbdd2025-01-08 13:05:40 -0800352 // Still generate the kati suffix in soong-only builds because soong-only still uses kati for
353 // the packaging step. Also, the kati suffix is used for the combined ninja file.
354 genKatiSuffix(ctx, config)
355
Anton Hansson5a7861a2021-06-04 10:09:01 +0100356 if what&RunSoong != 0 {
Dan Willemsen1e704462016-08-21 15:17:17 -0700357 runSoong(ctx, config)
358 }
359
Anton Hansson5a7861a2021-06-04 10:09:01 +0100360 if what&RunKati != 0 {
Dan Willemsen29971232018-09-26 14:58:30 -0700361 runKatiCleanSpec(ctx, config)
362 runKatiBuild(ctx, config)
Cole Faustc5bfbdd2025-01-08 13:05:40 -0800363 runKatiPackage(ctx, config, false)
Dan Willemsene0879fc2017-08-04 15:06:27 -0700364
Anton Hansson0b55bdb2021-06-04 10:08:08 +0100365 } else if what&RunKatiNinja != 0 {
Dan Willemsene0879fc2017-08-04 15:06:27 -0700366 // Load last Kati Suffix if it exists
Cole Faustc5bfbdd2025-01-08 13:05:40 -0800367 if katiSuffix, err := os.ReadFile(config.LastKatiSuffixFile()); err == nil {
Dan Willemsene0879fc2017-08-04 15:06:27 -0700368 ctx.Verboseln("Loaded previous kati config:", string(katiSuffix))
369 config.SetKatiSuffix(string(katiSuffix))
370 }
Cole Faustc5bfbdd2025-01-08 13:05:40 -0800371 } else if what&RunSoong != 0 {
372 runKatiPackage(ctx, config, true)
Dan Willemsen1e704462016-08-21 15:17:17 -0700373 }
374
Cole Faustc5bfbdd2025-01-08 13:05:40 -0800375 os.WriteFile(config.LastKatiSuffixFile(), []byte(config.KatiSuffix()), 0666) // a+rw
376
Colin Cross37193492017-11-16 17:55:00 -0800377 // Write combined ninja file
378 createCombinedBuildNinjaFile(ctx, config)
379
Colin Cross8ba7d472020-06-25 11:27:52 -0700380 distGzipFile(ctx, config, config.CombinedNinjaFile())
381
Colin Cross37193492017-11-16 17:55:00 -0800382 if what&RunBuildTests != 0 {
383 testForDanglingRules(ctx, config)
384 }
385
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400386 <-rbeCh
Colin Crosse7151f92023-11-28 14:18:12 -0800387 if rbePanic != nil {
388 // If there was a ctx.Fatal in startRBE, rethrow it.
389 panic(rbePanic)
390 }
391
Anton Hansson5a7861a2021-06-04 10:09:01 +0100392 if what&RunNinja != 0 {
393 if what&RunKati != 0 {
Dan Willemsene0879fc2017-08-04 15:06:27 -0700394 installCleanIfNecessary(ctx, config)
395 }
Lukacs T. Berkid1e3f1f2021-03-16 08:55:23 +0100396 runNinjaForBuild(ctx, config)
Peter Collingbourneb805c612024-03-14 21:59:57 -0700397 updateBuildIdDir(ctx, config)
Dan Willemsen1e704462016-08-21 15:17:17 -0700398 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800399
400 if what&RunDistActions != 0 {
401 runDistActions(ctx, config)
402 }
Taylor Santiago3c16e612024-05-30 14:41:31 -0700403 done = true
Dan Willemsen1e704462016-08-21 15:17:17 -0700404}
Colin Cross8ba7d472020-06-25 11:27:52 -0700405
Peter Collingbourneb805c612024-03-14 21:59:57 -0700406func updateBuildIdDir(ctx Context, config Config) {
407 ctx.BeginTrace(metrics.RunShutdownTool, "update_build_id_dir")
408 defer ctx.EndTrace()
409
410 symbolsDir := filepath.Join(config.ProductOut(), "symbols")
411 if err := elf.UpdateBuildIdDir(symbolsDir); err != nil {
412 ctx.Printf("failed to update %s/.build-id: %v", symbolsDir, err)
413 }
414}
415
usta6fffdd52022-09-19 13:16:18 -0400416func evaluateWhatToRun(config Config, verboseln func(v ...interface{})) int {
417 //evaluate what to run
Joe Onorato7f29a662023-02-23 15:47:06 -0800418 what := 0
usta6fffdd52022-09-19 13:16:18 -0400419 if config.Checkbuild() {
420 what |= RunBuildTests
421 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800422 if !config.SkipConfig() {
423 what |= RunProductConfig
424 } else {
usta6fffdd52022-09-19 13:16:18 -0400425 verboseln("Skipping Config as requested")
usta6fffdd52022-09-19 13:16:18 -0400426 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800427 if !config.SkipSoong() {
428 what |= RunSoong
429 } else {
usta6fffdd52022-09-19 13:16:18 -0400430 verboseln("Skipping use of Soong as requested")
usta6fffdd52022-09-19 13:16:18 -0400431 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800432 if !config.SkipKati() {
433 what |= RunKati
434 } else {
435 verboseln("Skipping Kati as requested")
436 }
437 if !config.SkipKatiNinja() {
438 what |= RunKatiNinja
439 } else {
440 verboseln("Skipping use of Kati ninja as requested")
441 }
442 if !config.SkipNinja() {
443 what |= RunNinja
444 } else {
usta6fffdd52022-09-19 13:16:18 -0400445 verboseln("Skipping Ninja as requested")
usta6fffdd52022-09-19 13:16:18 -0400446 }
447
448 if !config.SoongBuildInvocationNeeded() {
449 // This means that the output of soong_build is not needed and thus it would
450 // run unnecessarily. In addition, if this code wasn't there invocations
Joe Onorato35f300d2024-10-21 15:02:44 -0700451 // with only special-cased target names would result in
usta6fffdd52022-09-19 13:16:18 -0400452 // passing Ninja the empty target list and it would then build the default
453 // targets which is not what the user asked for.
454 what = what &^ RunNinja
455 what = what &^ RunKati
456 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800457
458 if config.Dist() {
459 what |= RunDistActions
460 }
461
usta6fffdd52022-09-19 13:16:18 -0400462 return what
463}
464
Dan Willemsen80d72612022-04-20 21:45:00 -0700465var distWaitGroup sync.WaitGroup
466
467// waitForDist waits for all backgrounded distGzipFile and distFile writes to finish
468func waitForDist(ctx Context) {
469 ctx.BeginTrace("soong_ui", "dist")
470 defer ctx.EndTrace()
471
472 distWaitGroup.Wait()
473}
474
Colin Cross8ba7d472020-06-25 11:27:52 -0700475// distGzipFile writes a compressed copy of src to the distDir if dist is enabled. Failures
Dan Willemsen80d72612022-04-20 21:45:00 -0700476// are printed but non-fatal. Uses the distWaitGroup func for backgrounding (optimization).
Colin Cross8ba7d472020-06-25 11:27:52 -0700477func distGzipFile(ctx Context, config Config, src string, subDirs ...string) {
478 if !config.Dist() {
479 return
480 }
481
482 subDir := filepath.Join(subDirs...)
Rupert Shuttleworth3c9f5ac2020-12-10 11:32:38 +0000483 destDir := filepath.Join(config.RealDistDir(), "soong_ui", subDir)
Colin Cross8ba7d472020-06-25 11:27:52 -0700484
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000485 if err := os.MkdirAll(destDir, 0777); err != nil { // a+rwx
Colin Cross8ba7d472020-06-25 11:27:52 -0700486 ctx.Printf("failed to mkdir %s: %s", destDir, err.Error())
Colin Cross8ba7d472020-06-25 11:27:52 -0700487 }
488
Dan Willemsen80d72612022-04-20 21:45:00 -0700489 distWaitGroup.Add(1)
490 go func() {
491 defer distWaitGroup.Done()
492 if err := gzipFileToDir(src, destDir); err != nil {
493 ctx.Printf("failed to dist %s: %s", filepath.Base(src), err.Error())
494 }
495 }()
Colin Cross8ba7d472020-06-25 11:27:52 -0700496}
497
498// distFile writes a copy of src to the distDir if dist is enabled. Failures are printed but
Dan Willemsen80d72612022-04-20 21:45:00 -0700499// non-fatal. Uses the distWaitGroup func for backgrounding (optimization).
Colin Cross8ba7d472020-06-25 11:27:52 -0700500func distFile(ctx Context, config Config, src string, subDirs ...string) {
501 if !config.Dist() {
502 return
503 }
504
505 subDir := filepath.Join(subDirs...)
Rupert Shuttleworth3c9f5ac2020-12-10 11:32:38 +0000506 destDir := filepath.Join(config.RealDistDir(), "soong_ui", subDir)
Colin Cross8ba7d472020-06-25 11:27:52 -0700507
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000508 if err := os.MkdirAll(destDir, 0777); err != nil { // a+rwx
Colin Cross8ba7d472020-06-25 11:27:52 -0700509 ctx.Printf("failed to mkdir %s: %s", destDir, err.Error())
Colin Cross8ba7d472020-06-25 11:27:52 -0700510 }
511
Dan Willemsen80d72612022-04-20 21:45:00 -0700512 distWaitGroup.Add(1)
513 go func() {
514 defer distWaitGroup.Done()
515 if _, err := copyFile(src, filepath.Join(destDir, filepath.Base(src))); err != nil {
516 ctx.Printf("failed to dist %s: %s", filepath.Base(src), err.Error())
517 }
518 }()
Colin Cross8ba7d472020-06-25 11:27:52 -0700519}
Joe Onorato7f29a662023-02-23 15:47:06 -0800520
521// Actions to run on every build where 'dist' is in the actions.
522// Be careful, anything added here slows down EVERY CI build
523func runDistActions(ctx Context, config Config) {
524 runStagingSnapshot(ctx, config)
Joe Onoratod6a29992024-12-06 12:55:41 -0800525 runSourceInputs(ctx, config)
Joe Onorato7f29a662023-02-23 15:47:06 -0800526}