Add build tracing

This creates a rotating build.trace.gz in the out directory that can be
loaded with chrome://tracing. It'll include start and end timings for
make/soong/kati/ninja, and it will import and time-correct the ninja log
files.

Test: m -j; load out/build.trace.gz in chrome://tracing
Test: multiproduct_kati -keep; load out/multiproduct*/build.trace.gz
Change-Id: Ic060fa9515eb88d95dbe16712479dae9dffcf626
diff --git a/cmd/multiproduct_kati/main.go b/cmd/multiproduct_kati/main.go
index 0570c17..2ff19ce 100644
--- a/cmd/multiproduct_kati/main.go
+++ b/cmd/multiproduct_kati/main.go
@@ -28,6 +28,7 @@
 
 	"android/soong/ui/build"
 	"android/soong/ui/logger"
+	"android/soong/ui/tracer"
 )
 
 // We default to number of cpus / 4, which seems to be the sweet spot for my
@@ -64,13 +65,20 @@
 	ctx, cancel := context.WithCancel(context.Background())
 	defer cancel()
 
-	build.SetupSignals(log, cancel, log.Cleanup)
+	trace := tracer.New(log)
+	defer trace.Close()
 
-	buildCtx := &build.ContextImpl{
+	build.SetupSignals(log, cancel, func() {
+		trace.Close()
+		log.Cleanup()
+	})
+
+	buildCtx := build.Context{&build.ContextImpl{
 		Context:        ctx,
 		Logger:         log,
+		Tracer:         trace,
 		StdioInterface: build.StdioImpl{},
-	}
+	}}
 
 	failed := false
 
@@ -95,6 +103,7 @@
 
 	build.SetupOutDir(buildCtx, config)
 	log.SetOutput(filepath.Join(config.OutDir(), "build.log"))
+	trace.SetOutput(filepath.Join(config.OutDir(), "build.trace"))
 
 	vars, err := build.DumpMakeVars(buildCtx, config, nil, nil, []string{"all_named_products"})
 	if err != nil {
@@ -130,11 +139,13 @@
 			productLog := logger.New(&bytes.Buffer{})
 			productLog.SetOutput(filepath.Join(productOutDir, "build.log"))
 
-			productCtx := &build.ContextImpl{
+			productCtx := build.Context{&build.ContextImpl{
 				Context:        ctx,
 				Logger:         productLog,
+				Tracer:         trace,
 				StdioInterface: build.NewCustomStdio(nil, f, f),
-			}
+				Thread:         trace.NewThread(product),
+			}}
 
 			productConfig := build.NewConfig(productCtx)
 			productConfig.Environment().Set("OUT_DIR", productOutDir)