Specify module dependency in the srcs list

* "srcs" list contains one main Rust source file,
  followed by optional dependent modules.
* A dependent module included in the "srcs" list is
  the module name prefixed with ":".
* Add a simple test.

Bug: 160331255
Test: make and manual test build dependencies on genrule modules
Change-Id: I4f079138c2599158810b6412fce81b612a3f64a4
diff --git a/rust/binary.go b/rust/binary.go
index a1cd410..9fc52cd 100644
--- a/rust/binary.go
+++ b/rust/binary.go
@@ -106,7 +106,8 @@
 func (binary *binaryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path {
 	fileName := binary.getStem(ctx) + ctx.toolchain().ExecutableSuffix()
 
-	srcPath := srcPathFromModuleSrcs(ctx, binary.baseCompiler.Properties.Srcs)
+	srcPath, paths := srcPathFromModuleSrcs(ctx, binary.baseCompiler.Properties.Srcs)
+	deps.SrcDeps = paths
 
 	outputFile := android.PathForModuleOut(ctx, fileName)
 	binary.unstrippedOutputFile = outputFile
diff --git a/rust/builder.go b/rust/builder.go
index 16d7306..7f94bb5 100644
--- a/rust/builder.go
+++ b/rust/builder.go
@@ -166,6 +166,7 @@
 	implicits = append(implicits, rustLibsToPaths(deps.ProcMacros)...)
 	implicits = append(implicits, deps.StaticLibs...)
 	implicits = append(implicits, deps.SharedLibs...)
+	implicits = append(implicits, deps.SrcDeps...)
 	if deps.CrtBegin.Valid() {
 		implicits = append(implicits, deps.CrtBegin.Path(), deps.CrtEnd.Path())
 	}
diff --git a/rust/compiler.go b/rust/compiler.go
index 92a3b07..c20179b 100644
--- a/rust/compiler.go
+++ b/rust/compiler.go
@@ -253,10 +253,24 @@
 	return String(compiler.Properties.Relative_install_path)
 }
 
-func srcPathFromModuleSrcs(ctx ModuleContext, srcs []string) android.Path {
-	srcPaths := android.PathsForModuleSrc(ctx, srcs)
-	if len(srcPaths) != 1 {
-		ctx.PropertyErrorf("srcs", "srcs can only contain one path for rust modules")
+func srcPathFromModuleSrcs(ctx ModuleContext, srcs []string) (android.Path, android.Paths) {
+	// The srcs can contain strings with prefix ":".
+	// They are dependent modules of this module, with android.SourceDepTag.
+	// They are not the main source file compiled by rustc.
+	numSrcs := 0
+	srcIndex := 0
+	for i, s := range srcs {
+		if android.SrcIsModule(s) == "" {
+			numSrcs++
+			srcIndex = i
+		}
 	}
-	return srcPaths[0]
+	if numSrcs != 1 {
+		ctx.PropertyErrorf("srcs", "srcs can only contain one path for a rust file")
+	}
+	if srcIndex != 0 {
+		ctx.PropertyErrorf("srcs", "main source file must be the first in srcs")
+	}
+	paths := android.PathsForModuleSrc(ctx, srcs)
+	return paths[srcIndex], paths
 }
diff --git a/rust/compiler_test.go b/rust/compiler_test.go
index bcde757..58ca52a 100644
--- a/rust/compiler_test.go
+++ b/rust/compiler_test.go
@@ -43,7 +43,7 @@
 // Test that we reject multiple source files.
 func TestEnforceSingleSourceFile(t *testing.T) {
 
-	singleSrcError := "srcs can only contain one path for rust modules"
+	singleSrcError := "srcs can only contain one path for a rust file"
 
 	// Test libraries
 	testRustError(t, singleSrcError, `
diff --git a/rust/library.go b/rust/library.go
index 8b8e797..d718eb8 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -368,7 +368,8 @@
 func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path {
 	var outputFile android.WritablePath
 
-	srcPath := srcPathFromModuleSrcs(ctx, library.baseCompiler.Properties.Srcs)
+	srcPath, paths := srcPathFromModuleSrcs(ctx, library.baseCompiler.Properties.Srcs)
+	deps.SrcDeps = paths
 
 	flags.RustFlags = append(flags.RustFlags, deps.depFlags...)
 
diff --git a/rust/prebuilt.go b/rust/prebuilt.go
index 67d649d..3b4f40a 100644
--- a/rust/prebuilt.go
+++ b/rust/prebuilt.go
@@ -95,7 +95,8 @@
 func (prebuilt *prebuiltLibraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path {
 	prebuilt.exportLinkDirs(android.PathsForModuleSrc(ctx, prebuilt.Properties.Link_dirs).Strings()...)
 
-	srcPath := srcPathFromModuleSrcs(ctx, prebuilt.prebuiltSrcs())
+	srcPath, paths := srcPathFromModuleSrcs(ctx, prebuilt.prebuiltSrcs())
+	deps.SrcDeps = paths
 
 	prebuilt.unstrippedOutputFile = srcPath
 
diff --git a/rust/proc_macro.go b/rust/proc_macro.go
index 2719161..49dbd8d 100644
--- a/rust/proc_macro.go
+++ b/rust/proc_macro.go
@@ -65,7 +65,8 @@
 	fileName := procMacro.getStem(ctx) + ctx.toolchain().ProcMacroSuffix()
 	outputFile := android.PathForModuleOut(ctx, fileName)
 
-	srcPath := srcPathFromModuleSrcs(ctx, procMacro.baseCompiler.Properties.Srcs)
+	srcPath, paths := srcPathFromModuleSrcs(ctx, procMacro.baseCompiler.Properties.Srcs)
+	deps.SrcDeps = paths
 
 	procMacro.unstrippedOutputFile = outputFile
 
diff --git a/rust/rust.go b/rust/rust.go
index 72301a7..7a98c64 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -239,6 +239,9 @@
 
 	CrtBegin android.OptionalPath
 	CrtEnd   android.OptionalPath
+
+	// Paths to generated source files
+	SrcDeps android.Paths
 }
 
 type RustLibraries []RustLibrary
@@ -843,6 +846,7 @@
 	// Dedup exported flags from dependencies
 	depPaths.linkDirs = android.FirstUniqueStrings(depPaths.linkDirs)
 	depPaths.depFlags = android.FirstUniqueStrings(depPaths.depFlags)
+	depPaths.SrcDeps = android.FirstUniquePaths(depPaths.SrcDeps)
 
 	return depPaths
 }
diff --git a/rust/rust_test.go b/rust/rust_test.go
index 08bc8ca..e803925 100644
--- a/rust/rust_test.go
+++ b/rust/rust_test.go
@@ -61,6 +61,7 @@
 		"foo.rs":     nil,
 		"foo.c":      nil,
 		"src/bar.rs": nil,
+		"src/any.h":  nil,
 		"liby.so":    nil,
 		"libz.so":    nil,
 	}
@@ -181,7 +182,7 @@
 		}
 		rust_library_host_rlib {
 			name: "librlib",
-			srcs: ["foo.rs"],
+			srcs: ["foo.rs", ":my_generator"],
 			crate_name: "rlib",
 		}
 		rust_proc_macro {
@@ -189,17 +190,38 @@
 			srcs: ["foo.rs"],
 			crate_name: "pm",
 		}
+		genrule {
+			name: "my_generator",
+			tools: ["any_rust_binary"],
+			cmd: "$(location) -o $(out) $(in)",
+			srcs: ["src/any.h"],
+			out: ["src/any.rs"],
+		}
 		rust_binary_host {
-			name: "fizz-buzz",
+			name: "fizz-buzz-dep",
 			dylibs: ["libdylib"],
 			rlibs: ["librlib"],
 			proc_macros: ["libpm"],
 			static_libs: ["libstatic"],
 			shared_libs: ["libshared"],
-			srcs: ["foo.rs"],
+			srcs: [
+				"foo.rs",
+				":my_generator",
+			],
 		}
 	`)
-	module := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Module().(*Module)
+	module := ctx.ModuleForTests("fizz-buzz-dep", "linux_glibc_x86_64").Module().(*Module)
+	rlibmodule := ctx.ModuleForTests("librlib", "linux_glibc_x86_64_rlib").Module().(*Module)
+
+	srcs := module.compiler.(*binaryDecorator).baseCompiler.Properties.Srcs
+	if len(srcs) != 2 || !android.InList(":my_generator", srcs) {
+		t.Errorf("missing module dependency in fizz-buzz)")
+	}
+
+	srcs = rlibmodule.compiler.(*libraryDecorator).baseCompiler.Properties.Srcs
+	if len(srcs) != 2 || !android.InList(":my_generator", srcs) {
+		t.Errorf("missing module dependency in rlib")
+	}
 
 	// Since dependencies are added to AndroidMk* properties, we can check these to see if they've been picked up.
 	if !android.InList("libdylib", module.Properties.AndroidMkDylibs) {
diff --git a/rust/testing.go b/rust/testing.go
index 3d583e1..430b40b 100644
--- a/rust/testing.go
+++ b/rust/testing.go
@@ -17,6 +17,7 @@
 import (
 	"android/soong/android"
 	"android/soong/cc"
+	"android/soong/genrule"
 )
 
 func GatherRequiredDepsForTest() string {
@@ -77,6 +78,7 @@
 func CreateTestContext() *android.TestContext {
 	ctx := android.NewTestArchContext()
 	cc.RegisterRequiredBuildComponentsForTest(ctx)
+	ctx.RegisterModuleType("genrule", genrule.GenRuleFactory)
 	ctx.RegisterModuleType("rust_binary", RustBinaryFactory)
 	ctx.RegisterModuleType("rust_binary_host", RustBinaryHostFactory)
 	ctx.RegisterModuleType("rust_test", RustTestFactory)