blob: 03d8392376938fb009084c1d77dee72578cc40ed [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
25 "android/soong/ui/metrics"
Dan Willemsen1e704462016-08-21 15:17:17 -070026)
27
Jingwen Chencda22c92020-11-23 00:22:30 -050028// SetupOutDir ensures the out directory exists, and has the proper files to
29// prevent kati from recursing into it.
Dan Willemsen1e704462016-08-21 15:17:17 -070030func SetupOutDir(ctx Context, config Config) {
31 ensureEmptyFileExists(ctx, filepath.Join(config.OutDir(), "Android.mk"))
32 ensureEmptyFileExists(ctx, filepath.Join(config.OutDir(), "CleanSpec.mk"))
Cole Faust583dfb42023-09-28 13:56:30 -070033 ensureEmptyDirectoriesExist(ctx, config.TempDir())
Anton Hansson17fc5a02021-06-18 16:37:14 +010034
35 // Potentially write a marker file for whether kati is enabled. This is used by soong_build to
36 // potentially run the AndroidMk singleton and postinstall commands.
37 // Note that the absence of the file does not not preclude running Kati for product
38 // configuration purposes.
39 katiEnabledMarker := filepath.Join(config.SoongOutDir(), ".soong.kati_enabled")
40 if config.SkipKatiNinja() {
41 os.Remove(katiEnabledMarker)
42 // Note that we can not remove the file for SkipKati builds yet -- some continuous builds
43 // --skip-make builds rely on kati targets being defined.
44 } else if !config.SkipKati() {
45 ensureEmptyFileExists(ctx, katiEnabledMarker)
Dan Willemsene0879fc2017-08-04 15:06:27 -070046 }
Anton Hansson17fc5a02021-06-18 16:37:14 +010047
Dan Willemsen1e704462016-08-21 15:17:17 -070048 // The ninja_build file is used by our buildbots to understand that the output
49 // can be parsed as ninja output.
50 ensureEmptyFileExists(ctx, filepath.Join(config.OutDir(), "ninja_build"))
Jeff Gastonb64fc1c2017-08-04 12:30:12 -070051 ensureEmptyFileExists(ctx, filepath.Join(config.OutDir(), ".out-dir"))
Colin Cross28f527c2019-11-26 16:19:04 -080052
53 if buildDateTimeFile, ok := config.environ.Get("BUILD_DATETIME_FILE"); ok {
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +000054 err := ioutil.WriteFile(buildDateTimeFile, []byte(config.buildDateTime), 0666) // a+rw
Colin Cross28f527c2019-11-26 16:19:04 -080055 if err != nil {
56 ctx.Fatalln("Failed to write BUILD_DATETIME to file:", err)
57 }
58 } else {
59 ctx.Fatalln("Missing BUILD_DATETIME_FILE")
60 }
Cole Faust583dfb42023-09-28 13:56:30 -070061
62 // BUILD_NUMBER should be set to the source control value that
63 // represents the current state of the source code. E.g., a
64 // perforce changelist number or a git hash. Can be an arbitrary string
65 // (to allow for source control that uses something other than numbers),
66 // but must be a single word and a valid file name.
67 //
Cole Faust1ae7b772024-06-12 18:08:44 -070068 // If no BUILD_NUMBER is set, create a useful "I am an engineering build"
69 // value. Make it start with a non-digit so that anyone trying to parse
70 // it as an integer will probably get "0". This value used to contain
71 // a timestamp, but now that more dependencies are tracked in order to
72 // reduce the importance of `m installclean`, changing it every build
73 // causes unnecessary rebuilds for local development.
Cole Faust583dfb42023-09-28 13:56:30 -070074 buildNumber, ok := config.environ.Get("BUILD_NUMBER")
75 if ok {
76 writeValueIfChanged(ctx, config, config.OutDir(), "file_name_tag.txt", buildNumber)
77 } else {
78 var username string
79 if username, ok = config.environ.Get("BUILD_USERNAME"); !ok {
80 ctx.Fatalln("Missing BUILD_USERNAME")
81 }
Cole Faust1ae7b772024-06-12 18:08:44 -070082 buildNumber = fmt.Sprintf("eng.%.6s.00000000.000000", username)
Cole Faust583dfb42023-09-28 13:56:30 -070083 writeValueIfChanged(ctx, config, config.OutDir(), "file_name_tag.txt", username)
84 }
85 // Write the build number to a file so it can be read back in
86 // without changing the command line every time. Avoids rebuilds
87 // when using ninja.
88 writeValueIfChanged(ctx, config, config.SoongOutDir(), "build_number.txt", buildNumber)
Dan Willemsen1e704462016-08-21 15:17:17 -070089}
90
91var combinedBuildNinjaTemplate = template.Must(template.New("combined").Parse(`
92builddir = {{.OutDir}}
Colin Cross8b8bec32019-11-15 13:18:43 -080093{{if .UseRemoteBuild }}pool local_pool
Dan Willemsen29971232018-09-26 14:58:30 -070094 depth = {{.Parallel}}
Colin Cross8b8bec32019-11-15 13:18:43 -080095{{end -}}
96pool highmem_pool
97 depth = {{.HighmemParallel}}
Anton Hansson0b55bdb2021-06-04 10:08:08 +010098{{if and (not .SkipKatiNinja) .HasKatiSuffix}}subninja {{.KatiBuildNinjaFile}}
Dan Willemsenfb1271a2018-09-26 15:00:42 -070099subninja {{.KatiPackageNinjaFile}}
Dan Willemsene0879fc2017-08-04 15:06:27 -0700100{{end -}}
Dan Willemsenfb1271a2018-09-26 15:00:42 -0700101subninja {{.SoongNinjaFile}}
Dan Willemsen1e704462016-08-21 15:17:17 -0700102`))
103
104func createCombinedBuildNinjaFile(ctx Context, config Config) {
Anton Hansson0b55bdb2021-06-04 10:08:08 +0100105 // If we're in SkipKati mode but want to run kati ninja, skip creating this file if it already exists
106 if config.SkipKati() && !config.SkipKatiNinja() {
Dan Willemsene0879fc2017-08-04 15:06:27 -0700107 if _, err := os.Stat(config.CombinedNinjaFile()); err == nil || !os.IsNotExist(err) {
108 return
109 }
110 }
111
Dan Willemsen1e704462016-08-21 15:17:17 -0700112 file, err := os.Create(config.CombinedNinjaFile())
113 if err != nil {
114 ctx.Fatalln("Failed to create combined ninja file:", err)
115 }
116 defer file.Close()
117
118 if err := combinedBuildNinjaTemplate.Execute(file, config); err != nil {
119 ctx.Fatalln("Failed to write combined ninja file:", err)
120 }
121}
122
Sam Delmericod9a34352022-11-15 17:27:21 -0500123// These are bitmasks which can be used to check whether various flags are set
Dan Willemsen1e704462016-08-21 15:17:17 -0700124const (
Anton Hansson5a7861a2021-06-04 10:09:01 +0100125 _ = iota
126 // Whether to run the kati config step.
127 RunProductConfig = 1 << iota
128 // Whether to run soong to generate a ninja file.
129 RunSoong = 1 << iota
130 // Whether to run kati to generate a ninja file.
131 RunKati = 1 << iota
Anton Hansson0b55bdb2021-06-04 10:08:08 +0100132 // Whether to include the kati-generated ninja file in the combined ninja.
133 RunKatiNinja = 1 << iota
Anton Hansson5a7861a2021-06-04 10:09:01 +0100134 // Whether to run ninja on the combined ninja.
Joe Onorato7f29a662023-02-23 15:47:06 -0800135 RunNinja = 1 << iota
136 RunDistActions = 1 << iota
137 RunBuildTests = 1 << iota
Dan Willemsen1e704462016-08-21 15:17:17 -0700138)
139
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000140// 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 +0100141func checkProblematicFiles(ctx Context) {
142 files := []string{"Android.mk", "CleanSpec.mk"}
143 for _, file := range files {
144 if _, err := os.Stat(file); !os.IsNotExist(err) {
145 absolute := absPath(ctx, file)
146 ctx.Printf("Found %s in tree root. This file needs to be removed to build.\n", file)
147 ctx.Fatalf(" rm %s\n", absolute)
148 }
149 }
150}
151
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000152// checkCaseSensitivity issues a warning if a case-insensitive file system is being used.
Dan Willemsendb8457c2017-05-12 16:38:17 -0700153func checkCaseSensitivity(ctx Context, config Config) {
154 outDir := config.OutDir()
155 lowerCase := filepath.Join(outDir, "casecheck.txt")
156 upperCase := filepath.Join(outDir, "CaseCheck.txt")
157 lowerData := "a"
158 upperData := "B"
159
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000160 if err := ioutil.WriteFile(lowerCase, []byte(lowerData), 0666); err != nil { // a+rw
Dan Willemsendb8457c2017-05-12 16:38:17 -0700161 ctx.Fatalln("Failed to check case sensitivity:", err)
162 }
163
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000164 if err := ioutil.WriteFile(upperCase, []byte(upperData), 0666); err != nil { // a+rw
Dan Willemsendb8457c2017-05-12 16:38:17 -0700165 ctx.Fatalln("Failed to check case sensitivity:", err)
166 }
167
168 res, err := ioutil.ReadFile(lowerCase)
169 if err != nil {
170 ctx.Fatalln("Failed to check case sensitivity:", err)
171 }
172
173 if string(res) != lowerData {
174 ctx.Println("************************************************************")
175 ctx.Println("You are building on a case-insensitive filesystem.")
176 ctx.Println("Please move your source tree to a case-sensitive filesystem.")
177 ctx.Println("************************************************************")
178 ctx.Fatalln("Case-insensitive filesystems not supported")
179 }
180}
181
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000182// help prints a help/usage message, via the build/make/help.sh script.
183func help(ctx Context, config Config) {
Jeff Gastondf4a0812017-05-30 20:11:20 -0700184 cmd := Command(ctx, config, "help.sh", "build/make/help.sh")
Dan Willemsenb2e6c2e2017-07-13 17:24:44 -0700185 cmd.Sandbox = dumpvarsSandbox
Dan Willemsenb82471a2018-05-17 16:37:09 -0700186 cmd.RunAndPrintOrFatal()
Dan Willemsen02781d52017-05-12 19:28:13 -0700187}
188
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000189// checkRAM warns if there probably isn't enough RAM to complete a build.
190func checkRAM(ctx Context, config Config) {
Dan Willemsen570a2922020-05-26 23:02:29 -0700191 if totalRAM := config.TotalRAM(); totalRAM != 0 {
192 ram := float32(totalRAM) / (1024 * 1024 * 1024)
193 ctx.Verbosef("Total RAM: %.3vGB", ram)
194
195 if ram <= 16 {
196 ctx.Println("************************************************************")
197 ctx.Printf("You are building on a machine with %.3vGB of RAM\n", ram)
198 ctx.Println("")
199 ctx.Println("The minimum required amount of free memory is around 16GB,")
200 ctx.Println("and even with that, some configurations may not work.")
201 ctx.Println("")
202 ctx.Println("If you run into segfaults or other errors, try reducing your")
203 ctx.Println("-j value.")
204 ctx.Println("************************************************************")
205 } else if ram <= float32(config.Parallel()) {
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000206 // Want at least 1GB of RAM per job.
Dan Willemsen570a2922020-05-26 23:02:29 -0700207 ctx.Printf("Warning: high -j%d count compared to %.3vGB of RAM", config.Parallel(), ram)
208 ctx.Println("If you run into segfaults or other errors, try a lower -j value")
209 }
210 }
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000211}
212
Usta Shresthadb46a9b2022-07-11 11:29:56 -0400213// Build the tree. Various flags in `config` govern which components of
214// the build to run.
Anton Hansson5a7861a2021-06-04 10:09:01 +0100215func Build(ctx Context, config Config) {
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000216 ctx.Verboseln("Starting build with args:", config.Arguments())
217 ctx.Verboseln("Environment:", config.Environment().Environ())
Dan Willemsen1e704462016-08-21 15:17:17 -0700218
Colin Cross74cda722020-01-16 15:25:50 -0800219 ctx.BeginTrace(metrics.Total, "total")
220 defer ctx.EndTrace()
221
Dan Willemsen1e704462016-08-21 15:17:17 -0700222 if inList("help", config.Arguments()) {
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000223 help(ctx, config)
Dan Willemsen0b73b4b2017-05-12 19:28:13 -0700224 return
Dan Willemsen1e704462016-08-21 15:17:17 -0700225 }
226
Jeff Gaston3615fe82017-05-24 13:14:34 -0700227 // Make sure that no other Soong process is running with the same output directory
228 buildLock := BecomeSingletonOrFail(ctx, config)
229 defer buildLock.Unlock()
230
Usta Shrestha675564d2022-08-09 18:03:23 -0400231 logArgsOtherThan := func(specialTargets ...string) {
232 var ignored []string
233 for _, a := range config.Arguments() {
234 if !inList(a, specialTargets) {
235 ignored = append(ignored, a)
236 }
237 }
238 if len(ignored) > 0 {
239 ctx.Printf("ignoring arguments %q", ignored)
240 }
241 }
242
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000243 if inList("clean", config.Arguments()) || inList("clobber", config.Arguments()) {
Usta Shrestha675564d2022-08-09 18:03:23 -0400244 logArgsOtherThan("clean", "clobber")
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000245 clean(ctx, config)
246 return
247 }
248
Dan Willemsen80d72612022-04-20 21:45:00 -0700249 defer waitForDist(ctx)
250
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000251 // 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 +0100252 checkProblematicFiles(ctx)
253
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000254 checkRAM(ctx, config)
255
Dan Willemsen1e704462016-08-21 15:17:17 -0700256 SetupOutDir(ctx, config)
257
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000258 // checkCaseSensitivity issues a warning if a case-insensitive file system is being used.
Dan Willemsendb8457c2017-05-12 16:38:17 -0700259 checkCaseSensitivity(ctx, config)
260
Dan Willemsen18490112018-05-25 16:30:04 -0700261 SetupPath(ctx, config)
262
usta6fffdd52022-09-19 13:16:18 -0400263 what := evaluateWhatToRun(config, ctx.Verboseln)
Lukacs T. Berkia1b93722021-09-02 17:23:06 +0200264
Yoshisato Yanagisawa2cb0e5d2019-01-10 10:14:16 +0900265 if config.StartGoma() {
Yoshisato Yanagisawa2cb0e5d2019-01-10 10:14:16 +0900266 startGoma(ctx, config)
267 }
268
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400269 rbeCh := make(chan bool)
Colin Crosse7151f92023-11-28 14:18:12 -0800270 var rbePanic any
Ramy Medhatbbf25672019-07-17 12:30:04 +0000271 if config.StartRBE() {
Kousik Kumar4c180ad2022-05-27 07:48:37 -0400272 cleanupRBELogsDir(ctx, config)
Colin Crosse7151f92023-11-28 14:18:12 -0800273 checkRBERequirements(ctx, config)
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400274 go func() {
Colin Crosse7151f92023-11-28 14:18:12 -0800275 defer func() {
276 rbePanic = recover()
277 close(rbeCh)
278 }()
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400279 startRBE(ctx, config)
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400280 }()
Kousik Kumara1d8fa92022-03-18 02:50:31 -0400281 defer DumpRBEMetrics(ctx, config, filepath.Join(config.LogsDir(), "rbe_metrics.pb"))
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400282 } else {
283 close(rbeCh)
Ramy Medhatbbf25672019-07-17 12:30:04 +0000284 }
285
Anton Hansson5a7861a2021-06-04 10:09:01 +0100286 if what&RunProductConfig != 0 {
Dan Willemsen1e704462016-08-21 15:17:17 -0700287 runMakeProductConfig(ctx, config)
288 }
289
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000290 // Everything below here depends on product config.
291
Colin Cross806fd942019-05-03 13:35:58 -0700292 if inList("installclean", config.Arguments()) ||
293 inList("install-clean", config.Arguments()) {
Usta Shrestha675564d2022-08-09 18:03:23 -0400294 logArgsOtherThan("installclean", "install-clean")
Rupert Shuttleworth1f304e62020-11-24 14:13:41 +0000295 installClean(ctx, config)
Dan Willemsenf052f782017-05-18 15:29:04 -0700296 ctx.Println("Deleted images and staging directories.")
297 return
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000298 }
299
300 if inList("dataclean", config.Arguments()) ||
Colin Cross806fd942019-05-03 13:35:58 -0700301 inList("data-clean", config.Arguments()) {
Usta Shrestha675564d2022-08-09 18:03:23 -0400302 logArgsOtherThan("dataclean", "data-clean")
Rupert Shuttleworth1f304e62020-11-24 14:13:41 +0000303 dataClean(ctx, config)
Dan Willemsenf052f782017-05-18 15:29:04 -0700304 ctx.Println("Deleted data files.")
305 return
306 }
307
Anton Hansson5a7861a2021-06-04 10:09:01 +0100308 if what&RunSoong != 0 {
Dan Willemsen1e704462016-08-21 15:17:17 -0700309 runSoong(ctx, config)
310 }
311
Anton Hansson5a7861a2021-06-04 10:09:01 +0100312 if what&RunKati != 0 {
Dan Willemsen29971232018-09-26 14:58:30 -0700313 genKatiSuffix(ctx, config)
314 runKatiCleanSpec(ctx, config)
315 runKatiBuild(ctx, config)
Dan Willemsenfb1271a2018-09-26 15:00:42 -0700316 runKatiPackage(ctx, config)
Dan Willemsene0879fc2017-08-04 15:06:27 -0700317
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000318 ioutil.WriteFile(config.LastKatiSuffixFile(), []byte(config.KatiSuffix()), 0666) // a+rw
Anton Hansson0b55bdb2021-06-04 10:08:08 +0100319 } else if what&RunKatiNinja != 0 {
Dan Willemsene0879fc2017-08-04 15:06:27 -0700320 // Load last Kati Suffix if it exists
321 if katiSuffix, err := ioutil.ReadFile(config.LastKatiSuffixFile()); err == nil {
322 ctx.Verboseln("Loaded previous kati config:", string(katiSuffix))
323 config.SetKatiSuffix(string(katiSuffix))
324 }
Dan Willemsen1e704462016-08-21 15:17:17 -0700325 }
326
Colin Cross37193492017-11-16 17:55:00 -0800327 // Write combined ninja file
328 createCombinedBuildNinjaFile(ctx, config)
329
Colin Cross8ba7d472020-06-25 11:27:52 -0700330 distGzipFile(ctx, config, config.CombinedNinjaFile())
331
Colin Cross37193492017-11-16 17:55:00 -0800332 if what&RunBuildTests != 0 {
333 testForDanglingRules(ctx, config)
334 }
335
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400336 <-rbeCh
Colin Crosse7151f92023-11-28 14:18:12 -0800337 if rbePanic != nil {
338 // If there was a ctx.Fatal in startRBE, rethrow it.
339 panic(rbePanic)
340 }
341
Anton Hansson5a7861a2021-06-04 10:09:01 +0100342 if what&RunNinja != 0 {
343 if what&RunKati != 0 {
Dan Willemsene0879fc2017-08-04 15:06:27 -0700344 installCleanIfNecessary(ctx, config)
345 }
Lukacs T. Berkid1e3f1f2021-03-16 08:55:23 +0100346 runNinjaForBuild(ctx, config)
Dan Willemsen1e704462016-08-21 15:17:17 -0700347 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800348
349 if what&RunDistActions != 0 {
350 runDistActions(ctx, config)
351 }
Dan Willemsen1e704462016-08-21 15:17:17 -0700352}
Colin Cross8ba7d472020-06-25 11:27:52 -0700353
usta6fffdd52022-09-19 13:16:18 -0400354func evaluateWhatToRun(config Config, verboseln func(v ...interface{})) int {
355 //evaluate what to run
Joe Onorato7f29a662023-02-23 15:47:06 -0800356 what := 0
usta6fffdd52022-09-19 13:16:18 -0400357 if config.Checkbuild() {
358 what |= RunBuildTests
359 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800360 if !config.SkipConfig() {
361 what |= RunProductConfig
362 } else {
usta6fffdd52022-09-19 13:16:18 -0400363 verboseln("Skipping Config as requested")
usta6fffdd52022-09-19 13:16:18 -0400364 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800365 if !config.SkipSoong() {
366 what |= RunSoong
367 } else {
usta6fffdd52022-09-19 13:16:18 -0400368 verboseln("Skipping use of Soong as requested")
usta6fffdd52022-09-19 13:16:18 -0400369 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800370 if !config.SkipKati() {
371 what |= RunKati
372 } else {
373 verboseln("Skipping Kati as requested")
374 }
375 if !config.SkipKatiNinja() {
376 what |= RunKatiNinja
377 } else {
378 verboseln("Skipping use of Kati ninja as requested")
379 }
380 if !config.SkipNinja() {
381 what |= RunNinja
382 } else {
usta6fffdd52022-09-19 13:16:18 -0400383 verboseln("Skipping Ninja as requested")
usta6fffdd52022-09-19 13:16:18 -0400384 }
385
386 if !config.SoongBuildInvocationNeeded() {
387 // This means that the output of soong_build is not needed and thus it would
388 // run unnecessarily. In addition, if this code wasn't there invocations
389 // with only special-cased target names like "m bp2build" would result in
390 // passing Ninja the empty target list and it would then build the default
391 // targets which is not what the user asked for.
392 what = what &^ RunNinja
393 what = what &^ RunKati
394 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800395
396 if config.Dist() {
397 what |= RunDistActions
398 }
399
usta6fffdd52022-09-19 13:16:18 -0400400 return what
401}
402
Dan Willemsen80d72612022-04-20 21:45:00 -0700403var distWaitGroup sync.WaitGroup
404
405// waitForDist waits for all backgrounded distGzipFile and distFile writes to finish
406func waitForDist(ctx Context) {
407 ctx.BeginTrace("soong_ui", "dist")
408 defer ctx.EndTrace()
409
410 distWaitGroup.Wait()
411}
412
Colin Cross8ba7d472020-06-25 11:27:52 -0700413// distGzipFile writes a compressed copy of src to the distDir if dist is enabled. Failures
Dan Willemsen80d72612022-04-20 21:45:00 -0700414// are printed but non-fatal. Uses the distWaitGroup func for backgrounding (optimization).
Colin Cross8ba7d472020-06-25 11:27:52 -0700415func distGzipFile(ctx Context, config Config, src string, subDirs ...string) {
416 if !config.Dist() {
417 return
418 }
419
420 subDir := filepath.Join(subDirs...)
Rupert Shuttleworth3c9f5ac2020-12-10 11:32:38 +0000421 destDir := filepath.Join(config.RealDistDir(), "soong_ui", subDir)
Colin Cross8ba7d472020-06-25 11:27:52 -0700422
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000423 if err := os.MkdirAll(destDir, 0777); err != nil { // a+rwx
Colin Cross8ba7d472020-06-25 11:27:52 -0700424 ctx.Printf("failed to mkdir %s: %s", destDir, err.Error())
Colin Cross8ba7d472020-06-25 11:27:52 -0700425 }
426
Dan Willemsen80d72612022-04-20 21:45:00 -0700427 distWaitGroup.Add(1)
428 go func() {
429 defer distWaitGroup.Done()
430 if err := gzipFileToDir(src, destDir); err != nil {
431 ctx.Printf("failed to dist %s: %s", filepath.Base(src), err.Error())
432 }
433 }()
Colin Cross8ba7d472020-06-25 11:27:52 -0700434}
435
436// distFile writes a copy of src to the distDir if dist is enabled. Failures are printed but
Dan Willemsen80d72612022-04-20 21:45:00 -0700437// non-fatal. Uses the distWaitGroup func for backgrounding (optimization).
Colin Cross8ba7d472020-06-25 11:27:52 -0700438func distFile(ctx Context, config Config, src string, subDirs ...string) {
439 if !config.Dist() {
440 return
441 }
442
443 subDir := filepath.Join(subDirs...)
Rupert Shuttleworth3c9f5ac2020-12-10 11:32:38 +0000444 destDir := filepath.Join(config.RealDistDir(), "soong_ui", subDir)
Colin Cross8ba7d472020-06-25 11:27:52 -0700445
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000446 if err := os.MkdirAll(destDir, 0777); err != nil { // a+rwx
Colin Cross8ba7d472020-06-25 11:27:52 -0700447 ctx.Printf("failed to mkdir %s: %s", destDir, err.Error())
Colin Cross8ba7d472020-06-25 11:27:52 -0700448 }
449
Dan Willemsen80d72612022-04-20 21:45:00 -0700450 distWaitGroup.Add(1)
451 go func() {
452 defer distWaitGroup.Done()
453 if _, err := copyFile(src, filepath.Join(destDir, filepath.Base(src))); err != nil {
454 ctx.Printf("failed to dist %s: %s", filepath.Base(src), err.Error())
455 }
456 }()
Colin Cross8ba7d472020-06-25 11:27:52 -0700457}
Joe Onorato7f29a662023-02-23 15:47:06 -0800458
459// Actions to run on every build where 'dist' is in the actions.
460// Be careful, anything added here slows down EVERY CI build
461func runDistActions(ctx Context, config Config) {
462 runStagingSnapshot(ctx, config)
463}