Pass pctx and ctx to NewRuleBuilder
Enable the RuleBuilder and RuleBuilderCommand methods to access the BuilderContext by passing it to NewRuleBuilder instead of RuleBuilder.Build. Test: genrule_test.go Test: rule_builder_test.go Test: m checkbuild Change-Id: I63e6597e19167393876dc2259d6f521363b7dabc
This commit is contained in:
@@ -37,6 +37,9 @@ const sboxOutDir = sboxSandboxBaseDir + "/" + sboxOutSubDir
|
||||
// RuleBuilder provides an alternative to ModuleContext.Rule and ModuleContext.Build to add a command line to the build
|
||||
// graph.
|
||||
type RuleBuilder struct {
|
||||
pctx PackageContext
|
||||
ctx BuilderContext
|
||||
|
||||
commands []*RuleBuilderCommand
|
||||
installs RuleBuilderInstalls
|
||||
temporariesSet map[WritablePath]bool
|
||||
@@ -44,14 +47,16 @@ type RuleBuilder struct {
|
||||
sbox bool
|
||||
highmem bool
|
||||
remoteable RemoteRuleSupports
|
||||
sboxOutDir WritablePath
|
||||
outDir WritablePath
|
||||
sboxManifestPath WritablePath
|
||||
missingDeps []string
|
||||
}
|
||||
|
||||
// NewRuleBuilder returns a newly created RuleBuilder.
|
||||
func NewRuleBuilder() *RuleBuilder {
|
||||
func NewRuleBuilder(pctx PackageContext, ctx BuilderContext) *RuleBuilder {
|
||||
return &RuleBuilder{
|
||||
pctx: pctx,
|
||||
ctx: ctx,
|
||||
temporariesSet: make(map[WritablePath]bool),
|
||||
}
|
||||
}
|
||||
@@ -130,7 +135,7 @@ func (r *RuleBuilder) Sbox(outputDir WritablePath, manifestPath WritablePath) *R
|
||||
panic("Sbox() is not compatible with Restat()")
|
||||
}
|
||||
r.sbox = true
|
||||
r.sboxOutDir = outputDir
|
||||
r.outDir = outputDir
|
||||
r.sboxManifestPath = manifestPath
|
||||
return r
|
||||
}
|
||||
@@ -146,8 +151,7 @@ func (r *RuleBuilder) Install(from Path, to string) {
|
||||
// race with any call to Build.
|
||||
func (r *RuleBuilder) Command() *RuleBuilderCommand {
|
||||
command := &RuleBuilderCommand{
|
||||
sbox: r.sbox,
|
||||
outDir: r.sboxOutDir,
|
||||
rule: r,
|
||||
}
|
||||
r.commands = append(r.commands, command)
|
||||
return command
|
||||
@@ -395,19 +399,19 @@ type BuilderContext interface {
|
||||
var _ BuilderContext = ModuleContext(nil)
|
||||
var _ BuilderContext = SingletonContext(nil)
|
||||
|
||||
func (r *RuleBuilder) depFileMergerCmd(ctx PathContext, depFiles WritablePaths) *RuleBuilderCommand {
|
||||
func (r *RuleBuilder) depFileMergerCmd(depFiles WritablePaths) *RuleBuilderCommand {
|
||||
return r.Command().
|
||||
BuiltTool(ctx, "dep_fixer").
|
||||
BuiltTool("dep_fixer").
|
||||
Inputs(depFiles.Paths())
|
||||
}
|
||||
|
||||
// Build adds the built command line to the build graph, with dependencies on Inputs and Tools, and output files for
|
||||
// Outputs.
|
||||
func (r *RuleBuilder) Build(pctx PackageContext, ctx BuilderContext, name string, desc string) {
|
||||
func (r *RuleBuilder) Build(name string, desc string) {
|
||||
name = ninjaNameEscape(name)
|
||||
|
||||
if len(r.missingDeps) > 0 {
|
||||
ctx.Build(pctx, BuildParams{
|
||||
r.ctx.Build(pctx, BuildParams{
|
||||
Rule: ErrorRule,
|
||||
Outputs: r.Outputs(),
|
||||
OrderOnly: r.OrderOnlys(),
|
||||
@@ -426,13 +430,13 @@ func (r *RuleBuilder) Build(pctx PackageContext, ctx BuilderContext, name string
|
||||
depFormat = blueprint.DepsGCC
|
||||
if len(depFiles) > 1 {
|
||||
// Add a command locally that merges all depfiles together into the first depfile.
|
||||
r.depFileMergerCmd(ctx, depFiles)
|
||||
r.depFileMergerCmd(depFiles)
|
||||
|
||||
if r.sbox {
|
||||
// Check for Rel() errors, as all depfiles should be in the output dir. Errors
|
||||
// will be reported to the ctx.
|
||||
for _, path := range depFiles[1:] {
|
||||
Rel(ctx, r.sboxOutDir.String(), path.String())
|
||||
Rel(r.ctx, r.outDir.String(), path.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -468,7 +472,7 @@ func (r *RuleBuilder) Build(pctx PackageContext, ctx BuilderContext, name string
|
||||
// to the output directory.
|
||||
sboxOutputs := make([]string, len(outputs))
|
||||
for i, output := range outputs {
|
||||
rel := Rel(ctx, r.sboxOutDir.String(), output.String())
|
||||
rel := Rel(r.ctx, r.outDir.String(), output.String())
|
||||
sboxOutputs[i] = filepath.Join(sboxOutDir, rel)
|
||||
command.CopyAfter = append(command.CopyAfter, &sbox_proto.Copy{
|
||||
From: proto.String(filepath.Join(sboxOutSubDir, rel)),
|
||||
@@ -483,23 +487,27 @@ func (r *RuleBuilder) Build(pctx PackageContext, ctx BuilderContext, name string
|
||||
|
||||
// Verify that the manifest textproto is not inside the sbox output directory, otherwise
|
||||
// it will get deleted when the sbox rule clears its output directory.
|
||||
_, manifestInOutDir := MaybeRel(ctx, r.sboxOutDir.String(), r.sboxManifestPath.String())
|
||||
_, manifestInOutDir := MaybeRel(r.ctx, r.outDir.String(), r.sboxManifestPath.String())
|
||||
if manifestInOutDir {
|
||||
ReportPathErrorf(ctx, "sbox rule %q manifestPath %q must not be in outputDir %q",
|
||||
name, r.sboxManifestPath.String(), r.sboxOutDir.String())
|
||||
ReportPathErrorf(r.ctx, "sbox rule %q manifestPath %q must not be in outputDir %q",
|
||||
name, r.sboxManifestPath.String(), r.outDir.String())
|
||||
}
|
||||
|
||||
// Create a rule to write the manifest as a the textproto.
|
||||
WriteFileRule(ctx, r.sboxManifestPath, proto.MarshalTextString(&manifest))
|
||||
WriteFileRule(r.ctx, r.sboxManifestPath, proto.MarshalTextString(&manifest))
|
||||
|
||||
// Generate a new string to use as the command line of the sbox rule. This uses
|
||||
// a RuleBuilderCommand as a convenience method of building the command line, then
|
||||
// converts it to a string to replace commandString.
|
||||
sboxCmd := &RuleBuilderCommand{}
|
||||
sboxCmd.Text("rm -rf").Output(r.sboxOutDir)
|
||||
sboxCmd := &RuleBuilderCommand{
|
||||
rule: &RuleBuilder{
|
||||
ctx: r.ctx,
|
||||
},
|
||||
}
|
||||
sboxCmd.Text("rm -rf").Output(r.outDir)
|
||||
sboxCmd.Text("&&")
|
||||
sboxCmd.BuiltTool(ctx, "sbox").
|
||||
Flag("--sandbox-path").Text(shared.TempDirForOutDir(PathForOutput(ctx).String())).
|
||||
sboxCmd.BuiltTool("sbox").
|
||||
Flag("--sandbox-path").Text(shared.TempDirForOutDir(PathForOutput(r.ctx).String())).
|
||||
Flag("--manifest").Input(r.sboxManifestPath)
|
||||
|
||||
// Replace the command string, and add the sbox tool and manifest textproto to the
|
||||
@@ -528,19 +536,19 @@ func (r *RuleBuilder) Build(pctx PackageContext, ctx BuilderContext, name string
|
||||
}
|
||||
|
||||
var pool blueprint.Pool
|
||||
if ctx.Config().UseGoma() && r.remoteable.Goma {
|
||||
if r.ctx.Config().UseGoma() && r.remoteable.Goma {
|
||||
// When USE_GOMA=true is set and the rule is supported by goma, allow jobs to run outside the local pool.
|
||||
} else if ctx.Config().UseRBE() && r.remoteable.RBE {
|
||||
} else if r.ctx.Config().UseRBE() && r.remoteable.RBE {
|
||||
// When USE_RBE=true is set and the rule is supported by RBE, use the remotePool.
|
||||
pool = remotePool
|
||||
} else if r.highmem {
|
||||
pool = highmemPool
|
||||
} else if ctx.Config().UseRemoteBuild() {
|
||||
} else if r.ctx.Config().UseRemoteBuild() {
|
||||
pool = localPool
|
||||
}
|
||||
|
||||
ctx.Build(pctx, BuildParams{
|
||||
Rule: ctx.Rule(pctx, name, blueprint.RuleParams{
|
||||
r.ctx.Build(r.pctx, BuildParams{
|
||||
Rule: r.ctx.Rule(pctx, name, blueprint.RuleParams{
|
||||
Command: commandString,
|
||||
CommandDeps: tools.Strings(),
|
||||
Restat: r.restat,
|
||||
@@ -564,6 +572,8 @@ func (r *RuleBuilder) Build(pctx PackageContext, ctx BuilderContext, name string
|
||||
// RuleBuilderCommand, so they can be used chained or unchained. All methods that add text implicitly add a single
|
||||
// space as a separator from the previous method.
|
||||
type RuleBuilderCommand struct {
|
||||
rule *RuleBuilder
|
||||
|
||||
buf strings.Builder
|
||||
inputs Paths
|
||||
implicits Paths
|
||||
@@ -576,16 +586,11 @@ type RuleBuilderCommand struct {
|
||||
|
||||
// spans [start,end) of the command that should not be ninja escaped
|
||||
unescapedSpans [][2]int
|
||||
|
||||
sbox bool
|
||||
// outDir is the directory that will contain the output files of the rules. sbox will copy
|
||||
// the output files from the sandbox directory to this directory when it finishes.
|
||||
outDir WritablePath
|
||||
}
|
||||
|
||||
func (c *RuleBuilderCommand) addInput(path Path) string {
|
||||
if c.sbox {
|
||||
if rel, isRel, _ := maybeRelErr(c.outDir.String(), path.String()); isRel {
|
||||
if c.rule.sbox {
|
||||
if rel, isRel, _ := maybeRelErr(c.rule.outDir.String(), path.String()); isRel {
|
||||
return filepath.Join(sboxOutDir, rel)
|
||||
}
|
||||
}
|
||||
@@ -594,8 +599,8 @@ func (c *RuleBuilderCommand) addInput(path Path) string {
|
||||
}
|
||||
|
||||
func (c *RuleBuilderCommand) addImplicit(path Path) string {
|
||||
if c.sbox {
|
||||
if rel, isRel, _ := maybeRelErr(c.outDir.String(), path.String()); isRel {
|
||||
if c.rule.sbox {
|
||||
if rel, isRel, _ := maybeRelErr(c.rule.outDir.String(), path.String()); isRel {
|
||||
return filepath.Join(sboxOutDir, rel)
|
||||
}
|
||||
}
|
||||
@@ -607,22 +612,19 @@ func (c *RuleBuilderCommand) addOrderOnly(path Path) {
|
||||
c.orderOnlys = append(c.orderOnlys, path)
|
||||
}
|
||||
|
||||
func (c *RuleBuilderCommand) outputStr(path WritablePath) string {
|
||||
if c.sbox {
|
||||
return SboxPathForOutput(path, c.outDir)
|
||||
// PathForOutput takes an output path and returns the appropriate path to use on the command
|
||||
// line. If sbox was enabled via a call to RuleBuilder.Sbox(), it returns a path with the
|
||||
// placeholder prefix used for outputs in sbox. If sbox is not enabled it returns the
|
||||
// original path.
|
||||
func (c *RuleBuilderCommand) PathForOutput(path WritablePath) string {
|
||||
if c.rule.sbox {
|
||||
// Errors will be handled in RuleBuilder.Build where we have a context to report them
|
||||
rel, _, _ := maybeRelErr(c.rule.outDir.String(), path.String())
|
||||
return filepath.Join(sboxOutDir, rel)
|
||||
}
|
||||
return path.String()
|
||||
}
|
||||
|
||||
// SboxPathForOutput takes an output path and the out directory passed to RuleBuilder.Sbox(),
|
||||
// and returns the corresponding path for the output in the sbox sandbox. This can be used
|
||||
// on the RuleBuilder command line to reference the output.
|
||||
func SboxPathForOutput(path WritablePath, outDir WritablePath) string {
|
||||
// Errors will be handled in RuleBuilder.Build where we have a context to report them
|
||||
rel, _, _ := maybeRelErr(outDir.String(), path.String())
|
||||
return filepath.Join(sboxOutDir, rel)
|
||||
}
|
||||
|
||||
// Text adds the specified raw text to the command line. The text should not contain input or output paths or the
|
||||
// rule will not have them listed in its dependencies or outputs.
|
||||
func (c *RuleBuilderCommand) Text(text string) *RuleBuilderCommand {
|
||||
@@ -699,8 +701,8 @@ func (c *RuleBuilderCommand) Tool(path Path) *RuleBuilderCommand {
|
||||
//
|
||||
// It is equivalent to:
|
||||
// cmd.Tool(ctx.Config().HostToolPath(ctx, tool))
|
||||
func (c *RuleBuilderCommand) BuiltTool(ctx PathContext, tool string) *RuleBuilderCommand {
|
||||
return c.Tool(ctx.Config().HostToolPath(ctx, tool))
|
||||
func (c *RuleBuilderCommand) BuiltTool(tool string) *RuleBuilderCommand {
|
||||
return c.Tool(c.rule.ctx.Config().HostToolPath(c.rule.ctx, tool))
|
||||
}
|
||||
|
||||
// PrebuiltBuildTool adds the specified tool path from prebuils/build-tools. The path will be also added to the
|
||||
@@ -768,7 +770,7 @@ func (c *RuleBuilderCommand) OrderOnlys(paths Paths) *RuleBuilderCommand {
|
||||
// RuleBuilder.Outputs.
|
||||
func (c *RuleBuilderCommand) Output(path WritablePath) *RuleBuilderCommand {
|
||||
c.outputs = append(c.outputs, path)
|
||||
return c.Text(c.outputStr(path))
|
||||
return c.Text(c.PathForOutput(path))
|
||||
}
|
||||
|
||||
// Outputs adds the specified output paths to the command line, separated by spaces. The paths will also be added to
|
||||
@@ -783,7 +785,7 @@ func (c *RuleBuilderCommand) Outputs(paths WritablePaths) *RuleBuilderCommand {
|
||||
// OutputDir adds the output directory to the command line. This is only available when used with RuleBuilder.Sbox,
|
||||
// and will be the temporary output directory managed by sbox, not the final one.
|
||||
func (c *RuleBuilderCommand) OutputDir() *RuleBuilderCommand {
|
||||
if !c.sbox {
|
||||
if !c.rule.sbox {
|
||||
panic("OutputDir only valid with Sbox")
|
||||
}
|
||||
return c.Text(sboxOutDir)
|
||||
@@ -794,7 +796,7 @@ func (c *RuleBuilderCommand) OutputDir() *RuleBuilderCommand {
|
||||
// commands in a single RuleBuilder then RuleBuilder.Build will add an extra command to merge the depfiles together.
|
||||
func (c *RuleBuilderCommand) DepFile(path WritablePath) *RuleBuilderCommand {
|
||||
c.depFiles = append(c.depFiles, path)
|
||||
return c.Text(c.outputStr(path))
|
||||
return c.Text(c.PathForOutput(path))
|
||||
}
|
||||
|
||||
// ImplicitOutput adds the specified output path to the dependencies returned by RuleBuilder.Outputs without modifying
|
||||
@@ -885,14 +887,14 @@ func (c *RuleBuilderCommand) FlagForEachInput(flag string, paths Paths) *RuleBui
|
||||
// will also be added to the outputs returned by RuleBuilder.Outputs.
|
||||
func (c *RuleBuilderCommand) FlagWithOutput(flag string, path WritablePath) *RuleBuilderCommand {
|
||||
c.outputs = append(c.outputs, path)
|
||||
return c.Text(flag + c.outputStr(path))
|
||||
return c.Text(flag + c.PathForOutput(path))
|
||||
}
|
||||
|
||||
// FlagWithDepFile adds the specified flag and depfile path to the command line, with no separator between them. The path
|
||||
// will also be added to the outputs returned by RuleBuilder.Outputs.
|
||||
func (c *RuleBuilderCommand) FlagWithDepFile(flag string, path WritablePath) *RuleBuilderCommand {
|
||||
c.depFiles = append(c.depFiles, path)
|
||||
return c.Text(flag + c.outputStr(path))
|
||||
return c.Text(flag + c.PathForOutput(path))
|
||||
}
|
||||
|
||||
// FlagWithRspFileInputList adds the specified flag and path to an rspfile to the command line, with no separator
|
||||
@@ -987,3 +989,21 @@ func hashSrcFiles(srcFiles Paths) string {
|
||||
h.Write([]byte(srcFileList))
|
||||
return fmt.Sprintf("%x", h.Sum(nil))
|
||||
}
|
||||
|
||||
// BuilderContextForTesting returns a BuilderContext for the given config that can be used for tests
|
||||
// that need to call methods that take a BuilderContext.
|
||||
func BuilderContextForTesting(config Config) BuilderContext {
|
||||
pathCtx := PathContextForTesting(config)
|
||||
return builderContextForTests{
|
||||
PathContext: pathCtx,
|
||||
}
|
||||
}
|
||||
|
||||
type builderContextForTests struct {
|
||||
PathContext
|
||||
}
|
||||
|
||||
func (builderContextForTests) Rule(PackageContext, string, blueprint.RuleParams, ...string) blueprint.Rule {
|
||||
return nil
|
||||
}
|
||||
func (builderContextForTests) Build(PackageContext, BuildParams) {}
|
||||
|
Reference in New Issue
Block a user