Use a unique depfile for each gensrcs command
gensrcs modules run the same command once for each input file to
produce each output file. Each command needs its own depfile instead
of reusing one per shard. The depfiles will be merged together
by RuleBuilder into one depfile per shard.
Test: TestGenSrcs
Change-Id: Iaf4f2cf9f5592c20e32944ddf34e0a61aff17ba8
diff --git a/genrule/genrule.go b/genrule/genrule.go
index cd7c52f..d667e94 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -148,14 +148,16 @@
type taskFunc func(ctx android.ModuleContext, rawCommand string, srcFiles android.Paths) []generateTask
type generateTask struct {
- in android.Paths
- out android.WritablePaths
- depFile android.WritablePath
- copyTo android.WritablePaths
- genDir android.WritablePath
- cmd string
- shard int
- shards int
+ in android.Paths
+ out android.WritablePaths
+ depFile android.WritablePath
+ copyTo android.WritablePaths
+ genDir android.WritablePath
+ extraTools android.Paths // dependencies on tools used by the generator
+
+ cmd string
+ shard int
+ shards int
}
func (g *Module) GeneratedSourceFiles() android.Paths {
@@ -434,6 +436,7 @@
cmd.ImplicitOutputs(task.out)
cmd.Implicits(task.in)
cmd.Implicits(g.deps)
+ cmd.Implicits(task.extraTools)
if Bool(g.properties.Depfile) {
cmd.ImplicitDepFile(task.depFile)
}
@@ -584,8 +587,8 @@
for i, shard := range shards {
var commands []string
var outFiles android.WritablePaths
+ var commandDepFiles []string
var copyTo android.WritablePaths
- var depFile android.WritablePath
// When sharding is enabled (i.e. len(shards) > 1), the sbox rules for each
// shard will be write to their own directories and then be merged together
@@ -598,7 +601,7 @@
genDir := android.PathForModuleGen(ctx, genSubDir)
- for j, in := range shard {
+ for _, in := range shard {
outFile := android.GenPathWithExt(ctx, finalSubDir, in, String(properties.Output_extension))
// If sharding is enabled, then outFile is the path to the output file in
@@ -610,10 +613,6 @@
outFile = shardFile
}
- if j == 0 {
- depFile = outFile.ReplaceExtension(ctx, "d")
- }
-
outFiles = append(outFiles, outFile)
// pre-expand the command line to replace $in and $out with references to
@@ -624,6 +623,12 @@
return in.String(), nil
case "out":
return android.SboxPathForOutput(outFile, genDir), nil
+ case "depfile":
+ // Generate a depfile for each output file. Store the list for
+ // later in order to combine them all into a single depfile.
+ depFile := android.SboxPathForOutput(outFile.ReplaceExtension(ctx, "d"), genDir)
+ commandDepFiles = append(commandDepFiles, depFile)
+ return depFile, nil
default:
return "$(" + name + ")", nil
}
@@ -638,15 +643,29 @@
}
fullCommand := strings.Join(commands, " && ")
+ var outputDepfile android.WritablePath
+ var extraTools android.Paths
+ if len(commandDepFiles) > 0 {
+ // Each command wrote to a depfile, but ninja can only handle one
+ // depfile per rule. Use the dep_fixer tool at the end of the
+ // command to combine all the depfiles into a single output depfile.
+ outputDepfile = android.PathForModuleGen(ctx, genSubDir, "gensrcs.d")
+ depFixerTool := ctx.Config().HostToolPath(ctx, "dep_fixer")
+ fullCommand += fmt.Sprintf(" && %s -o $(depfile) %s",
+ depFixerTool.String(), strings.Join(commandDepFiles, " "))
+ extraTools = append(extraTools, depFixerTool)
+ }
+
generateTasks = append(generateTasks, generateTask{
- in: shard,
- out: outFiles,
- depFile: depFile,
- copyTo: copyTo,
- genDir: genDir,
- cmd: fullCommand,
- shard: i,
- shards: len(shards),
+ in: shard,
+ out: outFiles,
+ depFile: outputDepfile,
+ copyTo: copyTo,
+ genDir: genDir,
+ cmd: fullCommand,
+ shard: i,
+ shards: len(shards),
+ extraTools: extraTools,
})
}