blob: 6874ef74d2740fd65263c57999115d659c33fd8c [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 }
117 if config.bazelDevMode {
118 count++
119 }
120 if config.bazelStagingMode {
121 count++
122 }
123 if count > 1 {
Chris Parsons1bb58da2022-08-30 13:37:57 -0400124 ctx.Fatalln("Conflicting bazel mode.\n" +
MarkDacekb78465d2022-10-18 20:10:16 +0000125 "Do not specify more than one of --bazel-mode and --bazel-mode-dev and --bazel-mode-staging ")
Chris Parsonsef615e52022-08-18 22:04:11 -0400126 }
127}
128
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000129// 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 +0100130func checkProblematicFiles(ctx Context) {
131 files := []string{"Android.mk", "CleanSpec.mk"}
132 for _, file := range files {
133 if _, err := os.Stat(file); !os.IsNotExist(err) {
134 absolute := absPath(ctx, file)
135 ctx.Printf("Found %s in tree root. This file needs to be removed to build.\n", file)
136 ctx.Fatalf(" rm %s\n", absolute)
137 }
138 }
139}
140
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000141// checkCaseSensitivity issues a warning if a case-insensitive file system is being used.
Dan Willemsendb8457c2017-05-12 16:38:17 -0700142func checkCaseSensitivity(ctx Context, config Config) {
143 outDir := config.OutDir()
144 lowerCase := filepath.Join(outDir, "casecheck.txt")
145 upperCase := filepath.Join(outDir, "CaseCheck.txt")
146 lowerData := "a"
147 upperData := "B"
148
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000149 if err := ioutil.WriteFile(lowerCase, []byte(lowerData), 0666); err != nil { // a+rw
Dan Willemsendb8457c2017-05-12 16:38:17 -0700150 ctx.Fatalln("Failed to check case sensitivity:", err)
151 }
152
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000153 if err := ioutil.WriteFile(upperCase, []byte(upperData), 0666); err != nil { // a+rw
Dan Willemsendb8457c2017-05-12 16:38:17 -0700154 ctx.Fatalln("Failed to check case sensitivity:", err)
155 }
156
157 res, err := ioutil.ReadFile(lowerCase)
158 if err != nil {
159 ctx.Fatalln("Failed to check case sensitivity:", err)
160 }
161
162 if string(res) != lowerData {
163 ctx.Println("************************************************************")
164 ctx.Println("You are building on a case-insensitive filesystem.")
165 ctx.Println("Please move your source tree to a case-sensitive filesystem.")
166 ctx.Println("************************************************************")
167 ctx.Fatalln("Case-insensitive filesystems not supported")
168 }
169}
170
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000171// help prints a help/usage message, via the build/make/help.sh script.
172func help(ctx Context, config Config) {
Jeff Gastondf4a0812017-05-30 20:11:20 -0700173 cmd := Command(ctx, config, "help.sh", "build/make/help.sh")
Dan Willemsenb2e6c2e2017-07-13 17:24:44 -0700174 cmd.Sandbox = dumpvarsSandbox
Dan Willemsenb82471a2018-05-17 16:37:09 -0700175 cmd.RunAndPrintOrFatal()
Dan Willemsen02781d52017-05-12 19:28:13 -0700176}
177
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000178// checkRAM warns if there probably isn't enough RAM to complete a build.
179func checkRAM(ctx Context, config Config) {
Dan Willemsen570a2922020-05-26 23:02:29 -0700180 if totalRAM := config.TotalRAM(); totalRAM != 0 {
181 ram := float32(totalRAM) / (1024 * 1024 * 1024)
182 ctx.Verbosef("Total RAM: %.3vGB", ram)
183
184 if ram <= 16 {
185 ctx.Println("************************************************************")
186 ctx.Printf("You are building on a machine with %.3vGB of RAM\n", ram)
187 ctx.Println("")
188 ctx.Println("The minimum required amount of free memory is around 16GB,")
189 ctx.Println("and even with that, some configurations may not work.")
190 ctx.Println("")
191 ctx.Println("If you run into segfaults or other errors, try reducing your")
192 ctx.Println("-j value.")
193 ctx.Println("************************************************************")
194 } else if ram <= float32(config.Parallel()) {
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000195 // Want at least 1GB of RAM per job.
Dan Willemsen570a2922020-05-26 23:02:29 -0700196 ctx.Printf("Warning: high -j%d count compared to %.3vGB of RAM", config.Parallel(), ram)
197 ctx.Println("If you run into segfaults or other errors, try a lower -j value")
198 }
199 }
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000200}
201
Usta Shresthadb46a9b2022-07-11 11:29:56 -0400202// Build the tree. Various flags in `config` govern which components of
203// the build to run.
Anton Hansson5a7861a2021-06-04 10:09:01 +0100204func Build(ctx Context, config Config) {
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000205 ctx.Verboseln("Starting build with args:", config.Arguments())
206 ctx.Verboseln("Environment:", config.Environment().Environ())
Dan Willemsen1e704462016-08-21 15:17:17 -0700207
Colin Cross74cda722020-01-16 15:25:50 -0800208 ctx.BeginTrace(metrics.Total, "total")
209 defer ctx.EndTrace()
210
Dan Willemsen1e704462016-08-21 15:17:17 -0700211 if inList("help", config.Arguments()) {
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000212 help(ctx, config)
Dan Willemsen0b73b4b2017-05-12 19:28:13 -0700213 return
Dan Willemsen1e704462016-08-21 15:17:17 -0700214 }
215
Jeff Gaston3615fe82017-05-24 13:14:34 -0700216 // Make sure that no other Soong process is running with the same output directory
217 buildLock := BecomeSingletonOrFail(ctx, config)
218 defer buildLock.Unlock()
219
Usta Shrestha675564d2022-08-09 18:03:23 -0400220 logArgsOtherThan := func(specialTargets ...string) {
221 var ignored []string
222 for _, a := range config.Arguments() {
223 if !inList(a, specialTargets) {
224 ignored = append(ignored, a)
225 }
226 }
227 if len(ignored) > 0 {
228 ctx.Printf("ignoring arguments %q", ignored)
229 }
230 }
231
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000232 if inList("clean", config.Arguments()) || inList("clobber", config.Arguments()) {
Usta Shrestha675564d2022-08-09 18:03:23 -0400233 logArgsOtherThan("clean", "clobber")
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000234 clean(ctx, config)
235 return
236 }
237
Dan Willemsen80d72612022-04-20 21:45:00 -0700238 defer waitForDist(ctx)
239
Chris Parsonsef615e52022-08-18 22:04:11 -0400240 checkBazelMode(ctx, config)
241
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000242 // 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 +0100243 checkProblematicFiles(ctx)
244
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000245 checkRAM(ctx, config)
246
Dan Willemsen1e704462016-08-21 15:17:17 -0700247 SetupOutDir(ctx, config)
248
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000249 // checkCaseSensitivity issues a warning if a case-insensitive file system is being used.
Dan Willemsendb8457c2017-05-12 16:38:17 -0700250 checkCaseSensitivity(ctx, config)
251
Jeff Gastonefc1b412017-03-29 17:29:06 -0700252 ensureEmptyDirectoriesExist(ctx, config.TempDir())
253
Dan Willemsen18490112018-05-25 16:30:04 -0700254 SetupPath(ctx, config)
255
usta6fffdd52022-09-19 13:16:18 -0400256 what := evaluateWhatToRun(config, ctx.Verboseln)
Lukacs T. Berkia1b93722021-09-02 17:23:06 +0200257
Yoshisato Yanagisawa2cb0e5d2019-01-10 10:14:16 +0900258 if config.StartGoma() {
Yoshisato Yanagisawa2cb0e5d2019-01-10 10:14:16 +0900259 startGoma(ctx, config)
260 }
261
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400262 rbeCh := make(chan bool)
Ramy Medhatbbf25672019-07-17 12:30:04 +0000263 if config.StartRBE() {
Kousik Kumar4c180ad2022-05-27 07:48:37 -0400264 cleanupRBELogsDir(ctx, config)
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400265 go func() {
266 startRBE(ctx, config)
267 close(rbeCh)
268 }()
Kousik Kumara1d8fa92022-03-18 02:50:31 -0400269 defer DumpRBEMetrics(ctx, config, filepath.Join(config.LogsDir(), "rbe_metrics.pb"))
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400270 } else {
271 close(rbeCh)
Ramy Medhatbbf25672019-07-17 12:30:04 +0000272 }
273
Anton Hansson5a7861a2021-06-04 10:09:01 +0100274 if what&RunProductConfig != 0 {
Dan Willemsen1e704462016-08-21 15:17:17 -0700275 runMakeProductConfig(ctx, config)
276 }
277
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000278 // Everything below here depends on product config.
279
Colin Cross806fd942019-05-03 13:35:58 -0700280 if inList("installclean", config.Arguments()) ||
281 inList("install-clean", config.Arguments()) {
Usta Shrestha675564d2022-08-09 18:03:23 -0400282 logArgsOtherThan("installclean", "install-clean")
Rupert Shuttleworth1f304e62020-11-24 14:13:41 +0000283 installClean(ctx, config)
Dan Willemsenf052f782017-05-18 15:29:04 -0700284 ctx.Println("Deleted images and staging directories.")
285 return
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000286 }
287
288 if inList("dataclean", config.Arguments()) ||
Colin Cross806fd942019-05-03 13:35:58 -0700289 inList("data-clean", config.Arguments()) {
Usta Shrestha675564d2022-08-09 18:03:23 -0400290 logArgsOtherThan("dataclean", "data-clean")
Rupert Shuttleworth1f304e62020-11-24 14:13:41 +0000291 dataClean(ctx, config)
Dan Willemsenf052f782017-05-18 15:29:04 -0700292 ctx.Println("Deleted data files.")
293 return
294 }
295
Anton Hansson5a7861a2021-06-04 10:09:01 +0100296 if what&RunSoong != 0 {
Dan Willemsen1e704462016-08-21 15:17:17 -0700297 runSoong(ctx, config)
298 }
299
Anton Hansson5a7861a2021-06-04 10:09:01 +0100300 if what&RunKati != 0 {
Dan Willemsen29971232018-09-26 14:58:30 -0700301 genKatiSuffix(ctx, config)
302 runKatiCleanSpec(ctx, config)
303 runKatiBuild(ctx, config)
Dan Willemsenfb1271a2018-09-26 15:00:42 -0700304 runKatiPackage(ctx, config)
Dan Willemsene0879fc2017-08-04 15:06:27 -0700305
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000306 ioutil.WriteFile(config.LastKatiSuffixFile(), []byte(config.KatiSuffix()), 0666) // a+rw
Anton Hansson0b55bdb2021-06-04 10:08:08 +0100307 } else if what&RunKatiNinja != 0 {
Dan Willemsene0879fc2017-08-04 15:06:27 -0700308 // Load last Kati Suffix if it exists
309 if katiSuffix, err := ioutil.ReadFile(config.LastKatiSuffixFile()); err == nil {
310 ctx.Verboseln("Loaded previous kati config:", string(katiSuffix))
311 config.SetKatiSuffix(string(katiSuffix))
312 }
Dan Willemsen1e704462016-08-21 15:17:17 -0700313 }
314
Colin Cross37193492017-11-16 17:55:00 -0800315 // Write combined ninja file
316 createCombinedBuildNinjaFile(ctx, config)
317
Colin Cross8ba7d472020-06-25 11:27:52 -0700318 distGzipFile(ctx, config, config.CombinedNinjaFile())
319
Colin Cross37193492017-11-16 17:55:00 -0800320 if what&RunBuildTests != 0 {
321 testForDanglingRules(ctx, config)
322 }
323
Ramy Medhatc8f6cc22023-03-31 09:50:34 -0400324 <-rbeCh
Anton Hansson5a7861a2021-06-04 10:09:01 +0100325 if what&RunNinja != 0 {
326 if what&RunKati != 0 {
Dan Willemsene0879fc2017-08-04 15:06:27 -0700327 installCleanIfNecessary(ctx, config)
328 }
Lukacs T. Berkid1e3f1f2021-03-16 08:55:23 +0100329 runNinjaForBuild(ctx, config)
Dan Willemsen1e704462016-08-21 15:17:17 -0700330 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800331
332 if what&RunDistActions != 0 {
333 runDistActions(ctx, config)
334 }
Dan Willemsen1e704462016-08-21 15:17:17 -0700335}
Colin Cross8ba7d472020-06-25 11:27:52 -0700336
usta6fffdd52022-09-19 13:16:18 -0400337func evaluateWhatToRun(config Config, verboseln func(v ...interface{})) int {
338 //evaluate what to run
Joe Onorato7f29a662023-02-23 15:47:06 -0800339 what := 0
usta6fffdd52022-09-19 13:16:18 -0400340 if config.Checkbuild() {
341 what |= RunBuildTests
342 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800343 if !config.SkipConfig() {
344 what |= RunProductConfig
345 } else {
usta6fffdd52022-09-19 13:16:18 -0400346 verboseln("Skipping Config as requested")
usta6fffdd52022-09-19 13:16:18 -0400347 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800348 if !config.SkipSoong() {
349 what |= RunSoong
350 } else {
usta6fffdd52022-09-19 13:16:18 -0400351 verboseln("Skipping use of Soong as requested")
usta6fffdd52022-09-19 13:16:18 -0400352 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800353 if !config.SkipKati() {
354 what |= RunKati
355 } else {
356 verboseln("Skipping Kati as requested")
357 }
358 if !config.SkipKatiNinja() {
359 what |= RunKatiNinja
360 } else {
361 verboseln("Skipping use of Kati ninja as requested")
362 }
363 if !config.SkipNinja() {
364 what |= RunNinja
365 } else {
usta6fffdd52022-09-19 13:16:18 -0400366 verboseln("Skipping Ninja as requested")
usta6fffdd52022-09-19 13:16:18 -0400367 }
368
369 if !config.SoongBuildInvocationNeeded() {
370 // This means that the output of soong_build is not needed and thus it would
371 // run unnecessarily. In addition, if this code wasn't there invocations
372 // with only special-cased target names like "m bp2build" would result in
373 // passing Ninja the empty target list and it would then build the default
374 // targets which is not what the user asked for.
375 what = what &^ RunNinja
376 what = what &^ RunKati
377 }
Joe Onorato7f29a662023-02-23 15:47:06 -0800378
379 if config.Dist() {
380 what |= RunDistActions
381 }
382
usta6fffdd52022-09-19 13:16:18 -0400383 return what
384}
385
Dan Willemsen80d72612022-04-20 21:45:00 -0700386var distWaitGroup sync.WaitGroup
387
388// waitForDist waits for all backgrounded distGzipFile and distFile writes to finish
389func waitForDist(ctx Context) {
390 ctx.BeginTrace("soong_ui", "dist")
391 defer ctx.EndTrace()
392
393 distWaitGroup.Wait()
394}
395
Colin Cross8ba7d472020-06-25 11:27:52 -0700396// distGzipFile writes a compressed copy of src to the distDir if dist is enabled. Failures
Dan Willemsen80d72612022-04-20 21:45:00 -0700397// are printed but non-fatal. Uses the distWaitGroup func for backgrounding (optimization).
Colin Cross8ba7d472020-06-25 11:27:52 -0700398func distGzipFile(ctx Context, config Config, src string, subDirs ...string) {
399 if !config.Dist() {
400 return
401 }
402
403 subDir := filepath.Join(subDirs...)
Rupert Shuttleworth3c9f5ac2020-12-10 11:32:38 +0000404 destDir := filepath.Join(config.RealDistDir(), "soong_ui", subDir)
Colin Cross8ba7d472020-06-25 11:27:52 -0700405
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000406 if err := os.MkdirAll(destDir, 0777); err != nil { // a+rwx
Colin Cross8ba7d472020-06-25 11:27:52 -0700407 ctx.Printf("failed to mkdir %s: %s", destDir, err.Error())
Colin Cross8ba7d472020-06-25 11:27:52 -0700408 }
409
Dan Willemsen80d72612022-04-20 21:45:00 -0700410 distWaitGroup.Add(1)
411 go func() {
412 defer distWaitGroup.Done()
413 if err := gzipFileToDir(src, destDir); err != nil {
414 ctx.Printf("failed to dist %s: %s", filepath.Base(src), err.Error())
415 }
416 }()
Colin Cross8ba7d472020-06-25 11:27:52 -0700417}
418
419// distFile writes a copy of src to the distDir if dist is enabled. Failures are printed but
Dan Willemsen80d72612022-04-20 21:45:00 -0700420// non-fatal. Uses the distWaitGroup func for backgrounding (optimization).
Colin Cross8ba7d472020-06-25 11:27:52 -0700421func distFile(ctx Context, config Config, src string, subDirs ...string) {
422 if !config.Dist() {
423 return
424 }
425
426 subDir := filepath.Join(subDirs...)
Rupert Shuttleworth3c9f5ac2020-12-10 11:32:38 +0000427 destDir := filepath.Join(config.RealDistDir(), "soong_ui", subDir)
Colin Cross8ba7d472020-06-25 11:27:52 -0700428
Rupert Shuttlewortheeb5caa2020-11-25 07:13:54 +0000429 if err := os.MkdirAll(destDir, 0777); err != nil { // a+rwx
Colin Cross8ba7d472020-06-25 11:27:52 -0700430 ctx.Printf("failed to mkdir %s: %s", destDir, err.Error())
Colin Cross8ba7d472020-06-25 11:27:52 -0700431 }
432
Dan Willemsen80d72612022-04-20 21:45:00 -0700433 distWaitGroup.Add(1)
434 go func() {
435 defer distWaitGroup.Done()
436 if _, err := copyFile(src, filepath.Join(destDir, filepath.Base(src))); err != nil {
437 ctx.Printf("failed to dist %s: %s", filepath.Base(src), err.Error())
438 }
439 }()
Colin Cross8ba7d472020-06-25 11:27:52 -0700440}
Joe Onorato7f29a662023-02-23 15:47:06 -0800441
442// Actions to run on every build where 'dist' is in the actions.
443// Be careful, anything added here slows down EVERY CI build
444func runDistActions(ctx Context, config Config) {
445 runStagingSnapshot(ctx, config)
446}