Support filegroups

filegroup is a module that contains a list of files, and can be used
to export files across package boundaries.  filegroups (and genrules)
can be referenced from srcs properties of other modules using the
syntax ":module".

Test: m -j
Change-Id: I3d6fc4819c0b4225b474e0ad42f0d947f55a5961
diff --git a/android/module.go b/android/module.go
index c0b9c47..7156e8c 100644
--- a/android/module.go
+++ b/android/module.go
@@ -711,6 +711,38 @@
 	return -1
 }
 
+func SrcIsModule(s string) string {
+	if len(s) > 1 && s[0] == ':' {
+		return s[1:]
+	}
+	return ""
+}
+
+type sourceDependencyTag struct {
+	blueprint.BaseDependencyTag
+}
+
+var SourceDepTag sourceDependencyTag
+
+// Returns a list of modules that must be depended on to satisfy filegroup or generated sources
+// modules listed in srcFiles using ":module" syntax
+func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) {
+	var deps []string
+	for _, s := range srcFiles {
+		if m := SrcIsModule(s); m != "" {
+			deps = append(deps, m)
+		}
+	}
+
+	ctx.AddDependency(ctx.Module(), SourceDepTag, deps...)
+}
+
+type SourceFileProducer interface {
+	Srcs() Paths
+}
+
+// Returns a list of paths expanded from globs and modules referenced using ":module" syntax.
+// ExpandSourceDeps must have already been called during the dependency resolution phase.
 func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
 	prefix := PathForModuleSrc(ctx).String()
 	for i, e := range excludes {
@@ -724,7 +756,14 @@
 
 	globbedSrcFiles := make(Paths, 0, len(srcFiles))
 	for _, s := range srcFiles {
-		if pathtools.IsGlob(s) {
+		if m := SrcIsModule(s); m != "" {
+			module := ctx.GetDirectDepWithTag(m, SourceDepTag)
+			if srcProducer, ok := module.(SourceFileProducer); ok {
+				globbedSrcFiles = append(globbedSrcFiles, srcProducer.Srcs()...)
+			} else {
+				ctx.ModuleErrorf("srcs dependency %q is not a source file producing module", m)
+			}
+		} else if pathtools.IsGlob(s) {
 			globbedSrcFiles = append(globbedSrcFiles, ctx.Glob(filepath.Join(prefix, s), excludes)...)
 		} else {
 			globbedSrcFiles = append(globbedSrcFiles, PathForModuleSrc(ctx, s))