Merge changes I3648c914,I47dec958,Ia20f8198

* changes:
  Allow strip.sh --keep-mini-debug-info to work on non-elf files
  Fix strip.sh --keep-mini-debug-info
  Remove relocation packer
diff --git a/android/variable.go b/android/variable.go
index b4ed1b7..b478389 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -43,8 +43,8 @@
 		} `android:"arch_variant"`
 
 		Malloc_not_svelte struct {
-			Cflags []string
-		}
+			Cflags []string `android:"arch_variant"`
+		} `android:"arch_variant"`
 
 		Safestack struct {
 			Cflags []string `android:"arch_variant"`
diff --git a/cmd/multiproduct_kati/main.go b/cmd/multiproduct_kati/main.go
index 813c060..374868c 100644
--- a/cmd/multiproduct_kati/main.go
+++ b/cmd/multiproduct_kati/main.go
@@ -18,6 +18,7 @@
 	"context"
 	"flag"
 	"fmt"
+	"io"
 	"io/ioutil"
 	"os"
 	"path/filepath"
@@ -27,6 +28,7 @@
 	"syscall"
 	"time"
 
+	"android/soong/finder"
 	"android/soong/ui/build"
 	"android/soong/ui/logger"
 	"android/soong/ui/status"
@@ -49,6 +51,7 @@
 var numJobs = flag.Int("j", detectNumJobs(), "number of parallel kati jobs")
 
 var keepArtifacts = flag.Bool("keep", false, "keep archives of artifacts")
+var incremental = flag.Bool("incremental", false, "run in incremental mode (saving intermediates)")
 
 var outDir = flag.String("out", "", "path to store output directories (defaults to tmpdir under $OUT when empty)")
 var alternateResultDir = flag.Bool("dist", false, "write select results to $DIST_DIR (or <out>/dist when empty)")
@@ -64,13 +67,6 @@
 const errorLeadingLines = 20
 const errorTrailingLines = 20
 
-type Product struct {
-	ctx     build.Context
-	config  build.Config
-	logFile string
-	action  *status.Action
-}
-
 func errMsgFromLog(filename string) string {
 	if filename == "" {
 		return ""
@@ -131,6 +127,34 @@
 	return false
 }
 
+func copyFile(from, to string) error {
+	fromFile, err := os.Open(from)
+	if err != nil {
+		return err
+	}
+	defer fromFile.Close()
+
+	toFile, err := os.Create(to)
+	if err != nil {
+		return err
+	}
+	defer toFile.Close()
+
+	_, err = io.Copy(toFile, fromFile)
+	return err
+}
+
+type mpContext struct {
+	Context context.Context
+	Logger  logger.Logger
+	Status  status.ToolStatus
+	Tracer  tracer.Tracer
+	Finder  *finder.Finder
+	Config  build.Config
+
+	LogsDir string
+}
+
 func main() {
 	writer := terminal.NewWriter(terminal.StdioImpl{})
 	defer writer.Finish()
@@ -169,7 +193,10 @@
 
 	config := build.NewConfig(buildCtx)
 	if *outDir == "" {
-		name := "multiproduct-" + time.Now().Format("20060102150405")
+		name := "multiproduct"
+		if !*incremental {
+			name += "-" + time.Now().Format("20060102150405")
+		}
 
 		*outDir = filepath.Join(config.OutDir(), name)
 
@@ -231,7 +258,7 @@
 		productsList = allProducts
 	}
 
-	products := make([]string, 0, len(productsList))
+	finalProductsList := make([]string, 0, len(productsList))
 	skipList := strings.Split(*skipProducts, ",")
 	skipProduct := func(p string) bool {
 		for _, s := range skipList {
@@ -243,136 +270,54 @@
 	}
 	for _, product := range productsList {
 		if !skipProduct(product) {
-			products = append(products, product)
+			finalProductsList = append(finalProductsList, product)
 		} else {
 			log.Verbose("Skipping: ", product)
 		}
 	}
 
-	log.Verbose("Got product list: ", products)
+	log.Verbose("Got product list: ", finalProductsList)
 
 	s := buildCtx.Status.StartTool()
-	s.SetTotalActions(len(products))
+	s.SetTotalActions(len(finalProductsList))
 
-	var wg sync.WaitGroup
-	productConfigs := make(chan Product, len(products))
+	mpCtx := &mpContext{
+		Context: ctx,
+		Logger:  log,
+		Status:  s,
+		Tracer:  trace,
 
-	// Run the product config for every product in parallel
-	for _, product := range products {
-		wg.Add(1)
-		go func(product string) {
-			var stdLog string
+		Finder: finder,
+		Config: config,
 
-			defer wg.Done()
-
-			action := &status.Action{
-				Description: product,
-				Outputs:     []string{product},
-			}
-			s.StartAction(action)
-			defer logger.Recover(func(err error) {
-				s.FinishAction(status.ActionResult{
-					Action: action,
-					Error:  err,
-					Output: errMsgFromLog(stdLog),
-				})
-			})
-
-			productOutDir := filepath.Join(config.OutDir(), product)
-			productLogDir := filepath.Join(logsDir, product)
-
-			if err := os.MkdirAll(productOutDir, 0777); err != nil {
-				log.Fatalf("Error creating out directory: %v", err)
-			}
-			if err := os.MkdirAll(productLogDir, 0777); err != nil {
-				log.Fatalf("Error creating log directory: %v", err)
-			}
-
-			stdLog = filepath.Join(productLogDir, "std.log")
-			f, err := os.Create(stdLog)
-			if err != nil {
-				log.Fatalf("Error creating std.log: %v", err)
-			}
-
-			productLog := logger.New(f)
-			productLog.SetOutput(filepath.Join(productLogDir, "soong.log"))
-
-			productCtx := build.Context{ContextImpl: &build.ContextImpl{
-				Context: ctx,
-				Logger:  productLog,
-				Tracer:  trace,
-				Writer:  terminal.NewWriter(terminal.NewCustomStdio(nil, f, f)),
-				Thread:  trace.NewThread(product),
-				Status:  &status.Status{},
-			}}
-			productCtx.Status.AddOutput(terminal.NewStatusOutput(productCtx.Writer, ""))
-
-			productConfig := build.NewConfig(productCtx, flag.Args()...)
-			productConfig.Environment().Set("OUT_DIR", productOutDir)
-			build.FindSources(productCtx, productConfig, finder)
-			productConfig.Lunch(productCtx, product, *buildVariant)
-
-			build.Build(productCtx, productConfig, build.BuildProductConfig)
-			productConfigs <- Product{productCtx, productConfig, stdLog, action}
-		}(product)
+		LogsDir: logsDir,
 	}
+
+	products := make(chan string, len(productsList))
 	go func() {
-		defer close(productConfigs)
-		wg.Wait()
+		defer close(products)
+		for _, product := range finalProductsList {
+			products <- product
+		}
 	}()
 
-	var wg2 sync.WaitGroup
-	// Then run up to numJobs worth of Soong and Kati
+	var wg sync.WaitGroup
 	for i := 0; i < *numJobs; i++ {
-		wg2.Add(1)
+		wg.Add(1)
 		go func() {
-			defer wg2.Done()
-			for product := range productConfigs {
-				func() {
-					defer logger.Recover(func(err error) {
-						s.FinishAction(status.ActionResult{
-							Action: product.action,
-							Error:  err,
-							Output: errMsgFromLog(product.logFile),
-						})
-					})
-
-					defer func() {
-						if *keepArtifacts {
-							args := zip.ZipArgs{
-								FileArgs: []zip.FileArg{
-									{
-										GlobDir:             product.config.OutDir(),
-										SourcePrefixToStrip: product.config.OutDir(),
-									},
-								},
-								OutputFilePath:   filepath.Join(config.OutDir(), product.config.TargetProduct()+".zip"),
-								NumParallelJobs:  runtime.NumCPU(),
-								CompressionLevel: 5,
-							}
-							if err := zip.Run(args); err != nil {
-								log.Fatalf("Error zipping artifacts: %v", err)
-							}
-						}
-						os.RemoveAll(product.config.OutDir())
-					}()
-
-					buildWhat := 0
-					if !*onlyConfig {
-						buildWhat |= build.BuildSoong
-						if !*onlySoong {
-							buildWhat |= build.BuildKati
-						}
+			defer wg.Done()
+			for {
+				select {
+				case product := <-products:
+					if product == "" {
+						return
 					}
-					build.Build(product.ctx, product.config, buildWhat)
-					s.FinishAction(status.ActionResult{
-						Action: product.action,
-					})
-				}()
+					buildProduct(mpCtx, product)
+				}
 			}
 		}()
 	}
-	wg2.Wait()
+	wg.Wait()
 
 	if *alternateResultDir {
 		args := zip.ZipArgs{
@@ -399,6 +344,111 @@
 	}
 }
 
+func buildProduct(mpctx *mpContext, product string) {
+	var stdLog string
+
+	outDir := filepath.Join(mpctx.Config.OutDir(), product)
+	logsDir := filepath.Join(mpctx.LogsDir, product)
+
+	if err := os.MkdirAll(outDir, 0777); err != nil {
+		mpctx.Logger.Fatalf("Error creating out directory: %v", err)
+	}
+	if err := os.MkdirAll(logsDir, 0777); err != nil {
+		mpctx.Logger.Fatalf("Error creating log directory: %v", err)
+	}
+
+	stdLog = filepath.Join(logsDir, "std.log")
+	f, err := os.Create(stdLog)
+	if err != nil {
+		mpctx.Logger.Fatalf("Error creating std.log: %v", err)
+	}
+	defer f.Close()
+
+	log := logger.New(f)
+	defer log.Cleanup()
+	log.SetOutput(filepath.Join(logsDir, "soong.log"))
+
+	action := &status.Action{
+		Description: product,
+		Outputs:     []string{product},
+	}
+	mpctx.Status.StartAction(action)
+	defer logger.Recover(func(err error) {
+		mpctx.Status.FinishAction(status.ActionResult{
+			Action: action,
+			Error:  err,
+			Output: errMsgFromLog(stdLog),
+		})
+	})
+
+	ctx := build.Context{ContextImpl: &build.ContextImpl{
+		Context: mpctx.Context,
+		Logger:  log,
+		Tracer:  mpctx.Tracer,
+		Writer:  terminal.NewWriter(terminal.NewCustomStdio(nil, f, f)),
+		Thread:  mpctx.Tracer.NewThread(product),
+		Status:  &status.Status{},
+	}}
+	ctx.Status.AddOutput(terminal.NewStatusOutput(ctx.Writer, ""))
+
+	config := build.NewConfig(ctx, flag.Args()...)
+	config.Environment().Set("OUT_DIR", outDir)
+	build.FindSources(ctx, config, mpctx.Finder)
+	config.Lunch(ctx, product, *buildVariant)
+
+	defer func() {
+		if *keepArtifacts {
+			args := zip.ZipArgs{
+				FileArgs: []zip.FileArg{
+					{
+						GlobDir:             outDir,
+						SourcePrefixToStrip: outDir,
+					},
+				},
+				OutputFilePath:   filepath.Join(mpctx.Config.OutDir(), product+".zip"),
+				NumParallelJobs:  runtime.NumCPU(),
+				CompressionLevel: 5,
+			}
+			if err := zip.Run(args); err != nil {
+				log.Fatalf("Error zipping artifacts: %v", err)
+			}
+		}
+		if *incremental {
+			// Save space, Kati doesn't notice
+			if f := config.KatiNinjaFile(); f != "" {
+				os.Truncate(f, 0)
+			}
+		} else {
+			os.RemoveAll(outDir)
+		}
+	}()
+
+	buildWhat := build.BuildProductConfig
+	if !*onlyConfig {
+		buildWhat |= build.BuildSoong
+		if !*onlySoong {
+			buildWhat |= build.BuildKati
+		}
+	}
+
+	before := time.Now()
+	build.Build(ctx, config, buildWhat)
+
+	// Save std_full.log if Kati re-read the makefiles
+	if buildWhat&build.BuildKati != 0 {
+		if after, err := os.Stat(config.KatiNinjaFile()); err == nil && after.ModTime().After(before) {
+			err := copyFile(stdLog, filepath.Join(filepath.Dir(stdLog), "std_full.log"))
+			if err != nil {
+				log.Fatalf("Error copying log file: %s", err)
+			}
+		}
+	}
+
+	mpctx.Status.FinishAction(status.ActionResult{
+		Action: action,
+	})
+}
+
 type failureCount int
 
 func (f *failureCount) StartAction(action *status.Action, counts status.Counts) {}
diff --git a/java/androidmk.go b/java/androidmk.go
index 877d840..bd88a1d 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -70,7 +70,7 @@
 				// Temporary hack: export sources used to compile framework.jar to Make
 				// to be used for droiddoc
 				// TODO(ccross): remove this once droiddoc is in soong
-				if library.Name() == "framework" {
+				if (library.Name() == "framework") || (library.Name() == "framework-annotation-proc") {
 					fmt.Fprintln(w, "SOONG_FRAMEWORK_SRCS :=", strings.Join(library.compiledJavaSrcs.Strings(), " "))
 					fmt.Fprintln(w, "SOONG_FRAMEWORK_SRCJARS :=", strings.Join(library.compiledSrcJars.Strings(), " "))
 				}
diff --git a/java/java.go b/java/java.go
index f6c9484..6c664d8 100644
--- a/java/java.go
+++ b/java/java.go
@@ -575,7 +575,7 @@
 		} else if *j.deviceProperties.System_modules != "none" && ctx.Config().TargetOpenJDK9() {
 			ctx.AddVariationDependencies(nil, systemModulesTag, *j.deviceProperties.System_modules)
 		}
-		if ctx.ModuleName() == "framework" {
+		if (ctx.ModuleName() == "framework") || (ctx.ModuleName() == "framework-annotation-proc") {
 			ctx.AddVariationDependencies(nil, frameworkResTag, "framework-res")
 		}
 		if ctx.ModuleName() == "android_stubs_current" ||
@@ -804,7 +804,7 @@
 			case annoTag:
 				deps.processorPath = append(deps.processorPath, dep.ImplementationAndResourcesJars()...)
 			case frameworkResTag:
-				if ctx.ModuleName() == "framework" {
+				if (ctx.ModuleName() == "framework") || (ctx.ModuleName() == "framework-annotation-proc") {
 					// framework.jar has a one-off dependency on the R.java and Manifest.java files
 					// generated by framework-res.apk
 					deps.srcJars = append(deps.srcJars, dep.(*AndroidApp).aaptSrcJar)
diff --git a/ui/build/config.go b/ui/build/config.go
index 2605f5b..fdeb8f2 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -369,14 +369,14 @@
 
 func (c *configImpl) OutDir() string {
 	if outDir, ok := c.environ.Get("OUT_DIR"); ok {
-		return outDir
+		return filepath.Clean(outDir)
 	}
 	return "out"
 }
 
 func (c *configImpl) DistDir() string {
 	if distDir, ok := c.environ.Get("DIST_DIR"); ok {
-		return distDir
+		return filepath.Clean(distDir)
 	}
 	return filepath.Join(c.OutDir(), "dist")
 }
diff --git a/ui/build/kati.go b/ui/build/kati.go
index b54872c..b26d673 100644
--- a/ui/build/kati.go
+++ b/ui/build/kati.go
@@ -81,6 +81,8 @@
 		"--warn_real_to_phony",
 		"--warn_phony_looks_real",
 		"--kati_stats",
+		"--writable", config.OutDir() + "/",
+		"--writable", config.DistDir() + "/",
 		"-f", "build/make/core/main.mk",
 	}
 
@@ -94,7 +96,10 @@
 	}
 
 	if !config.BuildBrokenPhonyTargets() {
-		args = append(args, "--werror_real_to_phony", "--werror_phony_looks_real")
+		args = append(args,
+			"--werror_real_to_phony",
+			"--werror_phony_looks_real",
+			"--werror_writable")
 	}
 
 	if !config.Environment().IsFalse("KATI_EMULATE_FIND") {