blob: c7319ed338d775227cca7e5e77034f2ac3228ea7 [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 Faust1ae7b772024-06-12 18:08:44 -070083 buildNumber = fmt.Sprintf("eng.%.6s.00000000.000000", username)
Cole Faust583dfb42023-09-28 13:56:30 -070084 writeValueIfChanged(ctx, config, config.OutDir(), "file_name_tag.txt", username)
85 }
86 // Write the build number to a file so it can be read back in
87 // without changing the command line every time. Avoids rebuilds
88 // when using ninja.
89 writeValueIfChanged(ctx, config, config.SoongOutDir(), "build_number.txt", buildNumber)
Dan Willemsen1e704462016-08-21 15:17:17 -070090}
91
92var combinedBuildNinjaTemplate = template.Must(template.New("combined").Parse(`
93builddir = {{.OutDir}}
Colin Cross8b8bec32019-11-15 13:18:43 -080094{{if .UseRemoteBuild }}pool local_pool
Dan Willemsen29971232018-09-26 14:58:30 -070095 depth = {{.Parallel}}
Colin Cross8b8bec32019-11-15 13:18:43 -080096{{end -}}
97pool highmem_pool
98 depth = {{.HighmemParallel}}
Anton Hansson0b55bdb2021-06-04 10:08:08 +010099{{if and (not .SkipKatiNinja) .HasKatiSuffix}}subninja {{.KatiBuildNinjaFile}}
Dan Willemsenfb1271a2018-09-26 15:00:42 -0700100subninja {{.KatiPackageNinjaFile}}
Dan Willemsene0879fc2017-08-04 15:06:27 -0700101{{end -}}
Dan Willemsenfb1271a2018-09-26 15:00:42 -0700102subninja {{.SoongNinjaFile}}
Dan Willemsen1e704462016-08-21 15:17:17 -0700103`))
104
105func createCombinedBuildNinjaFile(ctx Context, config Config) {
Anton Hansson0b55bdb2021-06-04 10:08:08 +0100106 // If we're in SkipKati mode but want to run kati ninja, skip creating this file if it already exists
107 if config.SkipKati() && !config.SkipKatiNinja() {
Dan Willemsene0879fc2017-08-04 15:06:27 -0700108 if _, err := os.Stat(config.CombinedNinjaFile()); err == nil || !os.IsNotExist(err) {
109 return
110 }
111 }
112
Dan Willemsen1e704462016-08-21 15:17:17 -0700113 file, err := os.Create(config.CombinedNinjaFile())
114 if err != nil {
115 ctx.Fatalln("Failed to create combined ninja file:", err)
116 }
117 defer file.Close()
118
119 if err := combinedBuildNinjaTemplate.Execute(file, config); err != nil {
120 ctx.Fatalln("Failed to write combined ninja file:", err)
121 }
122}
123
Sam Delmericod9a34352022-11-15 17:27:21 -0500124// These are bitmasks which can be used to check whether various flags are set
Dan Willemsen1e704462016-08-21 15:17:17 -0700125const (
Anton Hansson5a7861a2021-06-04 10:09:01 +0100126 _ = iota
127 // Whether to run the kati config step.
128 RunProductConfig = 1 << iota
129 // Whether to run soong to generate a ninja file.
130 RunSoong = 1 << iota
131 // Whether to run kati to generate a ninja file.
132 RunKati = 1 << iota
Anton Hansson0b55bdb2021-06-04 10:08:08 +0100133 // Whether to include the kati-generated ninja file in the combined ninja.
134 RunKatiNinja = 1 << iota
Anton Hansson5a7861a2021-06-04 10:09:01 +0100135 // Whether to run ninja on the combined ninja.
Joe Onorato7f29a662023-02-23 15:47:06 -0800136 RunNinja = 1 << iota
137 RunDistActions = 1 << iota
138 RunBuildTests = 1 << iota
Dan Willemsen1e704462016-08-21 15:17:17 -0700139)
140
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000141// checkProblematicFiles fails the build if existing Android.mk or CleanSpec.mk files are found at the root of the tree.
Anton Hanssonecf0f102018-09-19 22:14:17 +0100142func checkProblematicFiles(ctx Context) {
143 files := []string{"Android.mk", "CleanSpec.mk"}
144 for _, file := range files {
145 if _, err := os.Stat(file); !os.IsNotExist(err) {
146 absolute := absPath(ctx, file)
147 ctx.Printf("Found %s in tree root. This file needs to be removed to build.\n", file)
148 ctx.Fatalf(" rm %s\n", absolute)
149 }
150 }
151}
152
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000153// checkCaseSensitivity issues a warning if a case-insensitive file system is being used.
Dan Willemsendb8457c2017-05-12 16:38:17 -0700154func checkCaseSensitivity(ctx Context, config Config) {
155 outDir := config.OutDir()
156 lowerCase := filepath.Join(outDir, "casecheck.txt")
157 upperCase := filepath.Join(outDir, "CaseCheck.txt")
158 lowerData := "a"
159 upperData := "B"
160
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000161 if err := ioutil.WriteFile(lowerCase, []byte(lowerData), 0666); err != nil { // a+rw
Dan Willemsendb8457c2017-05-12 16:38:17 -0700162 ctx.Fatalln("Failed to check case sensitivity:", err)
163 }
164
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000165 if err := ioutil.WriteFile(upperCase, []byte(upperData), 0666); err != nil { // a+rw
Dan Willemsendb8457c2017-05-12 16:38:17 -0700166 ctx.Fatalln("Failed to check case sensitivity:", err)
167 }
168
169 res, err := ioutil.ReadFile(lowerCase)
170 if err != nil {
171 ctx.Fatalln("Failed to check case sensitivity:", err)
172 }
173
174 if string(res) != lowerData {
175 ctx.Println("************************************************************")
176 ctx.Println("You are building on a case-insensitive filesystem.")
177 ctx.Println("Please move your source tree to a case-sensitive filesystem.")
178 ctx.Println("************************************************************")
179 ctx.Fatalln("Case-insensitive filesystems not supported")
180 }
181}
182
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000183// help prints a help/usage message, via the build/make/help.sh script.
184func help(ctx Context, config Config) {
Jeff Gastondf4a0812017-05-30 20:11:20 -0700185 cmd := Command(ctx, config, "help.sh", "build/make/help.sh")
Dan Willemsenb2e6c2e2017-07-13 17:24:44 -0700186 cmd.Sandbox = dumpvarsSandbox
Dan Willemsenb82471a2018-05-17 16:37:09 -0700187 cmd.RunAndPrintOrFatal()
Dan Willemsen02781d52017-05-12 19:28:13 -0700188}
189
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000190// checkRAM warns if there probably isn't enough RAM to complete a build.
191func checkRAM(ctx Context, config Config) {
Dan Willemsen570a2922020-05-26 23:02:29 -0700192 if totalRAM := config.TotalRAM(); totalRAM != 0 {
193 ram := float32(totalRAM) / (1024 * 1024 * 1024)
194 ctx.Verbosef("Total RAM: %.3vGB", ram)
195
196 if ram <= 16 {
197 ctx.Println("************************************************************")
198 ctx.Printf("You are building on a machine with %.3vGB of RAM\n", ram)
199 ctx.Println("")
200 ctx.Println("The minimum required amount of free memory is around 16GB,")
201 ctx.Println("and even with that, some configurations may not work.")
202 ctx.Println("")
203 ctx.Println("If you run into segfaults or other errors, try reducing your")
204 ctx.Println("-j value.")
205 ctx.Println("************************************************************")
206 } else if ram <= float32(config.Parallel()) {
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000207 // Want at least 1GB of RAM per job.
Dan Willemsen570a2922020-05-26 23:02:29 -0700208 ctx.Printf("Warning: high -j%d count compared to %.3vGB of RAM", config.Parallel(), ram)
209 ctx.Println("If you run into segfaults or other errors, try a lower -j value")
210 }
211 }
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000212}
213
Usta Shresthadb46a9b2022-07-11 11:29:56 -0400214// Build the tree. Various flags in `config` govern which components of
215// the build to run.
Anton Hansson5a7861a2021-06-04 10:09:01 +0100216func Build(ctx Context, config Config) {
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000217 ctx.Verboseln("Starting build with args:", config.Arguments())
218 ctx.Verboseln("Environment:", config.Environment().Environ())
Dan Willemsen1e704462016-08-21 15:17:17 -0700219
Colin Cross74cda722020-01-16 15:25:50 -0800220 ctx.BeginTrace(metrics.Total, "total")
221 defer ctx.EndTrace()
222
Dan Willemsen1e704462016-08-21 15:17:17 -0700223 if inList("help", config.Arguments()) {
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000224 help(ctx, config)
Dan Willemsen0b73b4b2017-05-12 19:28:13 -0700225 return
Dan Willemsen1e704462016-08-21 15:17:17 -0700226 }
227
Jeff Gaston3615fe82017-05-24 13:14:34 -0700228 // Make sure that no other Soong process is running with the same output directory
229 buildLock := BecomeSingletonOrFail(ctx, config)
230 defer buildLock.Unlock()
231
Usta Shrestha675564d2022-08-09 18:03:23 -0400232 logArgsOtherThan := func(specialTargets ...string) {
233 var ignored []string
234 for _, a := range config.Arguments() {
235 if !inList(a, specialTargets) {
236 ignored = append(ignored, a)
237 }
238 }
239 if len(ignored) > 0 {
240 ctx.Printf("ignoring arguments %q", ignored)
241 }
242 }
243
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000244 if inList("clean", config.Arguments()) || inList("clobber", config.Arguments()) {
Usta Shrestha675564d2022-08-09 18:03:23 -0400245 logArgsOtherThan("clean", "clobber")
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000246 clean(ctx, config)
247 return
248 }
249
Dan Willemsen80d72612022-04-20 21:45:00 -0700250 defer waitForDist(ctx)
251
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000252 // 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 +0100253 checkProblematicFiles(ctx)
254
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000255 checkRAM(ctx, config)
256
Dan Willemsen1e704462016-08-21 15:17:17 -0700257 SetupOutDir(ctx, config)
258
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000259 // checkCaseSensitivity issues a warning if a case-insensitive file system is being used.
Dan Willemsendb8457c2017-05-12 16:38:17 -0700260 checkCaseSensitivity(ctx, config)
261
Dan Willemsen18490112018-05-25 16:30:04 -0700262 SetupPath(ctx, config)
263
usta6fffdd52022-09-19 13:16:18 -0400264 what := evaluateWhatToRun(config, ctx.Verboseln)
Lukacs T. Berkia1b93722021-09-02 17:23:06 +0200265
Yoshisato Yanagisawa2cb0e5d2019-01-10 10:14:16 +0900266 if config.StartGoma() {
Yoshisato Yanagisawa2cb0e5d2019-01-10 10:14:16 +0900267 startGoma(ctx, config)
268 }
269
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400270 rbeCh := make(chan bool)
Colin Crosse7151f92023-11-28 14:18:12 -0800271 var rbePanic any
Ramy Medhatbbf25672019-07-17 12:30:04 +0000272 if config.StartRBE() {
Kousik Kumar4c180ad2022-05-27 07:48:37 -0400273 cleanupRBELogsDir(ctx, config)
Colin Crosse7151f92023-11-28 14:18:12 -0800274 checkRBERequirements(ctx, config)
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400275 go func() {
Colin Crosse7151f92023-11-28 14:18:12 -0800276 defer func() {
277 rbePanic = recover()
278 close(rbeCh)
279 }()
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400280 startRBE(ctx, config)
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400281 }()
Kousik Kumara1d8fa92022-03-18 02:50:31 -0400282 defer DumpRBEMetrics(ctx, config, filepath.Join(config.LogsDir(), "rbe_metrics.pb"))
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400283 } else {
284 close(rbeCh)
Ramy Medhatbbf25672019-07-17 12:30:04 +0000285 }
286
Anton Hansson5a7861a2021-06-04 10:09:01 +0100287 if what&RunProductConfig != 0 {
Dan Willemsen1e704462016-08-21 15:17:17 -0700288 runMakeProductConfig(ctx, config)
289 }
290
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000291 // Everything below here depends on product config.
292
Colin Cross806fd942019-05-03 13:35:58 -0700293 if inList("installclean", config.Arguments()) ||
294 inList("install-clean", config.Arguments()) {
Usta Shrestha675564d2022-08-09 18:03:23 -0400295 logArgsOtherThan("installclean", "install-clean")
Rupert Shuttleworth1f304e62020-11-24 14:13:41 +0000296 installClean(ctx, config)
Dan Willemsenf052f782017-05-18 15:29:04 -0700297 ctx.Println("Deleted images and staging directories.")
298 return
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000299 }
300
301 if inList("dataclean", config.Arguments()) ||
Colin Cross806fd942019-05-03 13:35:58 -0700302 inList("data-clean", config.Arguments()) {
Usta Shrestha675564d2022-08-09 18:03:23 -0400303 logArgsOtherThan("dataclean", "data-clean")
Rupert Shuttleworth1f304e62020-11-24 14:13:41 +0000304 dataClean(ctx, config)
Dan Willemsenf052f782017-05-18 15:29:04 -0700305 ctx.Println("Deleted data files.")
306 return
307 }
308
Anton Hansson5a7861a2021-06-04 10:09:01 +0100309 if what&RunSoong != 0 {
Dan Willemsen1e704462016-08-21 15:17:17 -0700310 runSoong(ctx, config)
311 }
312
Anton Hansson5a7861a2021-06-04 10:09:01 +0100313 if what&RunKati != 0 {
Dan Willemsen29971232018-09-26 14:58:30 -0700314 genKatiSuffix(ctx, config)
315 runKatiCleanSpec(ctx, config)
316 runKatiBuild(ctx, config)
Dan Willemsenfb1271a2018-09-26 15:00:42 -0700317 runKatiPackage(ctx, config)
Dan Willemsene0879fc2017-08-04 15:06:27 -0700318
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000319 ioutil.WriteFile(config.LastKatiSuffixFile(), []byte(config.KatiSuffix()), 0666) // a+rw
Anton Hansson0b55bdb2021-06-04 10:08:08 +0100320 } else if what&RunKatiNinja != 0 {
Dan Willemsene0879fc2017-08-04 15:06:27 -0700321 // Load last Kati Suffix if it exists
322 if katiSuffix, err := ioutil.ReadFile(config.LastKatiSuffixFile()); err == nil {
323 ctx.Verboseln("Loaded previous kati config:", string(katiSuffix))
324 config.SetKatiSuffix(string(katiSuffix))
325 }
Dan Willemsen1e704462016-08-21 15:17:17 -0700326 }
327
Colin Cross37193492017-11-16 17:55:00 -0800328 // Write combined ninja file
329 createCombinedBuildNinjaFile(ctx, config)
330
Colin Cross8ba7d472020-06-25 11:27:52 -0700331 distGzipFile(ctx, config, config.CombinedNinjaFile())
332
Colin Cross37193492017-11-16 17:55:00 -0800333 if what&RunBuildTests != 0 {
334 testForDanglingRules(ctx, config)
335 }
336
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400337 <-rbeCh
Colin Crosse7151f92023-11-28 14:18:12 -0800338 if rbePanic != nil {
339 // If there was a ctx.Fatal in startRBE, rethrow it.
340 panic(rbePanic)
341 }
342
Anton Hansson5a7861a2021-06-04 10:09:01 +0100343 if what&RunNinja != 0 {
344 if what&RunKati != 0 {
Dan Willemsene0879fc2017-08-04 15:06:27 -0700345 installCleanIfNecessary(ctx, config)
346 }
Lukacs T. Berkid1e3f1f2021-03-16 08:55:23 +0100347 runNinjaForBuild(ctx, config)
Peter Collingbourneb805c612024-03-14 21:59:57 -0700348 updateBuildIdDir(ctx, config)
Dan Willemsen1e704462016-08-21 15:17:17 -0700349 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800350
351 if what&RunDistActions != 0 {
352 runDistActions(ctx, config)
353 }
Dan Willemsen1e704462016-08-21 15:17:17 -0700354}
Colin Cross8ba7d472020-06-25 11:27:52 -0700355
Peter Collingbourneb805c612024-03-14 21:59:57 -0700356func updateBuildIdDir(ctx Context, config Config) {
357 ctx.BeginTrace(metrics.RunShutdownTool, "update_build_id_dir")
358 defer ctx.EndTrace()
359
360 symbolsDir := filepath.Join(config.ProductOut(), "symbols")
361 if err := elf.UpdateBuildIdDir(symbolsDir); err != nil {
362 ctx.Printf("failed to update %s/.build-id: %v", symbolsDir, err)
363 }
364}
365
usta6fffdd52022-09-19 13:16:18 -0400366func evaluateWhatToRun(config Config, verboseln func(v ...interface{})) int {
367 //evaluate what to run
Joe Onorato7f29a662023-02-23 15:47:06 -0800368 what := 0
usta6fffdd52022-09-19 13:16:18 -0400369 if config.Checkbuild() {
370 what |= RunBuildTests
371 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800372 if !config.SkipConfig() {
373 what |= RunProductConfig
374 } else {
usta6fffdd52022-09-19 13:16:18 -0400375 verboseln("Skipping Config as requested")
usta6fffdd52022-09-19 13:16:18 -0400376 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800377 if !config.SkipSoong() {
378 what |= RunSoong
379 } else {
usta6fffdd52022-09-19 13:16:18 -0400380 verboseln("Skipping use of Soong as requested")
usta6fffdd52022-09-19 13:16:18 -0400381 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800382 if !config.SkipKati() {
383 what |= RunKati
384 } else {
385 verboseln("Skipping Kati as requested")
386 }
387 if !config.SkipKatiNinja() {
388 what |= RunKatiNinja
389 } else {
390 verboseln("Skipping use of Kati ninja as requested")
391 }
392 if !config.SkipNinja() {
393 what |= RunNinja
394 } else {
usta6fffdd52022-09-19 13:16:18 -0400395 verboseln("Skipping Ninja as requested")
usta6fffdd52022-09-19 13:16:18 -0400396 }
397
398 if !config.SoongBuildInvocationNeeded() {
399 // This means that the output of soong_build is not needed and thus it would
400 // run unnecessarily. In addition, if this code wasn't there invocations
401 // with only special-cased target names like "m bp2build" would result in
402 // passing Ninja the empty target list and it would then build the default
403 // targets which is not what the user asked for.
404 what = what &^ RunNinja
405 what = what &^ RunKati
406 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800407
408 if config.Dist() {
409 what |= RunDistActions
410 }
411
usta6fffdd52022-09-19 13:16:18 -0400412 return what
413}
414
Dan Willemsen80d72612022-04-20 21:45:00 -0700415var distWaitGroup sync.WaitGroup
416
417// waitForDist waits for all backgrounded distGzipFile and distFile writes to finish
418func waitForDist(ctx Context) {
419 ctx.BeginTrace("soong_ui", "dist")
420 defer ctx.EndTrace()
421
422 distWaitGroup.Wait()
423}
424
Colin Cross8ba7d472020-06-25 11:27:52 -0700425// distGzipFile writes a compressed copy of src to the distDir if dist is enabled. Failures
Dan Willemsen80d72612022-04-20 21:45:00 -0700426// are printed but non-fatal. Uses the distWaitGroup func for backgrounding (optimization).
Colin Cross8ba7d472020-06-25 11:27:52 -0700427func distGzipFile(ctx Context, config Config, src string, subDirs ...string) {
428 if !config.Dist() {
429 return
430 }
431
432 subDir := filepath.Join(subDirs...)
Rupert Shuttleworth3c9f5ac2020-12-10 11:32:38 +0000433 destDir := filepath.Join(config.RealDistDir(), "soong_ui", subDir)
Colin Cross8ba7d472020-06-25 11:27:52 -0700434
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000435 if err := os.MkdirAll(destDir, 0777); err != nil { // a+rwx
Colin Cross8ba7d472020-06-25 11:27:52 -0700436 ctx.Printf("failed to mkdir %s: %s", destDir, err.Error())
Colin Cross8ba7d472020-06-25 11:27:52 -0700437 }
438
Dan Willemsen80d72612022-04-20 21:45:00 -0700439 distWaitGroup.Add(1)
440 go func() {
441 defer distWaitGroup.Done()
442 if err := gzipFileToDir(src, destDir); err != nil {
443 ctx.Printf("failed to dist %s: %s", filepath.Base(src), err.Error())
444 }
445 }()
Colin Cross8ba7d472020-06-25 11:27:52 -0700446}
447
448// distFile writes a copy of src to the distDir if dist is enabled. Failures are printed but
Dan Willemsen80d72612022-04-20 21:45:00 -0700449// non-fatal. Uses the distWaitGroup func for backgrounding (optimization).
Colin Cross8ba7d472020-06-25 11:27:52 -0700450func distFile(ctx Context, config Config, src string, subDirs ...string) {
451 if !config.Dist() {
452 return
453 }
454
455 subDir := filepath.Join(subDirs...)
Rupert Shuttleworth3c9f5ac2020-12-10 11:32:38 +0000456 destDir := filepath.Join(config.RealDistDir(), "soong_ui", subDir)
Colin Cross8ba7d472020-06-25 11:27:52 -0700457
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000458 if err := os.MkdirAll(destDir, 0777); err != nil { // a+rwx
Colin Cross8ba7d472020-06-25 11:27:52 -0700459 ctx.Printf("failed to mkdir %s: %s", destDir, err.Error())
Colin Cross8ba7d472020-06-25 11:27:52 -0700460 }
461
Dan Willemsen80d72612022-04-20 21:45:00 -0700462 distWaitGroup.Add(1)
463 go func() {
464 defer distWaitGroup.Done()
465 if _, err := copyFile(src, filepath.Join(destDir, filepath.Base(src))); err != nil {
466 ctx.Printf("failed to dist %s: %s", filepath.Base(src), err.Error())
467 }
468 }()
Colin Cross8ba7d472020-06-25 11:27:52 -0700469}
Joe Onorato7f29a662023-02-23 15:47:06 -0800470
471// Actions to run on every build where 'dist' is in the actions.
472// Be careful, anything added here slows down EVERY CI build
473func runDistActions(ctx Context, config Config) {
474 runStagingSnapshot(ctx, config)
475}