blob: 14d23a7daca81c2db2cef78ae9466e7a1ae93f44 [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 (
Dan Willemsendb8457c2017-05-12 16:38:17 -070018 "io/ioutil"
Dan Willemsen1e704462016-08-21 15:17:17 -070019 "os"
Dan Willemsen1e704462016-08-21 15:17:17 -070020 "path/filepath"
Dan Willemsen80d72612022-04-20 21:45:00 -070021 "sync"
Dan Willemsen1e704462016-08-21 15:17:17 -070022 "text/template"
Colin Cross74cda722020-01-16 15:25:50 -080023
24 "android/soong/ui/metrics"
Dan Willemsen1e704462016-08-21 15:17:17 -070025)
26
Jingwen Chencda22c92020-11-23 00:22:30 -050027// SetupOutDir ensures the out directory exists, and has the proper files to
28// prevent kati from recursing into it.
Dan Willemsen1e704462016-08-21 15:17:17 -070029func SetupOutDir(ctx Context, config Config) {
30 ensureEmptyFileExists(ctx, filepath.Join(config.OutDir(), "Android.mk"))
31 ensureEmptyFileExists(ctx, filepath.Join(config.OutDir(), "CleanSpec.mk"))
Anton Hansson17fc5a02021-06-18 16:37:14 +010032
33 // Potentially write a marker file for whether kati is enabled. This is used by soong_build to
34 // potentially run the AndroidMk singleton and postinstall commands.
35 // Note that the absence of the file does not not preclude running Kati for product
36 // configuration purposes.
37 katiEnabledMarker := filepath.Join(config.SoongOutDir(), ".soong.kati_enabled")
38 if config.SkipKatiNinja() {
39 os.Remove(katiEnabledMarker)
40 // Note that we can not remove the file for SkipKati builds yet -- some continuous builds
41 // --skip-make builds rely on kati targets being defined.
42 } else if !config.SkipKati() {
43 ensureEmptyFileExists(ctx, katiEnabledMarker)
Dan Willemsene0879fc2017-08-04 15:06:27 -070044 }
Anton Hansson17fc5a02021-06-18 16:37:14 +010045
Dan Willemsen1e704462016-08-21 15:17:17 -070046 // The ninja_build file is used by our buildbots to understand that the output
47 // can be parsed as ninja output.
48 ensureEmptyFileExists(ctx, filepath.Join(config.OutDir(), "ninja_build"))
Jeff Gastonb64fc1c2017-08-04 12:30:12 -070049 ensureEmptyFileExists(ctx, filepath.Join(config.OutDir(), ".out-dir"))
Colin Cross28f527c2019-11-26 16:19:04 -080050
51 if buildDateTimeFile, ok := config.environ.Get("BUILD_DATETIME_FILE"); ok {
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +000052 err := ioutil.WriteFile(buildDateTimeFile, []byte(config.buildDateTime), 0666) // a+rw
Colin Cross28f527c2019-11-26 16:19:04 -080053 if err != nil {
54 ctx.Fatalln("Failed to write BUILD_DATETIME to file:", err)
55 }
56 } else {
57 ctx.Fatalln("Missing BUILD_DATETIME_FILE")
58 }
Dan Willemsen1e704462016-08-21 15:17:17 -070059}
60
61var combinedBuildNinjaTemplate = template.Must(template.New("combined").Parse(`
62builddir = {{.OutDir}}
Colin Cross8b8bec32019-11-15 13:18:43 -080063{{if .UseRemoteBuild }}pool local_pool
Dan Willemsen29971232018-09-26 14:58:30 -070064 depth = {{.Parallel}}
Colin Cross8b8bec32019-11-15 13:18:43 -080065{{end -}}
66pool highmem_pool
67 depth = {{.HighmemParallel}}
Anton Hansson0b55bdb2021-06-04 10:08:08 +010068{{if and (not .SkipKatiNinja) .HasKatiSuffix}}subninja {{.KatiBuildNinjaFile}}
Dan Willemsenfb1271a2018-09-26 15:00:42 -070069subninja {{.KatiPackageNinjaFile}}
Dan Willemsene0879fc2017-08-04 15:06:27 -070070{{end -}}
Dan Willemsenfb1271a2018-09-26 15:00:42 -070071subninja {{.SoongNinjaFile}}
Dan Willemsen1e704462016-08-21 15:17:17 -070072`))
73
74func createCombinedBuildNinjaFile(ctx Context, config Config) {
Anton Hansson0b55bdb2021-06-04 10:08:08 +010075 // If we're in SkipKati mode but want to run kati ninja, skip creating this file if it already exists
76 if config.SkipKati() && !config.SkipKatiNinja() {
Dan Willemsene0879fc2017-08-04 15:06:27 -070077 if _, err := os.Stat(config.CombinedNinjaFile()); err == nil || !os.IsNotExist(err) {
78 return
79 }
80 }
81
Dan Willemsen1e704462016-08-21 15:17:17 -070082 file, err := os.Create(config.CombinedNinjaFile())
83 if err != nil {
84 ctx.Fatalln("Failed to create combined ninja file:", err)
85 }
86 defer file.Close()
87
88 if err := combinedBuildNinjaTemplate.Execute(file, config); err != nil {
89 ctx.Fatalln("Failed to write combined ninja file:", err)
90 }
91}
92
Sam Delmericod9a34352022-11-15 17:27:21 -050093// These are bitmasks which can be used to check whether various flags are set
Dan Willemsen1e704462016-08-21 15:17:17 -070094const (
Anton Hansson5a7861a2021-06-04 10:09:01 +010095 _ = iota
96 // Whether to run the kati config step.
97 RunProductConfig = 1 << iota
98 // Whether to run soong to generate a ninja file.
99 RunSoong = 1 << iota
100 // Whether to run kati to generate a ninja file.
101 RunKati = 1 << iota
Anton Hansson0b55bdb2021-06-04 10:08:08 +0100102 // Whether to include the kati-generated ninja file in the combined ninja.
103 RunKatiNinja = 1 << iota
Anton Hansson5a7861a2021-06-04 10:09:01 +0100104 // Whether to run ninja on the combined ninja.
Joe Onorato7f29a662023-02-23 15:47:06 -0800105 RunNinja = 1 << iota
106 RunDistActions = 1 << iota
107 RunBuildTests = 1 << iota
Dan Willemsen1e704462016-08-21 15:17:17 -0700108)
109
Chris Parsonsef615e52022-08-18 22:04:11 -0400110// checkBazelMode fails the build if there are conflicting arguments for which bazel
111// build mode to use.
112func checkBazelMode(ctx Context, config Config) {
MarkDacekb78465d2022-10-18 20:10:16 +0000113 count := 0
114 if config.bazelProdMode {
115 count++
116 }
MarkDacekb78465d2022-10-18 20:10:16 +0000117 if config.bazelStagingMode {
118 count++
119 }
120 if count > 1 {
Chris Parsons1bb58da2022-08-30 13:37:57 -0400121 ctx.Fatalln("Conflicting bazel mode.\n" +
Chris Parsons21f80272023-06-15 04:02:28 +0000122 "Do not specify more than one of --bazel-mode and --bazel-mode-staging ")
Chris Parsonsef615e52022-08-18 22:04:11 -0400123 }
124}
125
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000126// 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 +0100127func checkProblematicFiles(ctx Context) {
128 files := []string{"Android.mk", "CleanSpec.mk"}
129 for _, file := range files {
130 if _, err := os.Stat(file); !os.IsNotExist(err) {
131 absolute := absPath(ctx, file)
132 ctx.Printf("Found %s in tree root. This file needs to be removed to build.\n", file)
133 ctx.Fatalf(" rm %s\n", absolute)
134 }
135 }
136}
137
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000138// checkCaseSensitivity issues a warning if a case-insensitive file system is being used.
Dan Willemsendb8457c2017-05-12 16:38:17 -0700139func checkCaseSensitivity(ctx Context, config Config) {
140 outDir := config.OutDir()
141 lowerCase := filepath.Join(outDir, "casecheck.txt")
142 upperCase := filepath.Join(outDir, "CaseCheck.txt")
143 lowerData := "a"
144 upperData := "B"
145
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000146 if err := ioutil.WriteFile(lowerCase, []byte(lowerData), 0666); err != nil { // a+rw
Dan Willemsendb8457c2017-05-12 16:38:17 -0700147 ctx.Fatalln("Failed to check case sensitivity:", err)
148 }
149
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000150 if err := ioutil.WriteFile(upperCase, []byte(upperData), 0666); err != nil { // a+rw
Dan Willemsendb8457c2017-05-12 16:38:17 -0700151 ctx.Fatalln("Failed to check case sensitivity:", err)
152 }
153
154 res, err := ioutil.ReadFile(lowerCase)
155 if err != nil {
156 ctx.Fatalln("Failed to check case sensitivity:", err)
157 }
158
159 if string(res) != lowerData {
160 ctx.Println("************************************************************")
161 ctx.Println("You are building on a case-insensitive filesystem.")
162 ctx.Println("Please move your source tree to a case-sensitive filesystem.")
163 ctx.Println("************************************************************")
164 ctx.Fatalln("Case-insensitive filesystems not supported")
165 }
166}
167
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000168// help prints a help/usage message, via the build/make/help.sh script.
169func help(ctx Context, config Config) {
Jeff Gastondf4a0812017-05-30 20:11:20 -0700170 cmd := Command(ctx, config, "help.sh", "build/make/help.sh")
Dan Willemsenb2e6c2e2017-07-13 17:24:44 -0700171 cmd.Sandbox = dumpvarsSandbox
Dan Willemsenb82471a2018-05-17 16:37:09 -0700172 cmd.RunAndPrintOrFatal()
Dan Willemsen02781d52017-05-12 19:28:13 -0700173}
174
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000175// checkRAM warns if there probably isn't enough RAM to complete a build.
176func checkRAM(ctx Context, config Config) {
Dan Willemsen570a2922020-05-26 23:02:29 -0700177 if totalRAM := config.TotalRAM(); totalRAM != 0 {
178 ram := float32(totalRAM) / (1024 * 1024 * 1024)
179 ctx.Verbosef("Total RAM: %.3vGB", ram)
180
181 if ram <= 16 {
182 ctx.Println("************************************************************")
183 ctx.Printf("You are building on a machine with %.3vGB of RAM\n", ram)
184 ctx.Println("")
185 ctx.Println("The minimum required amount of free memory is around 16GB,")
186 ctx.Println("and even with that, some configurations may not work.")
187 ctx.Println("")
188 ctx.Println("If you run into segfaults or other errors, try reducing your")
189 ctx.Println("-j value.")
190 ctx.Println("************************************************************")
191 } else if ram <= float32(config.Parallel()) {
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000192 // Want at least 1GB of RAM per job.
Dan Willemsen570a2922020-05-26 23:02:29 -0700193 ctx.Printf("Warning: high -j%d count compared to %.3vGB of RAM", config.Parallel(), ram)
194 ctx.Println("If you run into segfaults or other errors, try a lower -j value")
195 }
196 }
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000197}
198
Usta Shresthadb46a9b2022-07-11 11:29:56 -0400199// Build the tree. Various flags in `config` govern which components of
200// the build to run.
Anton Hansson5a7861a2021-06-04 10:09:01 +0100201func Build(ctx Context, config Config) {
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000202 ctx.Verboseln("Starting build with args:", config.Arguments())
203 ctx.Verboseln("Environment:", config.Environment().Environ())
Dan Willemsen1e704462016-08-21 15:17:17 -0700204
Colin Cross74cda722020-01-16 15:25:50 -0800205 ctx.BeginTrace(metrics.Total, "total")
206 defer ctx.EndTrace()
207
Dan Willemsen1e704462016-08-21 15:17:17 -0700208 if inList("help", config.Arguments()) {
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000209 help(ctx, config)
Dan Willemsen0b73b4b2017-05-12 19:28:13 -0700210 return
Dan Willemsen1e704462016-08-21 15:17:17 -0700211 }
212
Jeff Gaston3615fe82017-05-24 13:14:34 -0700213 // Make sure that no other Soong process is running with the same output directory
214 buildLock := BecomeSingletonOrFail(ctx, config)
215 defer buildLock.Unlock()
216
Usta Shrestha675564d2022-08-09 18:03:23 -0400217 logArgsOtherThan := func(specialTargets ...string) {
218 var ignored []string
219 for _, a := range config.Arguments() {
220 if !inList(a, specialTargets) {
221 ignored = append(ignored, a)
222 }
223 }
224 if len(ignored) > 0 {
225 ctx.Printf("ignoring arguments %q", ignored)
226 }
227 }
228
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000229 if inList("clean", config.Arguments()) || inList("clobber", config.Arguments()) {
Usta Shrestha675564d2022-08-09 18:03:23 -0400230 logArgsOtherThan("clean", "clobber")
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000231 clean(ctx, config)
232 return
233 }
234
Dan Willemsen80d72612022-04-20 21:45:00 -0700235 defer waitForDist(ctx)
236
Chris Parsonsef615e52022-08-18 22:04:11 -0400237 checkBazelMode(ctx, config)
238
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000239 // 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 +0100240 checkProblematicFiles(ctx)
241
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000242 checkRAM(ctx, config)
243
Dan Willemsen1e704462016-08-21 15:17:17 -0700244 SetupOutDir(ctx, config)
245
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000246 // checkCaseSensitivity issues a warning if a case-insensitive file system is being used.
Dan Willemsendb8457c2017-05-12 16:38:17 -0700247 checkCaseSensitivity(ctx, config)
248
Jeff Gastonefc1b412017-03-29 17:29:06 -0700249 ensureEmptyDirectoriesExist(ctx, config.TempDir())
250
Dan Willemsen18490112018-05-25 16:30:04 -0700251 SetupPath(ctx, config)
252
usta6fffdd52022-09-19 13:16:18 -0400253 what := evaluateWhatToRun(config, ctx.Verboseln)
Lukacs T. Berkia1b93722021-09-02 17:23:06 +0200254
Yoshisato Yanagisawa2cb0e5d2019-01-10 10:14:16 +0900255 if config.StartGoma() {
Yoshisato Yanagisawa2cb0e5d2019-01-10 10:14:16 +0900256 startGoma(ctx, config)
257 }
258
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400259 rbeCh := make(chan bool)
Ramy Medhatbbf25672019-07-17 12:30:04 +0000260 if config.StartRBE() {
Kousik Kumar4c180ad2022-05-27 07:48:37 -0400261 cleanupRBELogsDir(ctx, config)
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400262 go func() {
263 startRBE(ctx, config)
264 close(rbeCh)
265 }()
Kousik Kumara1d8fa92022-03-18 02:50:31 -0400266 defer DumpRBEMetrics(ctx, config, filepath.Join(config.LogsDir(), "rbe_metrics.pb"))
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400267 } else {
268 close(rbeCh)
Ramy Medhatbbf25672019-07-17 12:30:04 +0000269 }
270
Anton Hansson5a7861a2021-06-04 10:09:01 +0100271 if what&RunProductConfig != 0 {
Dan Willemsen1e704462016-08-21 15:17:17 -0700272 runMakeProductConfig(ctx, config)
273 }
274
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000275 // Everything below here depends on product config.
276
Colin Cross806fd942019-05-03 13:35:58 -0700277 if inList("installclean", config.Arguments()) ||
278 inList("install-clean", config.Arguments()) {
Usta Shrestha675564d2022-08-09 18:03:23 -0400279 logArgsOtherThan("installclean", "install-clean")
Rupert Shuttleworth1f304e62020-11-24 14:13:41 +0000280 installClean(ctx, config)
Dan Willemsenf052f782017-05-18 15:29:04 -0700281 ctx.Println("Deleted images and staging directories.")
282 return
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000283 }
284
285 if inList("dataclean", config.Arguments()) ||
Colin Cross806fd942019-05-03 13:35:58 -0700286 inList("data-clean", config.Arguments()) {
Usta Shrestha675564d2022-08-09 18:03:23 -0400287 logArgsOtherThan("dataclean", "data-clean")
Rupert Shuttleworth1f304e62020-11-24 14:13:41 +0000288 dataClean(ctx, config)
Dan Willemsenf052f782017-05-18 15:29:04 -0700289 ctx.Println("Deleted data files.")
290 return
291 }
292
Anton Hansson5a7861a2021-06-04 10:09:01 +0100293 if what&RunSoong != 0 {
Dan Willemsen1e704462016-08-21 15:17:17 -0700294 runSoong(ctx, config)
295 }
296
Anton Hansson5a7861a2021-06-04 10:09:01 +0100297 if what&RunKati != 0 {
Dan Willemsen29971232018-09-26 14:58:30 -0700298 genKatiSuffix(ctx, config)
299 runKatiCleanSpec(ctx, config)
300 runKatiBuild(ctx, config)
Dan Willemsenfb1271a2018-09-26 15:00:42 -0700301 runKatiPackage(ctx, config)
Dan Willemsene0879fc2017-08-04 15:06:27 -0700302
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000303 ioutil.WriteFile(config.LastKatiSuffixFile(), []byte(config.KatiSuffix()), 0666) // a+rw
Anton Hansson0b55bdb2021-06-04 10:08:08 +0100304 } else if what&RunKatiNinja != 0 {
Dan Willemsene0879fc2017-08-04 15:06:27 -0700305 // Load last Kati Suffix if it exists
306 if katiSuffix, err := ioutil.ReadFile(config.LastKatiSuffixFile()); err == nil {
307 ctx.Verboseln("Loaded previous kati config:", string(katiSuffix))
308 config.SetKatiSuffix(string(katiSuffix))
309 }
Dan Willemsen1e704462016-08-21 15:17:17 -0700310 }
311
Colin Cross37193492017-11-16 17:55:00 -0800312 // Write combined ninja file
313 createCombinedBuildNinjaFile(ctx, config)
314
Colin Cross8ba7d472020-06-25 11:27:52 -0700315 distGzipFile(ctx, config, config.CombinedNinjaFile())
316
Colin Cross37193492017-11-16 17:55:00 -0800317 if what&RunBuildTests != 0 {
318 testForDanglingRules(ctx, config)
319 }
320
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400321 <-rbeCh
Anton Hansson5a7861a2021-06-04 10:09:01 +0100322 if what&RunNinja != 0 {
323 if what&RunKati != 0 {
Dan Willemsene0879fc2017-08-04 15:06:27 -0700324 installCleanIfNecessary(ctx, config)
325 }
Lukacs T. Berkid1e3f1f2021-03-16 08:55:23 +0100326 runNinjaForBuild(ctx, config)
Dan Willemsen1e704462016-08-21 15:17:17 -0700327 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800328
329 if what&RunDistActions != 0 {
330 runDistActions(ctx, config)
331 }
Dan Willemsen1e704462016-08-21 15:17:17 -0700332}
Colin Cross8ba7d472020-06-25 11:27:52 -0700333
usta6fffdd52022-09-19 13:16:18 -0400334func evaluateWhatToRun(config Config, verboseln func(v ...interface{})) int {
335 //evaluate what to run
Joe Onorato7f29a662023-02-23 15:47:06 -0800336 what := 0
usta6fffdd52022-09-19 13:16:18 -0400337 if config.Checkbuild() {
338 what |= RunBuildTests
339 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800340 if !config.SkipConfig() {
341 what |= RunProductConfig
342 } else {
usta6fffdd52022-09-19 13:16:18 -0400343 verboseln("Skipping Config as requested")
usta6fffdd52022-09-19 13:16:18 -0400344 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800345 if !config.SkipSoong() {
346 what |= RunSoong
347 } else {
usta6fffdd52022-09-19 13:16:18 -0400348 verboseln("Skipping use of Soong as requested")
usta6fffdd52022-09-19 13:16:18 -0400349 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800350 if !config.SkipKati() {
351 what |= RunKati
352 } else {
353 verboseln("Skipping Kati as requested")
354 }
355 if !config.SkipKatiNinja() {
356 what |= RunKatiNinja
357 } else {
358 verboseln("Skipping use of Kati ninja as requested")
359 }
360 if !config.SkipNinja() {
361 what |= RunNinja
362 } else {
usta6fffdd52022-09-19 13:16:18 -0400363 verboseln("Skipping Ninja as requested")
usta6fffdd52022-09-19 13:16:18 -0400364 }
365
366 if !config.SoongBuildInvocationNeeded() {
367 // This means that the output of soong_build is not needed and thus it would
368 // run unnecessarily. In addition, if this code wasn't there invocations
369 // with only special-cased target names like "m bp2build" would result in
370 // passing Ninja the empty target list and it would then build the default
371 // targets which is not what the user asked for.
372 what = what &^ RunNinja
373 what = what &^ RunKati
374 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800375
376 if config.Dist() {
377 what |= RunDistActions
378 }
379
usta6fffdd52022-09-19 13:16:18 -0400380 return what
381}
382
Dan Willemsen80d72612022-04-20 21:45:00 -0700383var distWaitGroup sync.WaitGroup
384
385// waitForDist waits for all backgrounded distGzipFile and distFile writes to finish
386func waitForDist(ctx Context) {
387 ctx.BeginTrace("soong_ui", "dist")
388 defer ctx.EndTrace()
389
390 distWaitGroup.Wait()
391}
392
Colin Cross8ba7d472020-06-25 11:27:52 -0700393// distGzipFile writes a compressed copy of src to the distDir if dist is enabled. Failures
Dan Willemsen80d72612022-04-20 21:45:00 -0700394// are printed but non-fatal. Uses the distWaitGroup func for backgrounding (optimization).
Colin Cross8ba7d472020-06-25 11:27:52 -0700395func distGzipFile(ctx Context, config Config, src string, subDirs ...string) {
396 if !config.Dist() {
397 return
398 }
399
400 subDir := filepath.Join(subDirs...)
Rupert Shuttleworth3c9f5ac2020-12-10 11:32:38 +0000401 destDir := filepath.Join(config.RealDistDir(), "soong_ui", subDir)
Colin Cross8ba7d472020-06-25 11:27:52 -0700402
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000403 if err := os.MkdirAll(destDir, 0777); err != nil { // a+rwx
Colin Cross8ba7d472020-06-25 11:27:52 -0700404 ctx.Printf("failed to mkdir %s: %s", destDir, err.Error())
Colin Cross8ba7d472020-06-25 11:27:52 -0700405 }
406
Dan Willemsen80d72612022-04-20 21:45:00 -0700407 distWaitGroup.Add(1)
408 go func() {
409 defer distWaitGroup.Done()
410 if err := gzipFileToDir(src, destDir); err != nil {
411 ctx.Printf("failed to dist %s: %s", filepath.Base(src), err.Error())
412 }
413 }()
Colin Cross8ba7d472020-06-25 11:27:52 -0700414}
415
416// distFile writes a copy of src to the distDir if dist is enabled. Failures are printed but
Dan Willemsen80d72612022-04-20 21:45:00 -0700417// non-fatal. Uses the distWaitGroup func for backgrounding (optimization).
Colin Cross8ba7d472020-06-25 11:27:52 -0700418func distFile(ctx Context, config Config, src string, subDirs ...string) {
419 if !config.Dist() {
420 return
421 }
422
423 subDir := filepath.Join(subDirs...)
Rupert Shuttleworth3c9f5ac2020-12-10 11:32:38 +0000424 destDir := filepath.Join(config.RealDistDir(), "soong_ui", subDir)
Colin Cross8ba7d472020-06-25 11:27:52 -0700425
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000426 if err := os.MkdirAll(destDir, 0777); err != nil { // a+rwx
Colin Cross8ba7d472020-06-25 11:27:52 -0700427 ctx.Printf("failed to mkdir %s: %s", destDir, err.Error())
Colin Cross8ba7d472020-06-25 11:27:52 -0700428 }
429
Dan Willemsen80d72612022-04-20 21:45:00 -0700430 distWaitGroup.Add(1)
431 go func() {
432 defer distWaitGroup.Done()
433 if _, err := copyFile(src, filepath.Join(destDir, filepath.Base(src))); err != nil {
434 ctx.Printf("failed to dist %s: %s", filepath.Base(src), err.Error())
435 }
436 }()
Colin Cross8ba7d472020-06-25 11:27:52 -0700437}
Joe Onorato7f29a662023-02-23 15:47:06 -0800438
439// Actions to run on every build where 'dist' is in the actions.
440// Be careful, anything added here slows down EVERY CI build
441func runDistActions(ctx Context, config Config) {
442 runStagingSnapshot(ctx, config)
443}