blob: 69e4f696c4514c72e0fc2c7e2e4d5453cbbaf88b [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 main
16
17import (
18 "context"
Dan Willemsen051133b2017-07-14 11:29:29 -070019 "flag"
20 "fmt"
Dan Willemsen1e704462016-08-21 15:17:17 -070021 "os"
22 "path/filepath"
23 "strconv"
24 "strings"
25 "time"
26
27 "android/soong/ui/build"
28 "android/soong/ui/logger"
Nan Zhang17f27672018-12-12 16:01:49 -080029 "android/soong/ui/metrics"
Dan Willemsenb82471a2018-05-17 16:37:09 -070030 "android/soong/ui/status"
31 "android/soong/ui/terminal"
Dan Willemsend9f6fa22016-08-21 15:17:17 -070032 "android/soong/ui/tracer"
Dan Willemsen1e704462016-08-21 15:17:17 -070033)
34
Patrice Arrudaa5c25422019-04-09 18:49:49 -070035// A command represents an operation to be executed in the soong build
36// system.
37type command struct {
Patrice Arrudaf445ba12020-07-28 17:49:01 +000038 // The flag name (must have double dashes).
Patrice Arrudaa5c25422019-04-09 18:49:49 -070039 flag string
40
Patrice Arrudaf445ba12020-07-28 17:49:01 +000041 // Description for the flag (to display when running help).
Patrice Arrudaa5c25422019-04-09 18:49:49 -070042 description string
43
Patrice Arrudaf445ba12020-07-28 17:49:01 +000044 // Stream the build status output into the simple terminal mode.
45 simpleOutput bool
Colin Crossc0b9f6b2019-09-23 12:44:54 -070046
47 // Sets a prefix string to use for filenames of log files.
48 logsPrefix string
49
Patrice Arrudaa5c25422019-04-09 18:49:49 -070050 // Creates the build configuration based on the args and build context.
51 config func(ctx build.Context, args ...string) build.Config
52
53 // Returns what type of IO redirection this Command requires.
54 stdio func() terminal.StdioInterface
55
56 // run the command
57 run func(ctx build.Context, config build.Config, args []string, logsDir string)
58}
59
60const makeModeFlagName = "--make-mode"
61
62// list of supported commands (flags) supported by soong ui
63var commands []command = []command{
64 {
65 flag: makeModeFlagName,
66 description: "build the modules by the target name (i.e. soong_docs)",
67 config: func(ctx build.Context, args ...string) build.Config {
68 return build.NewConfig(ctx, args...)
69 },
Patrice Arrudab7b22822019-05-21 17:46:23 -070070 stdio: stdio,
71 run: make,
Patrice Arrudaa5c25422019-04-09 18:49:49 -070072 }, {
Patrice Arrudaf445ba12020-07-28 17:49:01 +000073 flag: "--dumpvar-mode",
74 description: "print the value of the legacy make variable VAR to stdout",
75 simpleOutput: true,
76 logsPrefix: "dumpvars-",
77 config: dumpVarConfig,
78 stdio: customStdio,
79 run: dumpVar,
Patrice Arrudaa5c25422019-04-09 18:49:49 -070080 }, {
Patrice Arrudaf445ba12020-07-28 17:49:01 +000081 flag: "--dumpvars-mode",
82 description: "dump the values of one or more legacy make variables, in shell syntax",
83 simpleOutput: true,
84 logsPrefix: "dumpvars-",
85 config: dumpVarConfig,
86 stdio: customStdio,
87 run: dumpVars,
Patrice Arrudab7b22822019-05-21 17:46:23 -070088 }, {
89 flag: "--build-mode",
90 description: "build modules based on the specified build action",
91 config: buildActionConfig,
92 stdio: stdio,
93 run: make,
Patrice Arrudaa5c25422019-04-09 18:49:49 -070094 },
95}
96
97// indexList returns the index of first found s. -1 is return if s is not
98// found.
Dan Willemsen1e704462016-08-21 15:17:17 -070099func indexList(s string, list []string) int {
100 for i, l := range list {
101 if l == s {
102 return i
103 }
104 }
Dan Willemsen1e704462016-08-21 15:17:17 -0700105 return -1
106}
107
Patrice Arrudaa5c25422019-04-09 18:49:49 -0700108// inList returns true if one or more of s is in the list.
Dan Willemsen1e704462016-08-21 15:17:17 -0700109func inList(s string, list []string) bool {
110 return indexList(s, list) != -1
111}
112
Patrice Arrudaa5c25422019-04-09 18:49:49 -0700113// Main execution of soong_ui. The command format is as follows:
114//
115// soong_ui <command> [<arg 1> <arg 2> ... <arg n>]
116//
117// Command is the type of soong_ui execution. Only one type of
118// execution is specified. The args are specific to the command.
Dan Willemsen1e704462016-08-21 15:17:17 -0700119func main() {
Patrice Arruda73c790f2020-07-13 23:01:18 +0000120 buildStarted := time.Now()
Patrice Arruda219eef32020-06-01 17:29:30 +0000121
Patrice Arrudaa5c25422019-04-09 18:49:49 -0700122 c, args := getCommand(os.Args)
123 if c == nil {
124 fmt.Fprintf(os.Stderr, "The `soong` native UI is not yet available.\n")
125 os.Exit(1)
Dan Willemsenc35b3812018-07-16 19:59:10 -0700126 }
127
Patrice Arrudaf445ba12020-07-28 17:49:01 +0000128 output := terminal.NewStatusOutput(c.stdio().Stdout(), os.Getenv("NINJA_STATUS"), c.simpleOutput,
Colin Crosse0df1a32019-06-09 19:40:08 -0700129 build.OsEnvironment().IsEnvTrue("ANDROID_QUIET_BUILD"))
Dan Willemsenb82471a2018-05-17 16:37:09 -0700130
Colin Crosse0df1a32019-06-09 19:40:08 -0700131 log := logger.New(output)
Dan Willemsen1e704462016-08-21 15:17:17 -0700132 defer log.Cleanup()
133
Dan Willemsen1e704462016-08-21 15:17:17 -0700134 ctx, cancel := context.WithCancel(context.Background())
135 defer cancel()
136
Dan Willemsend9f6fa22016-08-21 15:17:17 -0700137 trace := tracer.New(log)
138 defer trace.Close()
Dan Willemsen1e704462016-08-21 15:17:17 -0700139
Nan Zhang17f27672018-12-12 16:01:49 -0800140 met := metrics.New()
Patrice Arruda73c790f2020-07-13 23:01:18 +0000141 met.SetBuildDateTime(buildStarted)
Nan Zhang17f27672018-12-12 16:01:49 -0800142
Dan Willemsenb82471a2018-05-17 16:37:09 -0700143 stat := &status.Status{}
144 defer stat.Finish()
Colin Crosse0df1a32019-06-09 19:40:08 -0700145 stat.AddOutput(output)
Dan Willemsenb82471a2018-05-17 16:37:09 -0700146 stat.AddOutput(trace.StatusTracer())
147
Dan Willemsend9f6fa22016-08-21 15:17:17 -0700148 build.SetupSignals(log, cancel, func() {
149 trace.Close()
150 log.Cleanup()
Dan Willemsenb82471a2018-05-17 16:37:09 -0700151 stat.Finish()
Dan Willemsend9f6fa22016-08-21 15:17:17 -0700152 })
153
Dan Willemsen59339a22018-07-22 21:18:45 -0700154 buildCtx := build.Context{ContextImpl: &build.ContextImpl{
Dan Willemsenb82471a2018-05-17 16:37:09 -0700155 Context: ctx,
156 Logger: log,
Nan Zhang17f27672018-12-12 16:01:49 -0800157 Metrics: met,
Dan Willemsenb82471a2018-05-17 16:37:09 -0700158 Tracer: trace,
Colin Crosse0df1a32019-06-09 19:40:08 -0700159 Writer: output,
Dan Willemsenb82471a2018-05-17 16:37:09 -0700160 Status: stat,
Dan Willemsend9f6fa22016-08-21 15:17:17 -0700161 }}
Patrice Arrudaa5c25422019-04-09 18:49:49 -0700162
163 config := c.config(buildCtx, args...)
Dan Willemsen1e704462016-08-21 15:17:17 -0700164
Dan Willemsend9f6fa22016-08-21 15:17:17 -0700165 build.SetupOutDir(buildCtx, config)
Dan Willemsen8a073a82017-02-04 17:30:44 -0800166
Dan Willemsenb82471a2018-05-17 16:37:09 -0700167 logsDir := config.OutDir()
Dan Willemsen8a073a82017-02-04 17:30:44 -0800168 if config.Dist() {
Dan Willemsenb82471a2018-05-17 16:37:09 -0700169 logsDir = filepath.Join(config.DistDir(), "logs")
Dan Willemsen8a073a82017-02-04 17:30:44 -0800170 }
Dan Willemsen1e704462016-08-21 15:17:17 -0700171
Patrice Arruda219eef32020-06-01 17:29:30 +0000172 buildErrorFile := filepath.Join(logsDir, c.logsPrefix+"build_error")
173 rbeMetricsFile := filepath.Join(logsDir, c.logsPrefix+"rbe_metrics.pb")
174 soongMetricsFile := filepath.Join(logsDir, c.logsPrefix+"soong_metrics")
Patrice Arrudaf445ba12020-07-28 17:49:01 +0000175 defer build.UploadMetrics(buildCtx, config, c.simpleOutput, buildStarted, buildErrorFile, rbeMetricsFile, soongMetricsFile)
Patrice Arruda219eef32020-06-01 17:29:30 +0000176
Dan Willemsenb82471a2018-05-17 16:37:09 -0700177 os.MkdirAll(logsDir, 0777)
Colin Crossc0b9f6b2019-09-23 12:44:54 -0700178 log.SetOutput(filepath.Join(logsDir, c.logsPrefix+"soong.log"))
179 trace.SetOutput(filepath.Join(logsDir, c.logsPrefix+"build.trace"))
180 stat.AddOutput(status.NewVerboseLog(log, filepath.Join(logsDir, c.logsPrefix+"verbose.log")))
181 stat.AddOutput(status.NewErrorLog(log, filepath.Join(logsDir, c.logsPrefix+"error.log")))
Patrice Arruda219eef32020-06-01 17:29:30 +0000182 stat.AddOutput(status.NewProtoErrorLog(log, buildErrorFile))
Colin Cross7b624532019-06-21 15:08:30 -0700183 stat.AddOutput(status.NewCriticalPath(log))
Patrice Arruda74b43992020-03-11 08:21:05 -0700184 stat.AddOutput(status.NewBuildProgressLog(log, filepath.Join(logsDir, c.logsPrefix+"build_progress.pb")))
Dan Willemsenb82471a2018-05-17 16:37:09 -0700185
Colin Cross8b8bec32019-11-15 13:18:43 -0800186 buildCtx.Verbosef("Detected %.3v GB total RAM", float32(config.TotalRAM())/(1024*1024*1024))
187 buildCtx.Verbosef("Parallelism (local/remote/highmem): %v/%v/%v",
188 config.Parallel(), config.RemoteParallel(), config.HighmemParallel())
189
Patrice Arruda219eef32020-06-01 17:29:30 +0000190 defer met.Dump(soongMetricsFile)
Patrice Arruda62f1bf22020-07-07 12:48:26 +0000191 defer build.DumpRBEMetrics(buildCtx, config, rbeMetricsFile)
Nan Zhangd50f53b2019-01-07 20:26:51 -0800192
Dan Willemsen1e704462016-08-21 15:17:17 -0700193 if start, ok := os.LookupEnv("TRACE_BEGIN_SOONG"); ok {
194 if !strings.HasSuffix(start, "N") {
195 if start_time, err := strconv.ParseUint(start, 10, 64); err == nil {
196 log.Verbosef("Took %dms to start up.",
197 time.Since(time.Unix(0, int64(start_time))).Nanoseconds()/time.Millisecond.Nanoseconds())
Nan Zhang17f27672018-12-12 16:01:49 -0800198 buildCtx.CompleteTrace(metrics.RunSetupTool, "startup", start_time, uint64(time.Now().UnixNano()))
Dan Willemsen1e704462016-08-21 15:17:17 -0700199 }
200 }
Dan Willemsencae59bc2017-07-13 14:27:31 -0700201
202 if executable, err := os.Executable(); err == nil {
203 trace.ImportMicrofactoryLog(filepath.Join(filepath.Dir(executable), "."+filepath.Base(executable)+".trace"))
204 }
Dan Willemsen1e704462016-08-21 15:17:17 -0700205 }
206
Dan Willemsen6b783c82019-03-08 11:42:28 -0800207 // Fix up the source tree due to a repo bug where it doesn't remove
208 // linkfiles that have been removed
209 fixBadDanglingLink(buildCtx, "hardware/qcom/sdm710/Android.bp")
210 fixBadDanglingLink(buildCtx, "hardware/qcom/sdm710/Android.mk")
211
Jeff Gastonb64fc1c2017-08-04 12:30:12 -0700212 f := build.NewSourceFinder(buildCtx, config)
213 defer f.Shutdown()
214 build.FindSources(buildCtx, config, f)
215
Patrice Arrudaa5c25422019-04-09 18:49:49 -0700216 c.run(buildCtx, config, args, logsDir)
Dan Willemsen051133b2017-07-14 11:29:29 -0700217}
218
Dan Willemsen6b783c82019-03-08 11:42:28 -0800219func fixBadDanglingLink(ctx build.Context, name string) {
220 _, err := os.Lstat(name)
221 if err != nil {
222 return
223 }
224 _, err = os.Stat(name)
225 if os.IsNotExist(err) {
226 err = os.Remove(name)
227 if err != nil {
228 ctx.Fatalf("Failed to remove dangling link %q: %v", name, err)
229 }
230 }
231}
232
Patrice Arrudaa5c25422019-04-09 18:49:49 -0700233func dumpVar(ctx build.Context, config build.Config, args []string, _ string) {
Dan Willemsen051133b2017-07-14 11:29:29 -0700234 flags := flag.NewFlagSet("dumpvar", flag.ExitOnError)
235 flags.Usage = func() {
Patrice Arrudadb4c2f12019-06-17 17:27:09 -0700236 fmt.Fprintf(ctx.Writer, "usage: %s --dumpvar-mode [--abs] <VAR>\n\n", os.Args[0])
237 fmt.Fprintln(ctx.Writer, "In dumpvar mode, print the value of the legacy make variable VAR to stdout")
238 fmt.Fprintln(ctx.Writer, "")
Dan Willemsen051133b2017-07-14 11:29:29 -0700239
Patrice Arrudadb4c2f12019-06-17 17:27:09 -0700240 fmt.Fprintln(ctx.Writer, "'report_config' is a special case that prints the human-readable config banner")
241 fmt.Fprintln(ctx.Writer, "from the beginning of the build.")
242 fmt.Fprintln(ctx.Writer, "")
Dan Willemsen051133b2017-07-14 11:29:29 -0700243 flags.PrintDefaults()
244 }
245 abs := flags.Bool("abs", false, "Print the absolute path of the value")
246 flags.Parse(args)
247
248 if flags.NArg() != 1 {
249 flags.Usage()
250 os.Exit(1)
251 }
252
253 varName := flags.Arg(0)
254 if varName == "report_config" {
255 varData, err := build.DumpMakeVars(ctx, config, nil, build.BannerVars)
256 if err != nil {
257 ctx.Fatal(err)
258 }
259
260 fmt.Println(build.Banner(varData))
261 } else {
262 varData, err := build.DumpMakeVars(ctx, config, nil, []string{varName})
263 if err != nil {
264 ctx.Fatal(err)
265 }
266
267 if *abs {
268 var res []string
269 for _, path := range strings.Fields(varData[varName]) {
270 if abs, err := filepath.Abs(path); err == nil {
271 res = append(res, abs)
272 } else {
273 ctx.Fatalln("Failed to get absolute path of", path, err)
274 }
275 }
276 fmt.Println(strings.Join(res, " "))
277 } else {
278 fmt.Println(varData[varName])
279 }
280 }
281}
282
Patrice Arrudaa5c25422019-04-09 18:49:49 -0700283func dumpVars(ctx build.Context, config build.Config, args []string, _ string) {
Dan Willemsen051133b2017-07-14 11:29:29 -0700284 flags := flag.NewFlagSet("dumpvars", flag.ExitOnError)
285 flags.Usage = func() {
Patrice Arrudadb4c2f12019-06-17 17:27:09 -0700286 fmt.Fprintf(ctx.Writer, "usage: %s --dumpvars-mode [--vars=\"VAR VAR ...\"]\n\n", os.Args[0])
287 fmt.Fprintln(ctx.Writer, "In dumpvars mode, dump the values of one or more legacy make variables, in")
288 fmt.Fprintln(ctx.Writer, "shell syntax. The resulting output may be sourced directly into a shell to")
289 fmt.Fprintln(ctx.Writer, "set corresponding shell variables.")
290 fmt.Fprintln(ctx.Writer, "")
Dan Willemsen051133b2017-07-14 11:29:29 -0700291
Patrice Arrudadb4c2f12019-06-17 17:27:09 -0700292 fmt.Fprintln(ctx.Writer, "'report_config' is a special case that dumps a variable containing the")
293 fmt.Fprintln(ctx.Writer, "human-readable config banner from the beginning of the build.")
294 fmt.Fprintln(ctx.Writer, "")
Dan Willemsen051133b2017-07-14 11:29:29 -0700295 flags.PrintDefaults()
296 }
297
298 varsStr := flags.String("vars", "", "Space-separated list of variables to dump")
299 absVarsStr := flags.String("abs-vars", "", "Space-separated list of variables to dump (using absolute paths)")
300
301 varPrefix := flags.String("var-prefix", "", "String to prepend to all variable names when dumping")
302 absVarPrefix := flags.String("abs-var-prefix", "", "String to prepent to all absolute path variable names when dumping")
303
304 flags.Parse(args)
305
306 if flags.NArg() != 0 {
307 flags.Usage()
308 os.Exit(1)
309 }
310
311 vars := strings.Fields(*varsStr)
312 absVars := strings.Fields(*absVarsStr)
313
314 allVars := append([]string{}, vars...)
315 allVars = append(allVars, absVars...)
316
317 if i := indexList("report_config", allVars); i != -1 {
318 allVars = append(allVars[:i], allVars[i+1:]...)
319 allVars = append(allVars, build.BannerVars...)
320 }
321
322 if len(allVars) == 0 {
323 return
324 }
325
326 varData, err := build.DumpMakeVars(ctx, config, nil, allVars)
327 if err != nil {
328 ctx.Fatal(err)
329 }
330
331 for _, name := range vars {
332 if name == "report_config" {
333 fmt.Printf("%sreport_config='%s'\n", *varPrefix, build.Banner(varData))
334 } else {
335 fmt.Printf("%s%s='%s'\n", *varPrefix, name, varData[name])
336 }
337 }
338 for _, name := range absVars {
339 var res []string
340 for _, path := range strings.Fields(varData[name]) {
341 abs, err := filepath.Abs(path)
342 if err != nil {
343 ctx.Fatalln("Failed to get absolute path of", path, err)
344 }
345 res = append(res, abs)
346 }
347 fmt.Printf("%s%s='%s'\n", *absVarPrefix, name, strings.Join(res, " "))
348 }
Dan Willemsen1e704462016-08-21 15:17:17 -0700349}
Patrice Arrudaa5c25422019-04-09 18:49:49 -0700350
Patrice Arrudab7b22822019-05-21 17:46:23 -0700351func stdio() terminal.StdioInterface {
352 return terminal.StdioImpl{}
353}
354
Patrice Arrudaa5c25422019-04-09 18:49:49 -0700355func customStdio() terminal.StdioInterface {
356 return terminal.NewCustomStdio(os.Stdin, os.Stderr, os.Stderr)
357}
358
359// dumpVarConfig does not require any arguments to be parsed by the NewConfig.
360func dumpVarConfig(ctx build.Context, args ...string) build.Config {
361 return build.NewConfig(ctx)
362}
363
Patrice Arrudab7b22822019-05-21 17:46:23 -0700364func buildActionConfig(ctx build.Context, args ...string) build.Config {
365 flags := flag.NewFlagSet("build-mode", flag.ContinueOnError)
366 flags.Usage = func() {
367 fmt.Fprintf(ctx.Writer, "usage: %s --build-mode --dir=<path> <build action> [<build arg 1> <build arg 2> ...]\n\n", os.Args[0])
368 fmt.Fprintln(ctx.Writer, "In build mode, build the set of modules based on the specified build")
369 fmt.Fprintln(ctx.Writer, "action. The --dir flag is required to determine what is needed to")
370 fmt.Fprintln(ctx.Writer, "build in the source tree based on the build action. See below for")
371 fmt.Fprintln(ctx.Writer, "the list of acceptable build action flags.")
372 fmt.Fprintln(ctx.Writer, "")
373 flags.PrintDefaults()
374 }
375
376 buildActionFlags := []struct {
Dan Willemsence41e942019-07-29 23:39:30 -0700377 name string
378 description string
379 action build.BuildAction
380 set bool
Patrice Arrudab7b22822019-05-21 17:46:23 -0700381 }{{
Dan Willemsence41e942019-07-29 23:39:30 -0700382 name: "all-modules",
383 description: "Build action: build from the top of the source tree.",
384 action: build.BUILD_MODULES,
Patrice Arrudab7b22822019-05-21 17:46:23 -0700385 }, {
Dan Willemsence41e942019-07-29 23:39:30 -0700386 // This is redirecting to mma build command behaviour. Once it has soaked for a
387 // while, the build command is deleted from here once it has been removed from the
388 // envsetup.sh.
389 name: "modules-in-a-dir-no-deps",
390 description: "Build action: builds all of the modules in the current directory without their dependencies.",
391 action: build.BUILD_MODULES_IN_A_DIRECTORY,
Patrice Arrudab7b22822019-05-21 17:46:23 -0700392 }, {
Dan Willemsence41e942019-07-29 23:39:30 -0700393 // This is redirecting to mmma build command behaviour. Once it has soaked for a
394 // while, the build command is deleted from here once it has been removed from the
395 // envsetup.sh.
396 name: "modules-in-dirs-no-deps",
397 description: "Build action: builds all of the modules in the supplied directories without their dependencies.",
398 action: build.BUILD_MODULES_IN_DIRECTORIES,
Patrice Arrudab7b22822019-05-21 17:46:23 -0700399 }, {
Dan Willemsence41e942019-07-29 23:39:30 -0700400 name: "modules-in-a-dir",
401 description: "Build action: builds all of the modules in the current directory and their dependencies.",
402 action: build.BUILD_MODULES_IN_A_DIRECTORY,
Patrice Arrudab7b22822019-05-21 17:46:23 -0700403 }, {
Dan Willemsence41e942019-07-29 23:39:30 -0700404 name: "modules-in-dirs",
405 description: "Build action: builds all of the modules in the supplied directories and their dependencies.",
406 action: build.BUILD_MODULES_IN_DIRECTORIES,
Patrice Arrudab7b22822019-05-21 17:46:23 -0700407 }}
408 for i, flag := range buildActionFlags {
409 flags.BoolVar(&buildActionFlags[i].set, flag.name, false, flag.description)
410 }
411 dir := flags.String("dir", "", "Directory of the executed build command.")
412
413 // Only interested in the first two args which defines the build action and the directory.
414 // The remaining arguments are passed down to the config.
415 const numBuildActionFlags = 2
416 if len(args) < numBuildActionFlags {
417 flags.Usage()
418 ctx.Fatalln("Improper build action arguments.")
419 }
420 flags.Parse(args[0:numBuildActionFlags])
421
422 // The next block of code is to validate that exactly one build action is set and the dir flag
423 // is specified.
424 buildActionCount := 0
425 var buildAction build.BuildAction
Patrice Arrudab7b22822019-05-21 17:46:23 -0700426 for _, flag := range buildActionFlags {
427 if flag.set {
428 buildActionCount++
429 buildAction = flag.action
Patrice Arrudab7b22822019-05-21 17:46:23 -0700430 }
431 }
432 if buildActionCount != 1 {
433 ctx.Fatalln("Build action not defined.")
434 }
435 if *dir == "" {
436 ctx.Fatalln("-dir not specified.")
437 }
438
439 // Remove the build action flags from the args as they are not recognized by the config.
440 args = args[numBuildActionFlags:]
Dan Willemsence41e942019-07-29 23:39:30 -0700441 return build.NewBuildActionConfig(buildAction, *dir, ctx, args...)
Patrice Arrudab7b22822019-05-21 17:46:23 -0700442}
443
Patrice Arrudaa5c25422019-04-09 18:49:49 -0700444func make(ctx build.Context, config build.Config, _ []string, logsDir string) {
445 if config.IsVerbose() {
446 writer := ctx.Writer
Colin Cross097ed2a2019-06-08 21:48:58 -0700447 fmt.Fprintln(writer, "! The argument `showcommands` is no longer supported.")
448 fmt.Fprintln(writer, "! Instead, the verbose log is always written to a compressed file in the output dir:")
449 fmt.Fprintln(writer, "!")
450 fmt.Fprintf(writer, "! gzip -cd %s/verbose.log.gz | less -R\n", logsDir)
451 fmt.Fprintln(writer, "!")
452 fmt.Fprintln(writer, "! Older versions are saved in verbose.log.#.gz files")
453 fmt.Fprintln(writer, "")
Dan Willemsenc6360832019-07-25 14:07:36 -0700454 select {
455 case <-time.After(5 * time.Second):
456 case <-ctx.Done():
457 return
458 }
459 }
460
461 if _, ok := config.Environment().Get("ONE_SHOT_MAKEFILE"); ok {
462 writer := ctx.Writer
Dan Willemsence41e942019-07-29 23:39:30 -0700463 fmt.Fprintln(writer, "! The variable `ONE_SHOT_MAKEFILE` is obsolete.")
Dan Willemsenc6360832019-07-25 14:07:36 -0700464 fmt.Fprintln(writer, "!")
465 fmt.Fprintln(writer, "! If you're using `mm`, you'll need to run `source build/envsetup.sh` to update.")
466 fmt.Fprintln(writer, "!")
467 fmt.Fprintln(writer, "! Otherwise, either specify a module name with m, or use mma / MODULES-IN-...")
468 fmt.Fprintln(writer, "")
Dan Willemsence41e942019-07-29 23:39:30 -0700469 ctx.Fatal("done")
Patrice Arrudaa5c25422019-04-09 18:49:49 -0700470 }
471
472 toBuild := build.BuildAll
473 if config.Checkbuild() {
474 toBuild |= build.RunBuildTests
475 }
476 build.Build(ctx, config, toBuild)
477}
478
479// getCommand finds the appropriate command based on args[1] flag. args[0]
480// is the soong_ui filename.
481func getCommand(args []string) (*command, []string) {
482 if len(args) < 2 {
483 return nil, args
484 }
485
486 for _, c := range commands {
487 if c.flag == args[1] {
488 return &c, args[2:]
489 }
490
491 // special case for --make-mode: if soong_ui was called from
492 // build/make/core/main.mk, the makeparallel with --ninja
493 // option specified puts the -j<num> before --make-mode.
494 // TODO: Remove this hack once it has been fixed.
495 if c.flag == makeModeFlagName {
496 if inList(makeModeFlagName, args) {
497 return &c, args[1:]
498 }
499 }
500 }
501
502 // command not found
503 return nil, args
504}