diff --git a/bootstrap/bootstrap.go b/bootstrap/bootstrap.go index 13c6a0b..f68e5ef 100644 --- a/bootstrap/bootstrap.go +++ b/bootstrap/bootstrap.go @@ -149,6 +149,13 @@ var ( }, "depfile") + noop = pctx.StaticRule("noop", + blueprint.RuleParams{ + Command: "true", + Description: "noop", + Restat: true, + }) + _ = pctx.VariableFunc("ToolDir", func(config interface{}) (string, error) { return config.(BootstrapConfig).HostToolDir(), nil }) @@ -709,6 +716,13 @@ func (s *singleton) GenerateBuildActions(ctx blueprint.SingletonContext) { Inputs: blueprintGoPackages, Optional: true, }) + + // out/soong/bpglob is built by microfactory before any ninja runs, write a rule that + // convinces ninja that it has been built to avoid tripping Soong's dangling rules check. + ctx.Build(pctx, blueprint.BuildParams{ + Rule: noop, + Outputs: []string{"$bootstrapGlobCmd"}, + }) } // packageRoot returns the module-specific package root directory path. This diff --git a/bootstrap/glob.go b/bootstrap/glob.go index 9c80025..d699e00 100644 --- a/bootstrap/glob.go +++ b/bootstrap/glob.go @@ -44,22 +44,26 @@ import ( // in a build failure with a "missing and no known rule to make it" error. var ( - globCmd = filepath.Join("$ToolDir", "bpglob") + _ = pctx.VariableFunc("bootstrapGlobCmd", func(config interface{}) (string, error) { + return filepath.Join(config.(BootstrapConfig).SoongOutDir(), "bpglob"), nil + }) + + _ = pctx.StaticVariable("primaryBuilderGlobCmd", filepath.Join("$ToolDir", "bpglob")) // globRule rule traverses directories to produce a list of files that match $glob // and writes it to $out if it has changed, and writes the directories to $out.d GlobRule = pctx.StaticRule("GlobRule", blueprint.RuleParams{ - Command: fmt.Sprintf(`%s -o $out -v %d $args`, - globCmd, pathtools.BPGlobArgumentVersion), - CommandDeps: []string{globCmd}, + Command: fmt.Sprintf(`$globCmd -o $out -v %d $args`, + pathtools.BPGlobArgumentVersion), + CommandDeps: []string{"$globCmd"}, Description: "glob", Restat: true, Deps: blueprint.DepsGCC, Depfile: "$out.d", }, - "args") + "args", "globCmd") ) // GlobFileContext is the subset of ModuleContext and SingletonContext needed by GlobFile @@ -81,7 +85,8 @@ func GlobFile(ctx GlobFileContext, pattern string, excludes []string, fileListFi Rule: GlobRule, Outputs: []string{fileListFile}, Args: map[string]string{ - "args": args, + "args": args, + "globCmd": "$primaryBuilderGlobCmd", }, Description: "glob " + pattern, }) @@ -112,7 +117,8 @@ func multipleGlobFilesRule(ctx GlobFileContext, fileListFile string, shard int, Rule: GlobRule, Outputs: []string{fileListFile}, Args: map[string]string{ - "args": args.String(), + "args": args.String(), + "globCmd": "$bootstrapGlobCmd", }, Description: fmt.Sprintf("regenerate globs shard %d of %d", shard, numGlobBuckets), })