Add explicit rspfile argument to RuleBuilderCommand.FlagWithRspFileInputList

Using $out.rsp as the rsp file adds extra complexity around keeping
the $ unescaped.  Make callers to FlagWithRspFileInputList provide
an explicit path for the rsp file instead.

Bug: 182612695
Test: rule_builder_test.go
Change-Id: I3f531d80c1efa8a9d09aac0a63790c5b11a9f0c6
This commit is contained in:
Colin Cross
2021-03-12 17:48:14 -08:00
parent 4502978bee
commit 70c4741215
10 changed files with 68 additions and 24 deletions

View File

@@ -385,6 +385,21 @@ func (r *RuleBuilder) RspFileInputs() Paths {
return rspFileInputs
}
// RspFile returns the path to the rspfile that was passed to the RuleBuilderCommand.FlagWithRspFileInputList method.
func (r *RuleBuilder) RspFile() WritablePath {
var rspFile WritablePath
for _, c := range r.commands {
if c.rspFile != nil {
if rspFile != nil {
panic("Multiple commands in a rule may not have rsp file inputs")
}
rspFile = c.rspFile
}
}
return rspFile
}
// Commands returns a slice containing the built command line for each call to RuleBuilder.Command.
func (r *RuleBuilder) Commands() []string {
var commands []string
@@ -461,6 +476,8 @@ func (r *RuleBuilder) Build(name string, desc string) {
commands := r.NinjaEscapedCommands()
outputs := r.Outputs()
inputs := r.Inputs()
rspFileInputs := r.RspFileInputs()
rspFilePath := r.RspFile()
if len(commands) == 0 {
return
@@ -559,15 +576,14 @@ func (r *RuleBuilder) Build(name string, desc string) {
}
// Ninja doesn't like multiple outputs when depfiles are enabled, move all but the first output to
// ImplicitOutputs. RuleBuilder only uses "$out" for the rsp file location, so the distinction between Outputs and
// ImplicitOutputs. RuleBuilder doesn't use "$out", so the distinction between Outputs and
// ImplicitOutputs doesn't matter.
output := outputs[0]
implicitOutputs := outputs[1:]
var rspFile, rspFileContent string
rspFileInputs := r.RspFileInputs()
if rspFileInputs != nil {
rspFile = "$out.rsp"
if rspFilePath != nil {
rspFile = rspFilePath.String()
rspFileContent = "$in"
}
@@ -620,6 +636,7 @@ type RuleBuilderCommand struct {
tools Paths
packagedTools []PackagingSpec
rspFileInputs Paths
rspFile WritablePath
// spans [start,end) of the command that should not be ninja escaped
unescapedSpans [][2]int
@@ -1020,8 +1037,9 @@ func (c *RuleBuilderCommand) FlagWithDepFile(flag string, path WritablePath) *Ru
}
// FlagWithRspFileInputList adds the specified flag and path to an rspfile to the command line, with no separator
// between them. The paths will be written to the rspfile.
func (c *RuleBuilderCommand) FlagWithRspFileInputList(flag string, paths Paths) *RuleBuilderCommand {
// between them. The paths will be written to the rspfile. If sbox is enabled, the rspfile must
// be outside the sbox directory.
func (c *RuleBuilderCommand) FlagWithRspFileInputList(flag string, rspFile WritablePath, paths Paths) *RuleBuilderCommand {
if c.rspFileInputs != nil {
panic("FlagWithRspFileInputList cannot be called if rsp file inputs have already been provided")
}
@@ -1033,10 +1051,16 @@ func (c *RuleBuilderCommand) FlagWithRspFileInputList(flag string, paths Paths)
}
c.rspFileInputs = paths
c.rspFile = rspFile
rspFile := "$out.rsp"
c.FlagWithArg(flag, rspFile)
c.unescapedSpans = append(c.unescapedSpans, [2]int{c.buf.Len() - len(rspFile), c.buf.Len()})
if c.rule.sbox {
if _, isRel, _ := maybeRelErr(c.rule.outDir.String(), rspFile.String()); isRel {
panic(fmt.Errorf("FlagWithRspFileInputList rspfile %q must not be inside out dir %q",
rspFile.String(), c.rule.outDir.String()))
}
}
c.FlagWithArg(flag, rspFile.String())
return c
}