From 7b97ecd1f5a7501112659fa354ff1ce213e42aef Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Wed, 19 Jun 2019 13:17:59 -0700 Subject: [PATCH] Print ninja stdout live during the build When running ninja stream stdout to the status writer. This improves the ninja -d explain behavior, and will also allow Soong to be put into the ninja console pool letting it print timely output to the console. Bug: 80165685 Test: NINJA_ARGS="-d explain" m Change-Id: I40f03fc01d837ad91d400eae378007a7ce807705 --- ui/build/exec.go | 34 ++++++++++++++++++++++++++++++++++ ui/build/ninja.go | 2 +- ui/build/soong.go | 2 +- 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/ui/build/exec.go b/ui/build/exec.go index 5c312bcd9..e435c53be 100644 --- a/ui/build/exec.go +++ b/ui/build/exec.go @@ -15,7 +15,10 @@ package build import ( + "bufio" + "io" "os/exec" + "strings" ) // Cmd is a wrapper of os/exec.Cmd that integrates with the build context for @@ -139,3 +142,34 @@ func (c *Cmd) RunAndPrintOrFatal() { st.Finish() c.reportError(err) } + +// RunAndStreamOrFatal will run the command, while running print +// any output, then handle any errors with a call to ctx.Fatal +func (c *Cmd) RunAndStreamOrFatal() { + out, err := c.StdoutPipe() + if err != nil { + c.ctx.Fatal(err) + } + c.Stderr = c.Stdout + + st := c.ctx.Status.StartTool() + + c.StartOrFatal() + + buf := bufio.NewReaderSize(out, 2*1024*1024) + for { + // Attempt to read whole lines, but write partial lines that are too long to fit in the buffer or hit EOF + line, err := buf.ReadString('\n') + if line != "" { + st.Print(strings.TrimSuffix(line, "\n")) + } else if err == io.EOF { + break + } else if err != nil { + c.ctx.Fatal(err) + } + } + + err = c.Wait() + st.Finish() + c.reportError(err) +} diff --git a/ui/build/ninja.go b/ui/build/ninja.go index 7994f3a2d..b41ac208a 100644 --- a/ui/build/ninja.go +++ b/ui/build/ninja.go @@ -103,7 +103,7 @@ func runNinja(ctx Context, config Config) { }() ctx.Status.Status("Starting ninja...") - cmd.RunAndPrintOrFatal() + cmd.RunAndStreamOrFatal() } type statusChecker struct { diff --git a/ui/build/soong.go b/ui/build/soong.go index 2ce1ac935..338841702 100644 --- a/ui/build/soong.go +++ b/ui/build/soong.go @@ -120,7 +120,7 @@ func runSoong(ctx Context, config Config) { "--frontend_file", fifo, "-f", filepath.Join(config.SoongOutDir(), file)) cmd.Sandbox = soongSandbox - cmd.RunAndPrintOrFatal() + cmd.RunAndStreamOrFatal() } ninja("minibootstrap", ".minibootstrap/build.ninja")