diff --git a/rust/binary.go b/rust/binary.go index a1cd410c2..9fc52cdb8 100644 --- a/rust/binary.go +++ b/rust/binary.go @@ -106,7 +106,8 @@ func (binary *binaryDecorator) nativeCoverage() bool { 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 16d730603..7f94bb514 100644 --- a/rust/builder.go +++ b/rust/builder.go @@ -166,6 +166,7 @@ func transformSrctoCrate(ctx ModuleContext, main android.Path, deps PathDeps, fl 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 92a3b07f2..c20179bd0 100644 --- a/rust/compiler.go +++ b/rust/compiler.go @@ -253,10 +253,24 @@ func (compiler *baseCompiler) relativeInstallPath() string { 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 bcde75795..58ca52a0c 100644 --- a/rust/compiler_test.go +++ b/rust/compiler_test.go @@ -43,7 +43,7 @@ func TestFeaturesToFlags(t *testing.T) { // 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 8b8e797a2..d718eb897 100644 --- a/rust/library.go +++ b/rust/library.go @@ -368,7 +368,8 @@ func (library *libraryDecorator) compilerFlags(ctx ModuleContext, flags Flags) F 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 67d649d35..3b4f40a55 100644 --- a/rust/prebuilt.go +++ b/rust/prebuilt.go @@ -95,7 +95,8 @@ func (prebuilt *prebuiltLibraryDecorator) compilerProps() []interface{} { 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 2719161e5..49dbd8dc2 100644 --- a/rust/proc_macro.go +++ b/rust/proc_macro.go @@ -65,7 +65,8 @@ func (procMacro *procMacroDecorator) compile(ctx ModuleContext, flags Flags, dep 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 72301a718..7a98c6468 100644 --- a/rust/rust.go +++ b/rust/rust.go @@ -239,6 +239,9 @@ type PathDeps struct { CrtBegin android.OptionalPath CrtEnd android.OptionalPath + + // Paths to generated source files + SrcDeps android.Paths } type RustLibraries []RustLibrary @@ -843,6 +846,7 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { // 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 08bc8ca48..e80392589 100644 --- a/rust/rust_test.go +++ b/rust/rust_test.go @@ -61,6 +61,7 @@ func testConfig(bp string) android.Config { "foo.rs": nil, "foo.c": nil, "src/bar.rs": nil, + "src/any.h": nil, "liby.so": nil, "libz.so": nil, } @@ -181,7 +182,7 @@ func TestDepsTracking(t *testing.T) { } rust_library_host_rlib { name: "librlib", - srcs: ["foo.rs"], + srcs: ["foo.rs", ":my_generator"], crate_name: "rlib", } rust_proc_macro { @@ -189,17 +190,38 @@ func TestDepsTracking(t *testing.T) { 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 3d583e197..430b40bfd 100644 --- a/rust/testing.go +++ b/rust/testing.go @@ -17,6 +17,7 @@ package rust import ( "android/soong/android" "android/soong/cc" + "android/soong/genrule" ) func GatherRequiredDepsForTest() string { @@ -77,6 +78,7 @@ func GatherRequiredDepsForTest() string { 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)