Create 'androidmk' rule to automatically run androidbp

This finds any Android.bp files with Android modules defined, and if
there isn't an Android.mk file in the same directory, it will run
androidbp to generate one in $OUT

Change-Id: Ie8aef492e8cd28f6c314ce1254730975a1b8991f
diff --git a/common/defs.go b/common/defs.go
index 67b93ff..98464fe 100644
--- a/common/defs.go
+++ b/common/defs.go
@@ -15,7 +15,10 @@
 package common
 
 import (
+	"path/filepath"
+
 	"github.com/google/blueprint"
+	"github.com/google/blueprint/bootstrap"
 )
 
 var (
@@ -24,6 +27,13 @@
 	cpPreserveSymlinks = pctx.VariableConfigMethod("cpPreserveSymlinks",
 		Config.CpPreserveSymlinksFlags)
 
+	androidbpCmd = filepath.Join(bootstrap.BinDir, "androidbp")
+	androidbp    = pctx.StaticRule("androidbp",
+		blueprint.RuleParams{
+			Command:     androidbpCmd + " $in $out",
+			Description: "androidbp $out",
+		})
+
 	// A phony rule that is not the built-in Ninja phony rule.  The built-in
 	// phony rule has special behavior that is sometimes not desired.  See the
 	// Ninja docs for more details.
diff --git a/common/module.go b/common/module.go
index 33c586c..bf3c435 100644
--- a/common/module.go
+++ b/common/module.go
@@ -17,6 +17,8 @@
 import (
 	"path/filepath"
 	"runtime"
+	"sort"
+	"strings"
 
 	"android/soong/glob"
 
@@ -523,12 +525,15 @@
 	checkbuildDeps := []string{}
 
 	dirModules := make(map[string][]string)
+	hasBPFile := make(map[string]bool)
+	bpFiles := []string{}
 
 	ctx.VisitAllModules(func(module blueprint.Module) {
 		if a, ok := module.(AndroidModule); ok {
 			blueprintDir := a.base().blueprintDir
 			installTarget := a.base().installTarget
 			checkbuildTarget := a.base().checkbuildTarget
+			bpFile := ctx.BlueprintFile(module)
 
 			if checkbuildTarget != "" {
 				checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
@@ -538,6 +543,11 @@
 			if installTarget != "" {
 				dirModules[blueprintDir] = append(dirModules[blueprintDir], installTarget)
 			}
+
+			if !hasBPFile[bpFile] {
+				hasBPFile[bpFile] = true
+				bpFiles = append(bpFiles, bpFile)
+			}
 		}
 	})
 
@@ -560,4 +570,43 @@
 			Optional:  true,
 		})
 	}
+
+	// Create Android.bp->mk translation rules
+	androidMks := []string{}
+	srcDir := ctx.Config().(Config).SrcDir()
+	intermediatesDir := filepath.Join(ctx.Config().(Config).IntermediatesDir(), "androidmk")
+	sort.Strings(bpFiles)
+	for _, origBp := range bpFiles {
+		bpFile := filepath.Join(srcDir, origBp)
+		mkFile := filepath.Join(srcDir, filepath.Dir(origBp), "Android.mk")
+
+		files, err := Glob(ctx, intermediatesDir, mkFile, nil)
+		if err != nil {
+			ctx.Errorf("glob: %s", err.Error())
+			continue
+		}
+
+		// Existing Android.mk file, use that instead
+		if len(files) > 0 {
+			continue
+		}
+
+		transMk := filepath.Join("androidmk", "Android_"+strings.Replace(filepath.Dir(origBp), "/", "_", -1)+".mk")
+		ctx.Build(pctx, blueprint.BuildParams{
+			Rule:      androidbp,
+			Outputs:   []string{transMk},
+			Inputs:    []string{bpFile},
+			Implicits: []string{androidbpCmd},
+			Optional:  true,
+		})
+
+		androidMks = append(androidMks, transMk)
+	}
+
+	ctx.Build(pctx, blueprint.BuildParams{
+		Rule:      blueprint.Phony,
+		Outputs:   []string{"androidmk"},
+		Implicits: androidMks,
+		Optional:  true,
+	})
 }