Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 45a49718 authored by Colin Cross's avatar Colin Cross Committed by Gerrit Code Review
Browse files

Merge changes from topic "rule_builder_rsp"

* changes:
  Remove unescaped spans support from RuleBuilder
  Add explicit rspfile argument to RuleBuilderCommand.FlagWithRspFileInputList
  Ninja escape RuleBuilder rule params
parents d7ce8402 b70a1a90
Loading
Loading
Loading
Loading
+37 −50
Original line number Diff line number Diff line
@@ -385,21 +385,26 @@ func (r *RuleBuilder) RspFileInputs() Paths {
	return rspFileInputs
}

// Commands returns a slice containing the built command line for each call to RuleBuilder.Command.
func (r *RuleBuilder) Commands() []string {
	var commands []string
// 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 {
		commands = append(commands, c.String())
		if c.rspFile != nil {
			if rspFile != nil {
				panic("Multiple commands in a rule may not have rsp file inputs")
			}
	return commands
			rspFile = c.rspFile
		}
	}

	return rspFile
}

// NinjaEscapedCommands returns a slice containing the built command line after ninja escaping for each call to
// RuleBuilder.Command.
func (r *RuleBuilder) NinjaEscapedCommands() []string {
// Commands returns a slice containing the built command line for each call to RuleBuilder.Command.
func (r *RuleBuilder) Commands() []string {
	var commands []string
	for _, c := range r.commands {
		commands = append(commands, c.NinjaEscapedString())
		commands = append(commands, c.String())
	}
	return commands
}
@@ -458,9 +463,11 @@ func (r *RuleBuilder) Build(name string, desc string) {
	}

	tools := r.Tools()
	commands := r.NinjaEscapedCommands()
	commands := r.Commands()
	outputs := r.Outputs()
	inputs := r.Inputs()
	rspFileInputs := r.RspFileInputs()
	rspFilePath := r.RspFile()

	if len(commands) == 0 {
		return
@@ -530,7 +537,7 @@ func (r *RuleBuilder) Build(name string, desc string) {
		}

		// Create a rule to write the manifest as a the textproto.
		WriteFileRule(r.ctx, r.sboxManifestPath, proto.MarshalTextString(&manifest))
		WriteFileRule(r.ctx, r.sboxManifestPath, proptools.NinjaEscape(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
@@ -559,15 +566,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"
	}

@@ -585,10 +591,10 @@ func (r *RuleBuilder) Build(name string, desc string) {

	r.ctx.Build(r.pctx, BuildParams{
		Rule: r.ctx.Rule(pctx, name, blueprint.RuleParams{
			Command:        commandString,
			CommandDeps:    tools.Strings(),
			Command:        proptools.NinjaEscape(commandString),
			CommandDeps:    proptools.NinjaEscapeList(tools.Strings()),
			Restat:         r.restat,
			Rspfile:        rspFile,
			Rspfile:        proptools.NinjaEscape(rspFile),
			RspfileContent: rspFileContent,
			Pool:           pool,
		}),
@@ -620,9 +626,7 @@ type RuleBuilderCommand struct {
	tools          Paths
	packagedTools  []PackagingSpec
	rspFileInputs  Paths

	// spans [start,end) of the command that should not be ninja escaped
	unescapedSpans [][2]int
	rspFile        WritablePath
}

func (c *RuleBuilderCommand) addInput(path Path) string {
@@ -1020,8 +1024,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 +1038,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
}

@@ -1045,11 +1056,6 @@ func (c *RuleBuilderCommand) String() string {
	return c.buf.String()
}

// String returns the command line.
func (c *RuleBuilderCommand) NinjaEscapedString() string {
	return ninjaEscapeExceptForSpans(c.String(), c.unescapedSpans)
}

// RuleBuilderSboxProtoForTests takes the BuildParams for the manifest passed to RuleBuilder.Sbox()
// and returns sbox testproto generated by the RuleBuilder.
func RuleBuilderSboxProtoForTests(t *testing.T, params TestingBuildParams) *sbox_proto.Manifest {
@@ -1063,25 +1069,6 @@ func RuleBuilderSboxProtoForTests(t *testing.T, params TestingBuildParams) *sbox
	return &manifest
}

func ninjaEscapeExceptForSpans(s string, spans [][2]int) string {
	if len(spans) == 0 {
		return proptools.NinjaEscape(s)
	}

	sb := strings.Builder{}
	sb.Grow(len(s) * 11 / 10)

	i := 0
	for _, span := range spans {
		sb.WriteString(proptools.NinjaEscape(s[i:span[0]]))
		sb.WriteString(s[span[0]:span[1]])
		i = span[1]
	}
	sb.WriteString(proptools.NinjaEscape(s[i:]))

	return sb.String()
}

func ninjaNameEscape(s string) string {
	b := []byte(s)
	escaped := false
+3 −87
Original line number Diff line number Diff line
@@ -267,10 +267,10 @@ func ExampleRuleBuilderCommand_FlagWithRspFileInputList() {
	ctx := builderContext()
	fmt.Println(NewRuleBuilder(pctx, ctx).Command().
		Tool(PathForSource(ctx, "javac")).
		FlagWithRspFileInputList("@", PathsForTesting("a.java", "b.java")).
		NinjaEscapedString())
		FlagWithRspFileInputList("@", PathForOutput(ctx, "foo.rsp"), PathsForTesting("a.java", "b.java")).
		String())
	// Output:
	// javac @$out.rsp
	// javac @out/foo.rsp
}

func ExampleRuleBuilderCommand_String() {
@@ -283,16 +283,6 @@ func ExampleRuleBuilderCommand_String() {
	// FOO=foo echo $FOO
}

func ExampleRuleBuilderCommand_NinjaEscapedString() {
	ctx := builderContext()
	fmt.Println(NewRuleBuilder(pctx, ctx).Command().
		Text("FOO=foo").
		Text("echo $FOO").
		NinjaEscapedString())
	// Output:
	// FOO=foo echo $$FOO
}

func TestRuleBuilder(t *testing.T) {
	fs := map[string][]byte{
		"dep_fixer":  nil,
@@ -631,80 +621,6 @@ func TestRuleBuilder_Build(t *testing.T) {
	})
}

func Test_ninjaEscapeExceptForSpans(t *testing.T) {
	type args struct {
		s     string
		spans [][2]int
	}
	tests := []struct {
		name string
		args args
		want string
	}{
		{
			name: "empty",
			args: args{
				s: "",
			},
			want: "",
		},
		{
			name: "unescape none",
			args: args{
				s: "$abc",
			},
			want: "$$abc",
		},
		{
			name: "unescape all",
			args: args{
				s:     "$abc",
				spans: [][2]int{{0, 4}},
			},
			want: "$abc",
		},
		{
			name: "unescape first",
			args: args{
				s:     "$abc$",
				spans: [][2]int{{0, 1}},
			},
			want: "$abc$$",
		},
		{
			name: "unescape last",
			args: args{
				s:     "$abc$",
				spans: [][2]int{{4, 5}},
			},
			want: "$$abc$",
		},
		{
			name: "unescape middle",
			args: args{
				s:     "$a$b$c$",
				spans: [][2]int{{2, 5}},
			},
			want: "$$a$b$c$$",
		},
		{
			name: "unescape multiple",
			args: args{
				s:     "$a$b$c$",
				spans: [][2]int{{2, 3}, {4, 5}},
			},
			want: "$$a$b$c$$",
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if got := ninjaEscapeExceptForSpans(tt.args.s, tt.args.spans); got != tt.want {
				t.Errorf("ninjaEscapeExceptForSpans() = %v, want %v", got, tt.want)
			}
		})
	}
}

func TestRuleBuilderHashInputs(t *testing.T) {
	// The basic idea here is to verify that the command (in the case of a
	// non-sbox rule) or the sbox textproto manifest contain a hash of the
+1 −1
Original line number Diff line number Diff line
@@ -68,7 +68,7 @@ func robolectricTestSuite(ctx SingletonContext, files map[string]InstallPaths) W
		FlagWithOutput("-o ", outputFile).
		FlagWithArg("-P ", "host/testcases").
		FlagWithArg("-C ", testCasesDir.String()).
		FlagWithRspFileInputList("-r ", installedPaths.Paths())
		FlagWithRspFileInputList("-r ", outputFile.ReplaceExtension(ctx, "rsp"), installedPaths.Paths())
	rule.Build("robolectric_tests_zip", "robolectric-tests.zip")

	return outputFile
+2 −1
Original line number Diff line number Diff line
@@ -440,7 +440,8 @@ func (s *fuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
			command := builder.Command().BuiltTool("soong_zip").
				Flag("-j").
				FlagWithOutput("-o ", corpusZip)
			command.FlagWithRspFileInputList("-r ", fuzzModule.corpus)
			rspFile := corpusZip.ReplaceExtension(ctx, "rsp")
			command.FlagWithRspFileInputList("-r ", rspFile, fuzzModule.corpus)
			files = append(files, fileToZip{corpusZip, ""})
		}

+2 −1
Original line number Diff line number Diff line
@@ -528,10 +528,11 @@ func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
		ctx,
		snapshotDir,
		c.name+"-"+ctx.Config().DeviceName()+"_list")
	rspFile := snapshotOutputList.ReplaceExtension(ctx, "rsp")
	zipRule.Command().
		Text("tr").
		FlagWithArg("-d ", "\\'").
		FlagWithRspFileInputList("< ", snapshotOutputs).
		FlagWithRspFileInputList("< ", rspFile, snapshotOutputs).
		FlagWithOutput("> ", snapshotOutputList)

	zipRule.Temporary(snapshotOutputList)
Loading