blob: 54a4c27e5467f62c750f4adfd4272afb2f193034 [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"
Cole Faust583dfb42023-09-28 13:56:30 -070024 "time"
Colin Cross74cda722020-01-16 15:25:50 -080025
26 "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 //
69 // If no BUILD_NUMBER is set, create a useful "I am an engineering build
70 // from this date/time" value. Make it start with a non-digit so that
71 // anyone trying to parse it as an integer will probably get "0".
72 buildNumber, ok := config.environ.Get("BUILD_NUMBER")
73 if ok {
74 writeValueIfChanged(ctx, config, config.OutDir(), "file_name_tag.txt", buildNumber)
75 } else {
76 var username string
77 if username, ok = config.environ.Get("BUILD_USERNAME"); !ok {
78 ctx.Fatalln("Missing BUILD_USERNAME")
79 }
80 buildNumber = fmt.Sprintf("eng.%.6s.%s", username, time.Now().Format("20060102.150405" /* YYYYMMDD.HHMMSS */))
81 writeValueIfChanged(ctx, config, config.OutDir(), "file_name_tag.txt", username)
82 }
83 // Write the build number to a file so it can be read back in
84 // without changing the command line every time. Avoids rebuilds
85 // when using ninja.
86 writeValueIfChanged(ctx, config, config.SoongOutDir(), "build_number.txt", buildNumber)
Dan Willemsen1e704462016-08-21 15:17:17 -070087}
88
89var combinedBuildNinjaTemplate = template.Must(template.New("combined").Parse(`
90builddir = {{.OutDir}}
Colin Cross8b8bec32019-11-15 13:18:43 -080091{{if .UseRemoteBuild }}pool local_pool
Dan Willemsen29971232018-09-26 14:58:30 -070092 depth = {{.Parallel}}
Colin Cross8b8bec32019-11-15 13:18:43 -080093{{end -}}
94pool highmem_pool
95 depth = {{.HighmemParallel}}
Anton Hansson0b55bdb2021-06-04 10:08:08 +010096{{if and (not .SkipKatiNinja) .HasKatiSuffix}}subninja {{.KatiBuildNinjaFile}}
Dan Willemsenfb1271a2018-09-26 15:00:42 -070097subninja {{.KatiPackageNinjaFile}}
Dan Willemsene0879fc2017-08-04 15:06:27 -070098{{end -}}
Dan Willemsenfb1271a2018-09-26 15:00:42 -070099subninja {{.SoongNinjaFile}}
Dan Willemsen1e704462016-08-21 15:17:17 -0700100`))
101
102func createCombinedBuildNinjaFile(ctx Context, config Config) {
Anton Hansson0b55bdb2021-06-04 10:08:08 +0100103 // If we're in SkipKati mode but want to run kati ninja, skip creating this file if it already exists
104 if config.SkipKati() && !config.SkipKatiNinja() {
Dan Willemsene0879fc2017-08-04 15:06:27 -0700105 if _, err := os.Stat(config.CombinedNinjaFile()); err == nil || !os.IsNotExist(err) {
106 return
107 }
108 }
109
Dan Willemsen1e704462016-08-21 15:17:17 -0700110 file, err := os.Create(config.CombinedNinjaFile())
111 if err != nil {
112 ctx.Fatalln("Failed to create combined ninja file:", err)
113 }
114 defer file.Close()
115
116 if err := combinedBuildNinjaTemplate.Execute(file, config); err != nil {
117 ctx.Fatalln("Failed to write combined ninja file:", err)
118 }
119}
120
Sam Delmericod9a34352022-11-15 17:27:21 -0500121// These are bitmasks which can be used to check whether various flags are set
Dan Willemsen1e704462016-08-21 15:17:17 -0700122const (
Anton Hansson5a7861a2021-06-04 10:09:01 +0100123 _ = iota
124 // Whether to run the kati config step.
125 RunProductConfig = 1 << iota
126 // Whether to run soong to generate a ninja file.
127 RunSoong = 1 << iota
128 // Whether to run kati to generate a ninja file.
129 RunKati = 1 << iota
Anton Hansson0b55bdb2021-06-04 10:08:08 +0100130 // Whether to include the kati-generated ninja file in the combined ninja.
131 RunKatiNinja = 1 << iota
Anton Hansson5a7861a2021-06-04 10:09:01 +0100132 // Whether to run ninja on the combined ninja.
Joe Onorato7f29a662023-02-23 15:47:06 -0800133 RunNinja = 1 << iota
134 RunDistActions = 1 << iota
135 RunBuildTests = 1 << iota
Dan Willemsen1e704462016-08-21 15:17:17 -0700136)
137
Chris Parsonsef615e52022-08-18 22:04:11 -0400138// checkBazelMode fails the build if there are conflicting arguments for which bazel
139// build mode to use.
140func checkBazelMode(ctx Context, config Config) {
MarkDacekb78465d2022-10-18 20:10:16 +0000141 count := 0
142 if config.bazelProdMode {
143 count++
144 }
MarkDacekb78465d2022-10-18 20:10:16 +0000145 if config.bazelStagingMode {
146 count++
147 }
148 if count > 1 {
Chris Parsons1bb58da2022-08-30 13:37:57 -0400149 ctx.Fatalln("Conflicting bazel mode.\n" +
Chris Parsons21f80272023-06-15 04:02:28 +0000150 "Do not specify more than one of --bazel-mode and --bazel-mode-staging ")
Chris Parsonsef615e52022-08-18 22:04:11 -0400151 }
152}
153
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000154// 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 +0100155func checkProblematicFiles(ctx Context) {
156 files := []string{"Android.mk", "CleanSpec.mk"}
157 for _, file := range files {
158 if _, err := os.Stat(file); !os.IsNotExist(err) {
159 absolute := absPath(ctx, file)
160 ctx.Printf("Found %s in tree root. This file needs to be removed to build.\n", file)
161 ctx.Fatalf(" rm %s\n", absolute)
162 }
163 }
164}
165
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000166// checkCaseSensitivity issues a warning if a case-insensitive file system is being used.
Dan Willemsendb8457c2017-05-12 16:38:17 -0700167func checkCaseSensitivity(ctx Context, config Config) {
168 outDir := config.OutDir()
169 lowerCase := filepath.Join(outDir, "casecheck.txt")
170 upperCase := filepath.Join(outDir, "CaseCheck.txt")
171 lowerData := "a"
172 upperData := "B"
173
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000174 if err := ioutil.WriteFile(lowerCase, []byte(lowerData), 0666); err != nil { // a+rw
Dan Willemsendb8457c2017-05-12 16:38:17 -0700175 ctx.Fatalln("Failed to check case sensitivity:", err)
176 }
177
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000178 if err := ioutil.WriteFile(upperCase, []byte(upperData), 0666); err != nil { // a+rw
Dan Willemsendb8457c2017-05-12 16:38:17 -0700179 ctx.Fatalln("Failed to check case sensitivity:", err)
180 }
181
182 res, err := ioutil.ReadFile(lowerCase)
183 if err != nil {
184 ctx.Fatalln("Failed to check case sensitivity:", err)
185 }
186
187 if string(res) != lowerData {
188 ctx.Println("************************************************************")
189 ctx.Println("You are building on a case-insensitive filesystem.")
190 ctx.Println("Please move your source tree to a case-sensitive filesystem.")
191 ctx.Println("************************************************************")
192 ctx.Fatalln("Case-insensitive filesystems not supported")
193 }
194}
195
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000196// help prints a help/usage message, via the build/make/help.sh script.
197func help(ctx Context, config Config) {
Jeff Gastondf4a0812017-05-30 20:11:20 -0700198 cmd := Command(ctx, config, "help.sh", "build/make/help.sh")
Dan Willemsenb2e6c2e2017-07-13 17:24:44 -0700199 cmd.Sandbox = dumpvarsSandbox
Dan Willemsenb82471a2018-05-17 16:37:09 -0700200 cmd.RunAndPrintOrFatal()
Dan Willemsen02781d52017-05-12 19:28:13 -0700201}
202
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000203// checkRAM warns if there probably isn't enough RAM to complete a build.
204func checkRAM(ctx Context, config Config) {
Dan Willemsen570a2922020-05-26 23:02:29 -0700205 if totalRAM := config.TotalRAM(); totalRAM != 0 {
206 ram := float32(totalRAM) / (1024 * 1024 * 1024)
207 ctx.Verbosef("Total RAM: %.3vGB", ram)
208
209 if ram <= 16 {
210 ctx.Println("************************************************************")
211 ctx.Printf("You are building on a machine with %.3vGB of RAM\n", ram)
212 ctx.Println("")
213 ctx.Println("The minimum required amount of free memory is around 16GB,")
214 ctx.Println("and even with that, some configurations may not work.")
215 ctx.Println("")
216 ctx.Println("If you run into segfaults or other errors, try reducing your")
217 ctx.Println("-j value.")
218 ctx.Println("************************************************************")
219 } else if ram <= float32(config.Parallel()) {
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000220 // Want at least 1GB of RAM per job.
Dan Willemsen570a2922020-05-26 23:02:29 -0700221 ctx.Printf("Warning: high -j%d count compared to %.3vGB of RAM", config.Parallel(), ram)
222 ctx.Println("If you run into segfaults or other errors, try a lower -j value")
223 }
224 }
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000225}
226
Usta Shresthadb46a9b2022-07-11 11:29:56 -0400227// Build the tree. Various flags in `config` govern which components of
228// the build to run.
Anton Hansson5a7861a2021-06-04 10:09:01 +0100229func Build(ctx Context, config Config) {
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000230 ctx.Verboseln("Starting build with args:", config.Arguments())
231 ctx.Verboseln("Environment:", config.Environment().Environ())
Dan Willemsen1e704462016-08-21 15:17:17 -0700232
Colin Cross74cda722020-01-16 15:25:50 -0800233 ctx.BeginTrace(metrics.Total, "total")
234 defer ctx.EndTrace()
235
Dan Willemsen1e704462016-08-21 15:17:17 -0700236 if inList("help", config.Arguments()) {
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000237 help(ctx, config)
Dan Willemsen0b73b4b2017-05-12 19:28:13 -0700238 return
Dan Willemsen1e704462016-08-21 15:17:17 -0700239 }
240
Jeff Gaston3615fe82017-05-24 13:14:34 -0700241 // Make sure that no other Soong process is running with the same output directory
242 buildLock := BecomeSingletonOrFail(ctx, config)
243 defer buildLock.Unlock()
244
Usta Shrestha675564d2022-08-09 18:03:23 -0400245 logArgsOtherThan := func(specialTargets ...string) {
246 var ignored []string
247 for _, a := range config.Arguments() {
248 if !inList(a, specialTargets) {
249 ignored = append(ignored, a)
250 }
251 }
252 if len(ignored) > 0 {
253 ctx.Printf("ignoring arguments %q", ignored)
254 }
255 }
256
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000257 if inList("clean", config.Arguments()) || inList("clobber", config.Arguments()) {
Usta Shrestha675564d2022-08-09 18:03:23 -0400258 logArgsOtherThan("clean", "clobber")
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000259 clean(ctx, config)
260 return
261 }
262
Dan Willemsen80d72612022-04-20 21:45:00 -0700263 defer waitForDist(ctx)
264
Chris Parsonsef615e52022-08-18 22:04:11 -0400265 checkBazelMode(ctx, config)
266
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000267 // 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 +0100268 checkProblematicFiles(ctx)
269
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000270 checkRAM(ctx, config)
271
Dan Willemsen1e704462016-08-21 15:17:17 -0700272 SetupOutDir(ctx, config)
273
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000274 // checkCaseSensitivity issues a warning if a case-insensitive file system is being used.
Dan Willemsendb8457c2017-05-12 16:38:17 -0700275 checkCaseSensitivity(ctx, config)
276
Dan Willemsen18490112018-05-25 16:30:04 -0700277 SetupPath(ctx, config)
278
usta6fffdd52022-09-19 13:16:18 -0400279 what := evaluateWhatToRun(config, ctx.Verboseln)
Lukacs T. Berkia1b93722021-09-02 17:23:06 +0200280
Yoshisato Yanagisawa2cb0e5d2019-01-10 10:14:16 +0900281 if config.StartGoma() {
Yoshisato Yanagisawa2cb0e5d2019-01-10 10:14:16 +0900282 startGoma(ctx, config)
283 }
284
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400285 rbeCh := make(chan bool)
Colin Crosse7151f92023-11-28 14:18:12 -0800286 var rbePanic any
Ramy Medhatbbf25672019-07-17 12:30:04 +0000287 if config.StartRBE() {
Kousik Kumar4c180ad2022-05-27 07:48:37 -0400288 cleanupRBELogsDir(ctx, config)
Colin Crosse7151f92023-11-28 14:18:12 -0800289 checkRBERequirements(ctx, config)
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400290 go func() {
Colin Crosse7151f92023-11-28 14:18:12 -0800291 defer func() {
292 rbePanic = recover()
293 close(rbeCh)
294 }()
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400295 startRBE(ctx, config)
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400296 }()
Kousik Kumara1d8fa92022-03-18 02:50:31 -0400297 defer DumpRBEMetrics(ctx, config, filepath.Join(config.LogsDir(), "rbe_metrics.pb"))
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400298 } else {
299 close(rbeCh)
Ramy Medhatbbf25672019-07-17 12:30:04 +0000300 }
301
Anton Hansson5a7861a2021-06-04 10:09:01 +0100302 if what&RunProductConfig != 0 {
Dan Willemsen1e704462016-08-21 15:17:17 -0700303 runMakeProductConfig(ctx, config)
304 }
305
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000306 // Everything below here depends on product config.
307
Colin Cross806fd942019-05-03 13:35:58 -0700308 if inList("installclean", config.Arguments()) ||
309 inList("install-clean", config.Arguments()) {
Usta Shrestha675564d2022-08-09 18:03:23 -0400310 logArgsOtherThan("installclean", "install-clean")
Rupert Shuttleworth1f304e62020-11-24 14:13:41 +0000311 installClean(ctx, config)
Dan Willemsenf052f782017-05-18 15:29:04 -0700312 ctx.Println("Deleted images and staging directories.")
313 return
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000314 }
315
316 if inList("dataclean", config.Arguments()) ||
Colin Cross806fd942019-05-03 13:35:58 -0700317 inList("data-clean", config.Arguments()) {
Usta Shrestha675564d2022-08-09 18:03:23 -0400318 logArgsOtherThan("dataclean", "data-clean")
Rupert Shuttleworth1f304e62020-11-24 14:13:41 +0000319 dataClean(ctx, config)
Dan Willemsenf052f782017-05-18 15:29:04 -0700320 ctx.Println("Deleted data files.")
321 return
322 }
323
Anton Hansson5a7861a2021-06-04 10:09:01 +0100324 if what&RunSoong != 0 {
Dan Willemsen1e704462016-08-21 15:17:17 -0700325 runSoong(ctx, config)
326 }
327
Anton Hansson5a7861a2021-06-04 10:09:01 +0100328 if what&RunKati != 0 {
Dan Willemsen29971232018-09-26 14:58:30 -0700329 genKatiSuffix(ctx, config)
330 runKatiCleanSpec(ctx, config)
331 runKatiBuild(ctx, config)
Dan Willemsenfb1271a2018-09-26 15:00:42 -0700332 runKatiPackage(ctx, config)
Dan Willemsene0879fc2017-08-04 15:06:27 -0700333
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000334 ioutil.WriteFile(config.LastKatiSuffixFile(), []byte(config.KatiSuffix()), 0666) // a+rw
Anton Hansson0b55bdb2021-06-04 10:08:08 +0100335 } else if what&RunKatiNinja != 0 {
Dan Willemsene0879fc2017-08-04 15:06:27 -0700336 // Load last Kati Suffix if it exists
337 if katiSuffix, err := ioutil.ReadFile(config.LastKatiSuffixFile()); err == nil {
338 ctx.Verboseln("Loaded previous kati config:", string(katiSuffix))
339 config.SetKatiSuffix(string(katiSuffix))
340 }
Dan Willemsen1e704462016-08-21 15:17:17 -0700341 }
342
Colin Cross37193492017-11-16 17:55:00 -0800343 // Write combined ninja file
344 createCombinedBuildNinjaFile(ctx, config)
345
Colin Cross8ba7d472020-06-25 11:27:52 -0700346 distGzipFile(ctx, config, config.CombinedNinjaFile())
347
Colin Cross37193492017-11-16 17:55:00 -0800348 if what&RunBuildTests != 0 {
349 testForDanglingRules(ctx, config)
350 }
351
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400352 <-rbeCh
Colin Crosse7151f92023-11-28 14:18:12 -0800353 if rbePanic != nil {
354 // If there was a ctx.Fatal in startRBE, rethrow it.
355 panic(rbePanic)
356 }
357
Anton Hansson5a7861a2021-06-04 10:09:01 +0100358 if what&RunNinja != 0 {
359 if what&RunKati != 0 {
Dan Willemsene0879fc2017-08-04 15:06:27 -0700360 installCleanIfNecessary(ctx, config)
361 }
Lukacs T. Berkid1e3f1f2021-03-16 08:55:23 +0100362 runNinjaForBuild(ctx, config)
Dan Willemsen1e704462016-08-21 15:17:17 -0700363 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800364
365 if what&RunDistActions != 0 {
366 runDistActions(ctx, config)
367 }
Dan Willemsen1e704462016-08-21 15:17:17 -0700368}
Colin Cross8ba7d472020-06-25 11:27:52 -0700369
usta6fffdd52022-09-19 13:16:18 -0400370func evaluateWhatToRun(config Config, verboseln func(v ...interface{})) int {
371 //evaluate what to run
Joe Onorato7f29a662023-02-23 15:47:06 -0800372 what := 0
usta6fffdd52022-09-19 13:16:18 -0400373 if config.Checkbuild() {
374 what |= RunBuildTests
375 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800376 if !config.SkipConfig() {
377 what |= RunProductConfig
378 } else {
usta6fffdd52022-09-19 13:16:18 -0400379 verboseln("Skipping Config as requested")
usta6fffdd52022-09-19 13:16:18 -0400380 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800381 if !config.SkipSoong() {
382 what |= RunSoong
383 } else {
usta6fffdd52022-09-19 13:16:18 -0400384 verboseln("Skipping use of Soong as requested")
usta6fffdd52022-09-19 13:16:18 -0400385 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800386 if !config.SkipKati() {
387 what |= RunKati
388 } else {
389 verboseln("Skipping Kati as requested")
390 }
391 if !config.SkipKatiNinja() {
392 what |= RunKatiNinja
393 } else {
394 verboseln("Skipping use of Kati ninja as requested")
395 }
396 if !config.SkipNinja() {
397 what |= RunNinja
398 } else {
usta6fffdd52022-09-19 13:16:18 -0400399 verboseln("Skipping Ninja as requested")
usta6fffdd52022-09-19 13:16:18 -0400400 }
401
402 if !config.SoongBuildInvocationNeeded() {
403 // This means that the output of soong_build is not needed and thus it would
404 // run unnecessarily. In addition, if this code wasn't there invocations
405 // with only special-cased target names like "m bp2build" would result in
406 // passing Ninja the empty target list and it would then build the default
407 // targets which is not what the user asked for.
408 what = what &^ RunNinja
409 what = what &^ RunKati
410 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800411
412 if config.Dist() {
413 what |= RunDistActions
414 }
415
usta6fffdd52022-09-19 13:16:18 -0400416 return what
417}
418
Dan Willemsen80d72612022-04-20 21:45:00 -0700419var distWaitGroup sync.WaitGroup
420
421// waitForDist waits for all backgrounded distGzipFile and distFile writes to finish
422func waitForDist(ctx Context) {
423 ctx.BeginTrace("soong_ui", "dist")
424 defer ctx.EndTrace()
425
426 distWaitGroup.Wait()
427}
428
Colin Cross8ba7d472020-06-25 11:27:52 -0700429// distGzipFile writes a compressed copy of src to the distDir if dist is enabled. Failures
Dan Willemsen80d72612022-04-20 21:45:00 -0700430// are printed but non-fatal. Uses the distWaitGroup func for backgrounding (optimization).
Colin Cross8ba7d472020-06-25 11:27:52 -0700431func distGzipFile(ctx Context, config Config, src string, subDirs ...string) {
432 if !config.Dist() {
433 return
434 }
435
436 subDir := filepath.Join(subDirs...)
Rupert Shuttleworth3c9f5ac2020-12-10 11:32:38 +0000437 destDir := filepath.Join(config.RealDistDir(), "soong_ui", subDir)
Colin Cross8ba7d472020-06-25 11:27:52 -0700438
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000439 if err := os.MkdirAll(destDir, 0777); err != nil { // a+rwx
Colin Cross8ba7d472020-06-25 11:27:52 -0700440 ctx.Printf("failed to mkdir %s: %s", destDir, err.Error())
Colin Cross8ba7d472020-06-25 11:27:52 -0700441 }
442
Dan Willemsen80d72612022-04-20 21:45:00 -0700443 distWaitGroup.Add(1)
444 go func() {
445 defer distWaitGroup.Done()
446 if err := gzipFileToDir(src, destDir); err != nil {
447 ctx.Printf("failed to dist %s: %s", filepath.Base(src), err.Error())
448 }
449 }()
Colin Cross8ba7d472020-06-25 11:27:52 -0700450}
451
452// distFile writes a copy of src to the distDir if dist is enabled. Failures are printed but
Dan Willemsen80d72612022-04-20 21:45:00 -0700453// non-fatal. Uses the distWaitGroup func for backgrounding (optimization).
Colin Cross8ba7d472020-06-25 11:27:52 -0700454func distFile(ctx Context, config Config, src string, subDirs ...string) {
455 if !config.Dist() {
456 return
457 }
458
459 subDir := filepath.Join(subDirs...)
Rupert Shuttleworth3c9f5ac2020-12-10 11:32:38 +0000460 destDir := filepath.Join(config.RealDistDir(), "soong_ui", subDir)
Colin Cross8ba7d472020-06-25 11:27:52 -0700461
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000462 if err := os.MkdirAll(destDir, 0777); err != nil { // a+rwx
Colin Cross8ba7d472020-06-25 11:27:52 -0700463 ctx.Printf("failed to mkdir %s: %s", destDir, err.Error())
Colin Cross8ba7d472020-06-25 11:27:52 -0700464 }
465
Dan Willemsen80d72612022-04-20 21:45:00 -0700466 distWaitGroup.Add(1)
467 go func() {
468 defer distWaitGroup.Done()
469 if _, err := copyFile(src, filepath.Join(destDir, filepath.Base(src))); err != nil {
470 ctx.Printf("failed to dist %s: %s", filepath.Base(src), err.Error())
471 }
472 }()
Colin Cross8ba7d472020-06-25 11:27:52 -0700473}
Joe Onorato7f29a662023-02-23 15:47:06 -0800474
475// Actions to run on every build where 'dist' is in the actions.
476// Be careful, anything added here slows down EVERY CI build
477func runDistActions(ctx Context, config Config) {
478 runStagingSnapshot(ctx, config)
479}