Add direct deps on glob result files
n2 (a reimplemntation of ninja) adds a check that depfiles only add dependencies on source files, not generated files, because generated files are not guaranteed to exist before an action runs if there isn't an explicit dependency between the two. This is the case for our glob result files. However, we can rework the build so that they're directly depended on instead of using a depfile. Bug: 318434287 Test: rm -rf out && m nothing && m nothing Change-Id: I513fa5536136e6bf19c347710f0722d696199612
This commit is contained in:
@@ -28,6 +28,7 @@ import (
|
||||
"android/soong/android/allowlists"
|
||||
"android/soong/bp2build"
|
||||
"android/soong/shared"
|
||||
|
||||
"github.com/google/blueprint"
|
||||
"github.com/google/blueprint/bootstrap"
|
||||
"github.com/google/blueprint/deptools"
|
||||
@@ -196,7 +197,7 @@ func writeJsonModuleGraphAndActions(ctx *android.Context, cmdArgs android.CmdArg
|
||||
ctx.Context.PrintJSONGraphAndActions(graphFile, actionsFile)
|
||||
}
|
||||
|
||||
func writeBuildGlobsNinjaFile(ctx *android.Context) []string {
|
||||
func writeBuildGlobsNinjaFile(ctx *android.Context) {
|
||||
ctx.EventHandler.Begin("globs_ninja_file")
|
||||
defer ctx.EventHandler.End("globs_ninja_file")
|
||||
|
||||
@@ -208,7 +209,6 @@ func writeBuildGlobsNinjaFile(ctx *android.Context) []string {
|
||||
SrcDir: ctx.SrcDir(),
|
||||
}, ctx.Config())
|
||||
maybeQuit(err, "")
|
||||
return bootstrap.GlobFileListFiles(globDir)
|
||||
}
|
||||
|
||||
func writeDepFile(outputFile string, eventHandler *metrics.EventHandler, ninjaDeps []string) {
|
||||
@@ -238,8 +238,7 @@ func runSoongOnlyBuild(ctx *android.Context, extraNinjaDeps []string) string {
|
||||
maybeQuit(err, "")
|
||||
ninjaDeps = append(ninjaDeps, extraNinjaDeps...)
|
||||
|
||||
globListFiles := writeBuildGlobsNinjaFile(ctx)
|
||||
ninjaDeps = append(ninjaDeps, globListFiles...)
|
||||
writeBuildGlobsNinjaFile(ctx)
|
||||
|
||||
// Convert the Soong module graph into Bazel BUILD files.
|
||||
switch ctx.Config().BuildMode {
|
||||
|
@@ -36,6 +36,7 @@ import (
|
||||
"github.com/google/blueprint"
|
||||
"github.com/google/blueprint/bootstrap"
|
||||
"github.com/google/blueprint/microfactory"
|
||||
"github.com/google/blueprint/pathtools"
|
||||
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
@@ -181,7 +182,15 @@ func getGlobPathName(config Config) string {
|
||||
return globPathName
|
||||
}
|
||||
|
||||
func (pb PrimaryBuilderFactory) primaryBuilderInvocation() bootstrap.PrimaryBuilderInvocation {
|
||||
func getGlobPathNameFromPrimaryBuilderFactory(config Config, pb PrimaryBuilderFactory) string {
|
||||
if pb.name == soongBuildTag {
|
||||
// Glob path for soong build would be separated per product target
|
||||
return getGlobPathName(config)
|
||||
}
|
||||
return pb.name
|
||||
}
|
||||
|
||||
func (pb PrimaryBuilderFactory) primaryBuilderInvocation(config Config) bootstrap.PrimaryBuilderInvocation {
|
||||
commonArgs := make([]string, 0, 0)
|
||||
|
||||
if !pb.config.skipSoongTests {
|
||||
@@ -215,11 +224,7 @@ func (pb PrimaryBuilderFactory) primaryBuilderInvocation() bootstrap.PrimaryBuil
|
||||
|
||||
var allArgs []string
|
||||
allArgs = append(allArgs, pb.specificArgs...)
|
||||
globPathName := pb.name
|
||||
// Glob path for soong build would be separated per product target
|
||||
if pb.name == soongBuildTag {
|
||||
globPathName = getGlobPathName(pb.config)
|
||||
}
|
||||
globPathName := getGlobPathNameFromPrimaryBuilderFactory(config, pb)
|
||||
allArgs = append(allArgs,
|
||||
"--globListDir", globPathName,
|
||||
"--globFile", pb.config.NamedGlobFile(globPathName))
|
||||
@@ -234,8 +239,11 @@ func (pb PrimaryBuilderFactory) primaryBuilderInvocation() bootstrap.PrimaryBuil
|
||||
}
|
||||
allArgs = append(allArgs, "Android.bp")
|
||||
|
||||
globfiles := bootstrap.GlobFileListFiles(bootstrap.GlobDirectory(config.SoongOutDir(), globPathName))
|
||||
|
||||
return bootstrap.PrimaryBuilderInvocation{
|
||||
Inputs: []string{"Android.bp"},
|
||||
Implicits: globfiles,
|
||||
Outputs: []string{pb.output},
|
||||
Args: allArgs,
|
||||
Description: pb.description,
|
||||
@@ -376,17 +384,10 @@ func bootstrapBlueprint(ctx Context, config Config) {
|
||||
if debuggedInvocations[pbf.name] {
|
||||
pbf.debugPort = delvePort
|
||||
}
|
||||
pbi := pbf.primaryBuilderInvocation()
|
||||
pbi := pbf.primaryBuilderInvocation(config)
|
||||
invocations = append(invocations, pbi)
|
||||
}
|
||||
|
||||
// The glob .ninja files are subninja'd. However, they are generated during
|
||||
// the build itself so we write an empty file if the file does not exist yet
|
||||
// so that the subninja doesn't fail on clean builds
|
||||
for _, globFile := range bootstrapGlobFileList(config) {
|
||||
writeEmptyFile(ctx, globFile)
|
||||
}
|
||||
|
||||
blueprintArgs := bootstrap.Args{
|
||||
ModuleListFile: filepath.Join(config.FileListDir(), "Android.bp.list"),
|
||||
OutFile: shared.JoinPath(config.SoongOutDir(), "bootstrap.ninja"),
|
||||
@@ -408,6 +409,28 @@ func bootstrapBlueprint(ctx Context, config Config) {
|
||||
primaryBuilderInvocations: invocations,
|
||||
}
|
||||
|
||||
// The glob ninja files are generated during the main build phase. However, the
|
||||
// primary buildifer invocation depends on all of its glob files, even before
|
||||
// it's been run. Generate a "empty" glob ninja file on the first run,
|
||||
// so that the files can be there to satisfy the dependency.
|
||||
for _, pb := range pbfs {
|
||||
globPathName := getGlobPathNameFromPrimaryBuilderFactory(config, pb)
|
||||
globNinjaFile := config.NamedGlobFile(globPathName)
|
||||
if _, err := os.Stat(globNinjaFile); os.IsNotExist(err) {
|
||||
err := bootstrap.WriteBuildGlobsNinjaFile(&bootstrap.GlobSingleton{
|
||||
GlobLister: func() pathtools.MultipleGlobResults { return nil },
|
||||
GlobFile: globNinjaFile,
|
||||
GlobDir: bootstrap.GlobDirectory(config.SoongOutDir(), globPathName),
|
||||
SrcDir: ".",
|
||||
}, blueprintConfig)
|
||||
if err != nil {
|
||||
ctx.Fatal(err)
|
||||
}
|
||||
} else if err != nil {
|
||||
ctx.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// since `bootstrap.ninja` is regenerated unconditionally, we ignore the deps, i.e. little
|
||||
// reason to write a `bootstrap.ninja.d` file
|
||||
_, err := bootstrap.RunBlueprint(blueprintArgs, bootstrap.DoEverything, blueprintCtx, blueprintConfig)
|
||||
|
Reference in New Issue
Block a user