Merge changes from topic 'genrule-multi-out'

* changes:
  Remove shared lib name checks
  Add export_generated_headers
  Support multiple outputs for genrule
  Parse genrule's cmd property
  Expose HostToolPath on the cc module to fix genrule.tool
diff --git a/cc/binary.go b/cc/binary.go
index 6ad71c6..8afce09 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -69,7 +69,7 @@
 
 	Properties BinaryLinkerProperties
 
-	hostToolPath android.OptionalPath
+	toolPath android.OptionalPath
 }
 
 var _ linker = (*binaryDecorator)(nil)
@@ -256,9 +256,6 @@
 	fileName := binary.getStem(ctx) + flags.Toolchain.ExecutableSuffix()
 	outputFile := android.PathForModuleOut(ctx, fileName)
 	ret := outputFile
-	if ctx.Os().Class == android.Host {
-		binary.hostToolPath = android.OptionalPathForPath(outputFile)
-	}
 
 	var linkerDeps android.Paths
 
@@ -291,6 +288,13 @@
 	return ret
 }
 
-func (binary *binaryDecorator) HostToolPath() android.OptionalPath {
-	return binary.hostToolPath
+func (binary *binaryDecorator) install(ctx ModuleContext, file android.Path) {
+	binary.baseInstaller.install(ctx, file)
+	if ctx.Os().Class == android.Host {
+		binary.toolPath = android.OptionalPathForPath(binary.baseInstaller.path)
+	}
+}
+
+func (binary *binaryDecorator) hostToolPath() android.OptionalPath {
+	return binary.toolPath
 }
diff --git a/cc/builder.go b/cc/builder.go
index a84ba08..42a7f48 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -377,13 +377,6 @@
 	}
 
 	for _, lib := range sharedLibs {
-		file := filepath.Base(lib.String())
-		if !strings.HasPrefix(file, "lib") {
-			panic("shared library " + lib.String() + " does not start with lib")
-		}
-		if !strings.HasSuffix(file, flags.toolchain.ShlibSuffix()) {
-			panic("shared library " + lib.String() + " does not end with " + flags.toolchain.ShlibSuffix())
-		}
 		libFlagsList = append(libFlagsList, lib.String())
 	}
 
diff --git a/cc/cc.go b/cc/cc.go
index 5b4dfc6..66c47c1 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -64,6 +64,8 @@
 	GeneratedSources []string
 	GeneratedHeaders []string
 
+	ReexportGeneratedHeaders []string
+
 	CrtBegin, CrtEnd string
 }
 
@@ -181,6 +183,7 @@
 	installerProps() []interface{}
 	install(ctx ModuleContext, path android.Path)
 	inData() bool
+	hostToolPath() android.OptionalPath
 }
 
 type dependencyTag struct {
@@ -192,21 +195,22 @@
 }
 
 var (
-	sharedDepTag       = dependencyTag{name: "shared", library: true}
-	sharedExportDepTag = dependencyTag{name: "shared", library: true, reexportFlags: true}
-	lateSharedDepTag   = dependencyTag{name: "late shared", library: true}
-	staticDepTag       = dependencyTag{name: "static", library: true}
-	staticExportDepTag = dependencyTag{name: "static", library: true, reexportFlags: true}
-	lateStaticDepTag   = dependencyTag{name: "late static", library: true}
-	wholeStaticDepTag  = dependencyTag{name: "whole static", library: true, reexportFlags: true}
-	genSourceDepTag    = dependencyTag{name: "gen source"}
-	genHeaderDepTag    = dependencyTag{name: "gen header"}
-	objDepTag          = dependencyTag{name: "obj"}
-	crtBeginDepTag     = dependencyTag{name: "crtbegin"}
-	crtEndDepTag       = dependencyTag{name: "crtend"}
-	reuseObjTag        = dependencyTag{name: "reuse objects"}
-	ndkStubDepTag      = dependencyTag{name: "ndk stub", library: true}
-	ndkLateStubDepTag  = dependencyTag{name: "ndk late stub", library: true}
+	sharedDepTag          = dependencyTag{name: "shared", library: true}
+	sharedExportDepTag    = dependencyTag{name: "shared", library: true, reexportFlags: true}
+	lateSharedDepTag      = dependencyTag{name: "late shared", library: true}
+	staticDepTag          = dependencyTag{name: "static", library: true}
+	staticExportDepTag    = dependencyTag{name: "static", library: true, reexportFlags: true}
+	lateStaticDepTag      = dependencyTag{name: "late static", library: true}
+	wholeStaticDepTag     = dependencyTag{name: "whole static", library: true, reexportFlags: true}
+	genSourceDepTag       = dependencyTag{name: "gen source"}
+	genHeaderDepTag       = dependencyTag{name: "gen header"}
+	genHeaderExportDepTag = dependencyTag{name: "gen header", reexportFlags: true}
+	objDepTag             = dependencyTag{name: "obj"}
+	crtBeginDepTag        = dependencyTag{name: "crtbegin"}
+	crtEndDepTag          = dependencyTag{name: "crtend"}
+	reuseObjTag           = dependencyTag{name: "reuse objects"}
+	ndkStubDepTag         = dependencyTag{name: "ndk stub", library: true}
+	ndkLateStubDepTag     = dependencyTag{name: "ndk late stub", library: true}
 )
 
 // Module contains the properties and members used by all C/C++ module types, and implements
@@ -502,6 +506,12 @@
 		}
 	}
 
+	for _, gen := range deps.ReexportGeneratedHeaders {
+		if !inList(gen, deps.GeneratedHeaders) {
+			ctx.PropertyErrorf("export_generated_headers", "Generated header module not in generated_headers: '%s'", gen)
+		}
+	}
+
 	return deps
 }
 
@@ -593,7 +603,14 @@
 		deps.LateSharedLibs...)
 
 	actx.AddDependency(c, genSourceDepTag, deps.GeneratedSources...)
-	actx.AddDependency(c, genHeaderDepTag, deps.GeneratedHeaders...)
+
+	for _, gen := range deps.GeneratedHeaders {
+		depTag := genHeaderDepTag
+		if inList(gen, deps.ReexportGeneratedHeaders) {
+			depTag = genHeaderExportDepTag
+		}
+		actx.AddDependency(c, depTag, gen)
+	}
 
 	actx.AddDependency(c, objDepTag, deps.ObjFiles...)
 
@@ -735,12 +752,15 @@
 				} else {
 					ctx.ModuleErrorf("module %q is not a gensrcs or genrule", name)
 				}
-			case genHeaderDepTag:
+			case genHeaderDepTag, genHeaderExportDepTag:
 				if genRule, ok := m.(genrule.SourceFileGenerator); ok {
 					depPaths.GeneratedHeaders = append(depPaths.GeneratedHeaders,
 						genRule.GeneratedSourceFiles()...)
-					depPaths.Flags = append(depPaths.Flags,
-						includeDirsToFlags(android.Paths{genRule.GeneratedHeaderDir()}))
+					flags := includeDirsToFlags(android.Paths{genRule.GeneratedHeaderDir()})
+					depPaths.Flags = append(depPaths.Flags, flags)
+					if tag == genHeaderExportDepTag {
+						depPaths.ReexportedFlags = append(depPaths.ReexportedFlags, flags)
+					}
 				} else {
 					ctx.ModuleErrorf("module %q is not a genrule", name)
 				}
@@ -845,6 +865,13 @@
 	return c.installer.inData()
 }
 
+func (c *Module) HostToolPath() android.OptionalPath {
+	if c.installer == nil {
+		return android.OptionalPath{}
+	}
+	return c.installer.hostToolPath()
+}
+
 //
 // Defaults
 //
diff --git a/cc/installer.go b/cc/installer.go
index fa8fc32..8ce9541 100644
--- a/cc/installer.go
+++ b/cc/installer.go
@@ -80,3 +80,7 @@
 func (installer *baseInstaller) inData() bool {
 	return installer.location == InstallInData
 }
+
+func (installer *baseInstaller) hostToolPath() android.OptionalPath {
+	return android.OptionalPath{}
+}
diff --git a/cc/linker.go b/cc/linker.go
index 4ee38dc..2c4c250 100644
--- a/cc/linker.go
+++ b/cc/linker.go
@@ -67,6 +67,10 @@
 	// present in static_libs.
 	Export_static_lib_headers []string `android:"arch_variant"`
 
+	// list of generated headers to re-export include directories from. Entries must be
+	// present in generated_headers.
+	Export_generated_headers []string `android:"arch_variant"`
+
 	// don't link in crt_begin and crt_end.  This flag should only be necessary for
 	// compiling crt or libc.
 	Nocrt *bool `android:"arch_variant"`
@@ -107,6 +111,7 @@
 
 	deps.ReexportStaticLibHeaders = append(deps.ReexportStaticLibHeaders, linker.Properties.Export_static_lib_headers...)
 	deps.ReexportSharedLibHeaders = append(deps.ReexportSharedLibHeaders, linker.Properties.Export_shared_lib_headers...)
+	deps.ReexportGeneratedHeaders = append(deps.ReexportGeneratedHeaders, linker.Properties.Export_generated_headers...)
 
 	if ctx.ModuleName() != "libcompiler_rt-extras" {
 		deps.LateStaticLibs = append(deps.LateStaticLibs, "libcompiler_rt-extras")
diff --git a/genrule/genrule.go b/genrule/genrule.go
index ecc5ab8..4a9b336 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -15,6 +15,8 @@
 package genrule
 
 import (
+	"os"
+
 	"github.com/google/blueprint"
 
 	"android/soong"
@@ -52,6 +54,7 @@
 	// $in: one or more input files
 	// $out: a single output file
 	// $srcDir: the root directory of the source tree
+	// $genDir: the sandbox directory for this tool; contains $out
 	// The host bin directory will be in the path
 	Cmd string
 
@@ -82,7 +85,7 @@
 
 type generateTask struct {
 	in  android.Paths
-	out android.ModuleGenPath
+	out android.WritablePaths
 }
 
 func (g *generator) GeneratedSourceFiles() android.Paths {
@@ -109,8 +112,30 @@
 		return
 	}
 
+	g.genPath = android.PathForModuleGen(ctx, "")
+
+	cmd := os.Expand(g.properties.Cmd, func(name string) string {
+		switch name {
+		case "$":
+			return "$$"
+		case "tool":
+			return "${tool}"
+		case "in":
+			return "${in}"
+		case "out":
+			return "${out}"
+		case "srcDir":
+			return "${srcDir}"
+		case "genDir":
+			return g.genPath.String()
+		default:
+			ctx.PropertyErrorf("cmd", "unknown variable '%s'", name)
+		}
+		return ""
+	})
+
 	g.rule = ctx.Rule(pctx, "generator", blueprint.RuleParams{
-		Command: "PATH=$$PATH:$hostBin " + g.properties.Cmd,
+		Command: "PATH=$$PATH:$hostBin " + cmd,
 	}, "tool")
 
 	var tool string
@@ -134,8 +159,6 @@
 		})
 	}
 
-	g.genPath = android.PathForModuleGen(ctx, "")
-
 	for _, task := range g.tasks(ctx) {
 		g.generateSourceFile(ctx, task, tool)
 	}
@@ -144,7 +167,7 @@
 func (g *generator) generateSourceFile(ctx android.ModuleContext, task generateTask, tool string) {
 	ctx.ModuleBuild(pctx, android.ModuleBuildParams{
 		Rule:      g.rule,
-		Output:    task.out,
+		Outputs:   task.out,
 		Inputs:    task.in,
 		Implicits: g.deps,
 		Args: map[string]string{
@@ -152,7 +175,9 @@
 		},
 	})
 
-	g.outputFiles = append(g.outputFiles, task.out)
+	for _, outputFile := range task.out {
+		g.outputFiles = append(g.outputFiles, outputFile)
+	}
 }
 
 func generatorFactory(tasks taskFunc, props ...interface{}) (blueprint.Module, []interface{}) {
@@ -174,7 +199,7 @@
 		for _, in := range srcFiles {
 			tasks = append(tasks, generateTask{
 				in:  android.Paths{in},
-				out: android.GenPathWithExt(ctx, in, properties.Output_extension),
+				out: android.WritablePaths{android.GenPathWithExt(ctx, in, properties.Output_extension)},
 			})
 		}
 		return tasks
@@ -195,10 +220,14 @@
 	properties := &genRuleProperties{}
 
 	tasks := func(ctx android.ModuleContext) []generateTask {
+		outs := make(android.WritablePaths, len(properties.Out))
+		for i, out := range properties.Out {
+			outs[i] = android.PathForModuleGen(ctx, out)
+		}
 		return []generateTask{
 			{
 				in:  ctx.ExpandSources(properties.Srcs, nil),
-				out: android.PathForModuleGen(ctx, properties.Out),
+				out: outs,
 			},
 		}
 	}
@@ -210,6 +239,6 @@
 	// list of input files
 	Srcs []string
 
-	// name of the output file that will be generated
-	Out string
+	// names of the output files that will be generated
+	Out []string
 }