Add gensrcs module type

gensrcs allows sources to be generated by a specified command.

Change-Id: I725086fcdcd72bfe6c07fb8903e7b520678a247f
diff --git a/genrule/genrule.go b/genrule/genrule.go
new file mode 100644
index 0000000..6c8d75b
--- /dev/null
+++ b/genrule/genrule.go
@@ -0,0 +1,97 @@
+// Copyright 2015 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package genrule
+
+import (
+	"path/filepath"
+
+	"blueprint"
+	"blueprint/pathtools"
+
+	"android/soong/common"
+)
+
+type Config interface {
+	SrcDir() string
+}
+
+var (
+	pctx = blueprint.NewPackageContext("android/soong/genrule")
+)
+
+func init() {
+	pctx.VariableConfigMethod("srcDir", Config.SrcDir)
+}
+
+type SourceFileGenerator interface {
+	GeneratedSourceFiles() []string
+}
+
+type genSrcsProperties struct {
+	// cmd: command to run on each input file.  Available variables for substitution:
+	// $in: an input file
+	// $out: the corresponding output file
+	// $srcDir: the root directory of the source tree
+	Cmd string
+
+	// srcs: list of input files
+	Srcs []string
+
+	// output_extension: extension that will be substituted for each output file
+	Output_extension string
+}
+
+func NewGenSrcs() (blueprint.Module, []interface{}) {
+	module := &genSrcs{}
+
+	return common.InitAndroidModule(module, &module.properties)
+}
+
+type genSrcs struct {
+	common.AndroidModuleBase
+
+	properties  genSrcsProperties
+	outputFiles []string
+}
+
+func (g *genSrcs) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
+	rule := ctx.Rule(pctx, "genSrcs", blueprint.RuleParams{
+		Command: g.properties.Cmd,
+	})
+
+	srcFiles := g.properties.Srcs
+	srcFiles = pathtools.PrefixPaths(srcFiles, common.ModuleSrcDir(ctx))
+	srcFiles = common.ExpandGlobs(ctx, srcFiles)
+
+	g.outputFiles = make([]string, 0, len(srcFiles))
+
+	for _, in := range srcFiles {
+		out := pathtools.ReplaceExtension(in, g.properties.Output_extension)
+		out = filepath.Join(common.ModuleGenDir(ctx), out)
+		g.outputFiles = append(g.outputFiles, out)
+		ctx.Build(pctx, blueprint.BuildParams{
+			Rule:    rule,
+			Inputs:  []string{in},
+			Outputs: []string{out},
+			// TODO: visit dependencies to add implicit dependencies on required tools
+		})
+	}
+}
+
+var _ SourceFileGenerator = (*genSrcs)(nil)
+
+func (g *genSrcs) GeneratedSourceFiles() []string {
+	return g.outputFiles
+}