Merge "Move genrule on top of RuleBuilder"
This commit is contained in:
commit
d4a63eaeb7
7 changed files with 266 additions and 207 deletions
|
@ -15,7 +15,9 @@
|
|||
package android
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
|
@ -25,6 +27,8 @@ import (
|
|||
"android/soong/shared"
|
||||
)
|
||||
|
||||
const sboxOutDir = "__SBOX_OUT_DIR__"
|
||||
|
||||
// RuleBuilder provides an alternative to ModuleContext.Rule and ModuleContext.Build to add a command line to the build
|
||||
// graph.
|
||||
type RuleBuilder struct {
|
||||
|
@ -134,7 +138,7 @@ func (r *RuleBuilder) Install(from Path, to string) {
|
|||
func (r *RuleBuilder) Command() *RuleBuilderCommand {
|
||||
command := &RuleBuilderCommand{
|
||||
sbox: r.sbox,
|
||||
sboxOutDir: r.sboxOutDir,
|
||||
outDir: r.sboxOutDir,
|
||||
}
|
||||
r.commands = append(r.commands, command)
|
||||
return command
|
||||
|
@ -163,7 +167,7 @@ func (r *RuleBuilder) DeleteTemporaryFiles() {
|
|||
}
|
||||
|
||||
// Inputs returns the list of paths that were passed to the RuleBuilderCommand methods that take
|
||||
// input paths, such as RuleBuilderCommand.Input, RuleBuilderComand.Implicit, or
|
||||
// input paths, such as RuleBuilderCommand.Input, RuleBuilderCommand.Implicit, or
|
||||
// RuleBuilderCommand.FlagWithInput. Inputs to a command that are also outputs of another command
|
||||
// in the same RuleBuilder are filtered out. The list is sorted and duplicates removed.
|
||||
func (r *RuleBuilder) Inputs() Paths {
|
||||
|
@ -362,7 +366,7 @@ func (r *RuleBuilder) Commands() []string {
|
|||
return commands
|
||||
}
|
||||
|
||||
// NinjaEscapedCommands returns a slice containin the built command line after ninja escaping for each call to
|
||||
// NinjaEscapedCommands returns a slice containing the built command line after ninja escaping for each call to
|
||||
// RuleBuilder.Command.
|
||||
func (r *RuleBuilder) NinjaEscapedCommands() []string {
|
||||
var commands []string
|
||||
|
@ -427,6 +431,7 @@ func (r *RuleBuilder) Build(pctx PackageContext, ctx BuilderContext, name string
|
|||
tools := r.Tools()
|
||||
commands := r.NinjaEscapedCommands()
|
||||
outputs := r.Outputs()
|
||||
inputs := r.Inputs()
|
||||
|
||||
if len(commands) == 0 {
|
||||
return
|
||||
|
@ -440,7 +445,7 @@ func (r *RuleBuilder) Build(pctx PackageContext, ctx BuilderContext, name string
|
|||
if r.sbox {
|
||||
sboxOutputs := make([]string, len(outputs))
|
||||
for i, output := range outputs {
|
||||
sboxOutputs[i] = "__SBOX_OUT_DIR__/" + Rel(ctx, r.sboxOutDir.String(), output.String())
|
||||
sboxOutputs[i] = filepath.Join(sboxOutDir, Rel(ctx, r.sboxOutDir.String(), output.String()))
|
||||
}
|
||||
|
||||
commandString = proptools.ShellEscape(commandString)
|
||||
|
@ -458,10 +463,19 @@ func (r *RuleBuilder) Build(pctx PackageContext, ctx BuilderContext, name string
|
|||
sboxCmd.Flag("--depfile-out").Text(depFile.String())
|
||||
}
|
||||
|
||||
// Add a hash of the list of input files to the xbox command line so that ninja reruns
|
||||
// it when the list of input files changes.
|
||||
sboxCmd.FlagWithArg("--input-hash ", hashSrcFiles(inputs))
|
||||
|
||||
sboxCmd.Flags(sboxOutputs)
|
||||
|
||||
commandString = sboxCmd.buf.String()
|
||||
tools = append(tools, sboxCmd.tools...)
|
||||
} else {
|
||||
// If not using sbox the rule will run the command directly, put the hash of the
|
||||
// list of input files in a comment at the end of the command line to ensure ninja
|
||||
// reruns the rule when the list of input files changes.
|
||||
commandString += " # hash of input list: " + hashSrcFiles(inputs)
|
||||
}
|
||||
|
||||
// Ninja doesn't like multiple outputs when depfiles are enabled, move all but the first output to
|
||||
|
@ -499,7 +513,7 @@ func (r *RuleBuilder) Build(pctx PackageContext, ctx BuilderContext, name string
|
|||
Pool: pool,
|
||||
}),
|
||||
Inputs: rspFileInputs,
|
||||
Implicits: r.Inputs(),
|
||||
Implicits: inputs,
|
||||
Output: output,
|
||||
ImplicitOutputs: implicitOutputs,
|
||||
SymlinkOutputs: r.SymlinkOutputs(),
|
||||
|
@ -528,13 +542,15 @@ type RuleBuilderCommand struct {
|
|||
unescapedSpans [][2]int
|
||||
|
||||
sbox bool
|
||||
sboxOutDir WritablePath
|
||||
// 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.sboxOutDir.String(), path.String()); isRel {
|
||||
return "__SBOX_OUT_DIR__/" + rel
|
||||
if rel, isRel, _ := maybeRelErr(c.outDir.String(), path.String()); isRel {
|
||||
return filepath.Join(sboxOutDir, rel)
|
||||
}
|
||||
}
|
||||
c.inputs = append(c.inputs, path)
|
||||
|
@ -543,8 +559,8 @@ func (c *RuleBuilderCommand) addInput(path Path) string {
|
|||
|
||||
func (c *RuleBuilderCommand) addImplicit(path Path) string {
|
||||
if c.sbox {
|
||||
if rel, isRel, _ := maybeRelErr(c.sboxOutDir.String(), path.String()); isRel {
|
||||
return "__SBOX_OUT_DIR__/" + rel
|
||||
if rel, isRel, _ := maybeRelErr(c.outDir.String(), path.String()); isRel {
|
||||
return filepath.Join(sboxOutDir, rel)
|
||||
}
|
||||
}
|
||||
c.implicits = append(c.implicits, path)
|
||||
|
@ -555,15 +571,22 @@ func (c *RuleBuilderCommand) addOrderOnly(path Path) {
|
|||
c.orderOnlys = append(c.orderOnlys, path)
|
||||
}
|
||||
|
||||
func (c *RuleBuilderCommand) outputStr(path Path) string {
|
||||
func (c *RuleBuilderCommand) outputStr(path WritablePath) string {
|
||||
if c.sbox {
|
||||
// Errors will be handled in RuleBuilder.Build where we have a context to report them
|
||||
rel, _, _ := maybeRelErr(c.sboxOutDir.String(), path.String())
|
||||
return "__SBOX_OUT_DIR__/" + rel
|
||||
return SboxPathForOutput(path, c.outDir)
|
||||
}
|
||||
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 {
|
||||
|
@ -727,7 +750,7 @@ func (c *RuleBuilderCommand) OutputDir() *RuleBuilderCommand {
|
|||
if !c.sbox {
|
||||
panic("OutputDir only valid with Sbox")
|
||||
}
|
||||
return c.Text("__SBOX_OUT_DIR__")
|
||||
return c.Text(sboxOutDir)
|
||||
}
|
||||
|
||||
// DepFile adds the specified depfile path to the paths returned by RuleBuilder.DepFiles and adds it to the command
|
||||
|
@ -906,3 +929,12 @@ func ninjaNameEscape(s string) string {
|
|||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// hashSrcFiles returns a hash of the list of source files. It is used to ensure the command line
|
||||
// or the sbox textproto manifest change even if the input files are not listed on the command line.
|
||||
func hashSrcFiles(srcFiles Paths) string {
|
||||
h := sha256.New()
|
||||
srcFileList := strings.Join(srcFiles.Strings(), "\n")
|
||||
h.Write([]byte(srcFileList))
|
||||
return fmt.Sprintf("%x", h.Sum(nil))
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ import (
|
|||
"fmt"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
|
@ -441,7 +442,7 @@ func testRuleBuilderFactory() Module {
|
|||
type testRuleBuilderModule struct {
|
||||
ModuleBase
|
||||
properties struct {
|
||||
Src string
|
||||
Srcs []string
|
||||
|
||||
Restat bool
|
||||
Sbox bool
|
||||
|
@ -449,7 +450,7 @@ type testRuleBuilderModule struct {
|
|||
}
|
||||
|
||||
func (t *testRuleBuilderModule) GenerateAndroidBuildActions(ctx ModuleContext) {
|
||||
in := PathForSource(ctx, t.properties.Src)
|
||||
in := PathsForSource(ctx, t.properties.Srcs)
|
||||
out := PathForModuleOut(ctx, ctx.ModuleName())
|
||||
outDep := PathForModuleOut(ctx, ctx.ModuleName()+".d")
|
||||
outDir := PathForModuleOut(ctx)
|
||||
|
@ -468,17 +469,17 @@ func (t *testRuleBuilderSingleton) GenerateBuildActions(ctx SingletonContext) {
|
|||
out := PathForOutput(ctx, "baz")
|
||||
outDep := PathForOutput(ctx, "baz.d")
|
||||
outDir := PathForOutput(ctx)
|
||||
testRuleBuilder_Build(ctx, in, out, outDep, outDir, true, false)
|
||||
testRuleBuilder_Build(ctx, Paths{in}, out, outDep, outDir, true, false)
|
||||
}
|
||||
|
||||
func testRuleBuilder_Build(ctx BuilderContext, in Path, out, outDep, outDir WritablePath, restat, sbox bool) {
|
||||
func testRuleBuilder_Build(ctx BuilderContext, in Paths, out, outDep, outDir WritablePath, restat, sbox bool) {
|
||||
rule := NewRuleBuilder()
|
||||
|
||||
if sbox {
|
||||
rule.Sbox(outDir)
|
||||
}
|
||||
|
||||
rule.Command().Tool(PathForSource(ctx, "cp")).Input(in).Output(out).ImplicitDepFile(outDep)
|
||||
rule.Command().Tool(PathForSource(ctx, "cp")).Inputs(in).Output(out).ImplicitDepFile(outDep)
|
||||
|
||||
if restat {
|
||||
rule.Restat()
|
||||
|
@ -496,12 +497,12 @@ func TestRuleBuilder_Build(t *testing.T) {
|
|||
bp := `
|
||||
rule_builder_test {
|
||||
name: "foo",
|
||||
src: "bar",
|
||||
srcs: ["bar"],
|
||||
restat: true,
|
||||
}
|
||||
rule_builder_test {
|
||||
name: "foo_sbox",
|
||||
src: "bar",
|
||||
srcs: ["bar"],
|
||||
sbox: true,
|
||||
}
|
||||
`
|
||||
|
@ -519,7 +520,10 @@ func TestRuleBuilder_Build(t *testing.T) {
|
|||
|
||||
check := func(t *testing.T, params TestingBuildParams, wantCommand, wantOutput, wantDepfile string, wantRestat bool, extraCmdDeps []string) {
|
||||
t.Helper()
|
||||
if params.RuleParams.Command != wantCommand {
|
||||
command := params.RuleParams.Command
|
||||
re := regexp.MustCompile(" (# hash of input list:|--input-hash) [a-z0-9]*")
|
||||
command = re.ReplaceAllLiteralString(command, "")
|
||||
if command != wantCommand {
|
||||
t.Errorf("\nwant RuleParams.Command = %q\n got %q", wantCommand, params.RuleParams.Command)
|
||||
}
|
||||
|
||||
|
@ -651,3 +655,78 @@ func Test_ninjaEscapeExceptForSpans(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
// inputs.
|
||||
|
||||
// By including a hash of the inputs, we cause the rule to re-run if
|
||||
// the list of inputs changes because the command line or a dependency
|
||||
// changes.
|
||||
|
||||
bp := `
|
||||
rule_builder_test {
|
||||
name: "hash0",
|
||||
srcs: ["in1.txt", "in2.txt"],
|
||||
}
|
||||
rule_builder_test {
|
||||
name: "hash0_sbox",
|
||||
srcs: ["in1.txt", "in2.txt"],
|
||||
sbox: true,
|
||||
}
|
||||
rule_builder_test {
|
||||
name: "hash1",
|
||||
srcs: ["in1.txt", "in2.txt", "in3.txt"],
|
||||
}
|
||||
rule_builder_test {
|
||||
name: "hash1_sbox",
|
||||
srcs: ["in1.txt", "in2.txt", "in3.txt"],
|
||||
sbox: true,
|
||||
}
|
||||
`
|
||||
testcases := []struct {
|
||||
name string
|
||||
expectedHash string
|
||||
}{
|
||||
{
|
||||
name: "hash0",
|
||||
// sha256 value obtained from: echo -en 'in1.txt\nin2.txt' | sha256sum
|
||||
expectedHash: "18da75b9b1cc74b09e365b4ca2e321b5d618f438cc632b387ad9dc2ab4b20e9d",
|
||||
},
|
||||
{
|
||||
name: "hash1",
|
||||
// sha256 value obtained from: echo -en 'in1.txt\nin2.txt\nin3.txt' | sha256sum
|
||||
expectedHash: "a38d432a4b19df93140e1f1fe26c97ff0387dae01fe506412b47208f0595fb45",
|
||||
},
|
||||
}
|
||||
|
||||
config := TestConfig(buildDir, nil, bp, nil)
|
||||
ctx := NewTestContext(config)
|
||||
ctx.RegisterModuleType("rule_builder_test", testRuleBuilderFactory)
|
||||
ctx.Register()
|
||||
|
||||
_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
|
||||
FailIfErrored(t, errs)
|
||||
_, errs = ctx.PrepareBuildActions(config)
|
||||
FailIfErrored(t, errs)
|
||||
|
||||
for _, test := range testcases {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
t.Run("sbox", func(t *testing.T) {
|
||||
gen := ctx.ModuleForTests(test.name+"_sbox", "")
|
||||
command := gen.Output(test.name + "_sbox").RuleParams.Command
|
||||
if g, w := command, " --input-hash "+test.expectedHash; !strings.Contains(g, w) {
|
||||
t.Errorf("Expected command line to end with %q, got %q", w, g)
|
||||
}
|
||||
})
|
||||
t.Run("", func(t *testing.T) {
|
||||
gen := ctx.ModuleForTests(test.name+"", "")
|
||||
command := gen.Output(test.name).RuleParams.Command
|
||||
if g, w := command, " # hash of input list: "+test.expectedHash; !strings.HasSuffix(g, w) {
|
||||
t.Errorf("Expected command line to end with %q, got %q", w, g)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,7 +75,11 @@ func genYacc(ctx android.ModuleContext, rule *android.RuleBuilder, yaccFile andr
|
|||
cmd := rule.Command()
|
||||
|
||||
// Fix up #line markers to not use the sbox temporary directory
|
||||
sedCmd := "sed -i.bak 's#__SBOX_OUT_DIR__#" + outDir.String() + "#'"
|
||||
// android.SboxPathForOutput(outDir, outDir) returns the sbox placeholder for the out
|
||||
// directory itself, without any filename appended.
|
||||
// TODO(ccross): make this cmd.PathForOutput(outDir) instead.
|
||||
sboxOutDir := android.SboxPathForOutput(outDir, outDir)
|
||||
sedCmd := "sed -i.bak 's#" + sboxOutDir + "#" + outDir.String() + "#'"
|
||||
rule.Command().Text(sedCmd).Input(outFile)
|
||||
rule.Command().Text(sedCmd).Input(headerFile)
|
||||
|
||||
|
|
|
@ -66,14 +66,14 @@ func TestArchGenruleCmd(t *testing.T) {
|
|||
|
||||
gen := ctx.ModuleForTests("gen", "android_arm_armv7-a-neon").Output("out_arm")
|
||||
expected := []string{"foo"}
|
||||
if !reflect.DeepEqual(expected, gen.Inputs.Strings()) {
|
||||
t.Errorf(`want arm inputs %v, got %v`, expected, gen.Inputs.Strings())
|
||||
if !reflect.DeepEqual(expected, gen.Implicits.Strings()[:len(expected)]) {
|
||||
t.Errorf(`want arm inputs %v, got %v`, expected, gen.Implicits.Strings())
|
||||
}
|
||||
|
||||
gen = ctx.ModuleForTests("gen", "android_arm64_armv8-a").Output("out_arm64")
|
||||
expected = []string{"bar"}
|
||||
if !reflect.DeepEqual(expected, gen.Inputs.Strings()) {
|
||||
t.Errorf(`want arm64 inputs %v, got %v`, expected, gen.Inputs.Strings())
|
||||
if !reflect.DeepEqual(expected, gen.Implicits.Strings()[:len(expected)]) {
|
||||
t.Errorf(`want arm64 inputs %v, got %v`, expected, gen.Implicits.Strings())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -108,10 +108,10 @@ func TestLibraryGenruleCmd(t *testing.T) {
|
|||
gen := ctx.ModuleForTests("gen", "android_arm_armv7-a-neon").Output("out")
|
||||
expected := []string{"libboth.so", "libshared.so", "libstatic.a"}
|
||||
var got []string
|
||||
for _, input := range gen.Inputs {
|
||||
for _, input := range gen.Implicits {
|
||||
got = append(got, input.Base())
|
||||
}
|
||||
if !reflect.DeepEqual(expected, got) {
|
||||
if !reflect.DeepEqual(expected, got[:len(expected)]) {
|
||||
t.Errorf(`want inputs %v, got %v`, expected, got)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ package genrule
|
|||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
|
@ -25,9 +26,6 @@ import (
|
|||
"github.com/google/blueprint/proptools"
|
||||
|
||||
"android/soong/android"
|
||||
"android/soong/shared"
|
||||
"crypto/sha256"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -158,9 +156,9 @@ type taskFunc func(ctx android.ModuleContext, rawCommand string, srcFiles androi
|
|||
type generateTask struct {
|
||||
in android.Paths
|
||||
out android.WritablePaths
|
||||
depFile android.WritablePath
|
||||
copyTo android.WritablePaths
|
||||
genDir android.WritablePath
|
||||
sandboxOuts []string
|
||||
cmd string
|
||||
shard int
|
||||
shards int
|
||||
|
@ -330,19 +328,23 @@ func (g *Module) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||
var zipArgs strings.Builder
|
||||
|
||||
for _, task := range g.taskGenerator(ctx, String(g.properties.Cmd), srcFiles) {
|
||||
for _, out := range task.out {
|
||||
addLocationLabel(out.Rel(), []string{filepath.Join("__SBOX_OUT_DIR__", out.Rel())})
|
||||
if len(task.out) == 0 {
|
||||
ctx.ModuleErrorf("must have at least one output file")
|
||||
return
|
||||
}
|
||||
|
||||
for _, out := range task.out {
|
||||
addLocationLabel(out.Rel(), []string{android.SboxPathForOutput(out, task.genDir)})
|
||||
}
|
||||
|
||||
referencedIn := false
|
||||
referencedDepfile := false
|
||||
|
||||
rawCommand, err := android.ExpandNinjaEscaped(task.cmd, func(name string) (string, bool, error) {
|
||||
rawCommand, err := android.Expand(task.cmd, func(name string) (string, error) {
|
||||
// report the error directly without returning an error to android.Expand to catch multiple errors in a
|
||||
// single run
|
||||
reportError := func(fmt string, args ...interface{}) (string, bool, error) {
|
||||
reportError := func(fmt string, args ...interface{}) (string, error) {
|
||||
ctx.PropertyErrorf("cmd", fmt, args...)
|
||||
return "SOONG_ERROR", false, nil
|
||||
return "SOONG_ERROR", nil
|
||||
}
|
||||
|
||||
switch name {
|
||||
|
@ -357,20 +359,23 @@ func (g *Module) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||
return reportError("default label %q has multiple files, use $(locations %s) to reference it",
|
||||
firstLabel, firstLabel)
|
||||
}
|
||||
return locationLabels[firstLabel][0], false, nil
|
||||
return locationLabels[firstLabel][0], nil
|
||||
case "in":
|
||||
referencedIn = true
|
||||
return "${in}", true, nil
|
||||
return strings.Join(srcFiles.Strings(), " "), nil
|
||||
case "out":
|
||||
return "__SBOX_OUT_FILES__", false, nil
|
||||
var sandboxOuts []string
|
||||
for _, out := range task.out {
|
||||
sandboxOuts = append(sandboxOuts, android.SboxPathForOutput(out, task.genDir))
|
||||
}
|
||||
return strings.Join(sandboxOuts, " "), nil
|
||||
case "depfile":
|
||||
referencedDepfile = true
|
||||
if !Bool(g.properties.Depfile) {
|
||||
return reportError("$(depfile) used without depfile property")
|
||||
}
|
||||
return "__SBOX_DEPFILE__", false, nil
|
||||
return "__SBOX_DEPFILE__", nil
|
||||
case "genDir":
|
||||
return "__SBOX_OUT_DIR__", false, nil
|
||||
return android.SboxPathForOutput(task.genDir, task.genDir), nil
|
||||
default:
|
||||
if strings.HasPrefix(name, "location ") {
|
||||
label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
|
||||
|
@ -381,7 +386,7 @@ func (g *Module) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||
return reportError("label %q has multiple files, use $(locations %s) to reference it",
|
||||
label, label)
|
||||
}
|
||||
return paths[0], false, nil
|
||||
return paths[0], nil
|
||||
} else {
|
||||
return reportError("unknown location label %q", label)
|
||||
}
|
||||
|
@ -391,7 +396,7 @@ func (g *Module) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||
if len(paths) == 0 {
|
||||
return reportError("label %q has no files", label)
|
||||
}
|
||||
return strings.Join(paths, " "), false, nil
|
||||
return strings.Join(paths, " "), nil
|
||||
} else {
|
||||
return reportError("unknown locations label %q", label)
|
||||
}
|
||||
|
@ -410,50 +415,39 @@ func (g *Module) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||
ctx.PropertyErrorf("cmd", "specified depfile=true but did not include a reference to '${depfile}' in cmd")
|
||||
return
|
||||
}
|
||||
|
||||
// tell the sbox command which directory to use as its sandbox root
|
||||
buildDir := android.PathForOutput(ctx).String()
|
||||
sandboxPath := shared.TempDirForOutDir(buildDir)
|
||||
|
||||
// recall that Sprintf replaces percent sign expressions, whereas dollar signs expressions remain as written,
|
||||
// to be replaced later by ninja_strings.go
|
||||
depfilePlaceholder := ""
|
||||
if Bool(g.properties.Depfile) {
|
||||
depfilePlaceholder = "$depfileArgs"
|
||||
}
|
||||
|
||||
// Escape the command for the shell
|
||||
rawCommand = "'" + strings.Replace(rawCommand, "'", `'\''`, -1) + "'"
|
||||
g.rawCommands = append(g.rawCommands, rawCommand)
|
||||
|
||||
sandboxCommand := fmt.Sprintf("rm -rf %s && $sboxCmd --sandbox-path %s --output-root %s",
|
||||
task.genDir, sandboxPath, task.genDir)
|
||||
|
||||
if !referencedIn {
|
||||
sandboxCommand = sandboxCommand + hashSrcFiles(srcFiles)
|
||||
}
|
||||
|
||||
sandboxCommand = sandboxCommand + fmt.Sprintf(" -c %s %s $allouts",
|
||||
rawCommand, depfilePlaceholder)
|
||||
|
||||
ruleParams := blueprint.RuleParams{
|
||||
Command: sandboxCommand,
|
||||
CommandDeps: []string{"$sboxCmd"},
|
||||
}
|
||||
args := []string{"allouts"}
|
||||
if Bool(g.properties.Depfile) {
|
||||
ruleParams.Deps = blueprint.DepsGCC
|
||||
args = append(args, "depfileArgs")
|
||||
}
|
||||
// Pick a unique rule name and the user-visible description.
|
||||
desc := "generate"
|
||||
name := "generator"
|
||||
if task.shards > 1 {
|
||||
if task.shards > 0 {
|
||||
desc += " " + strconv.Itoa(task.shard)
|
||||
name += strconv.Itoa(task.shard)
|
||||
} else if len(task.out) == 1 {
|
||||
desc += " " + task.out[0].Base()
|
||||
}
|
||||
rule := ctx.Rule(pctx, name, ruleParams, args...)
|
||||
|
||||
g.generateSourceFile(ctx, task, rule)
|
||||
// Use a RuleBuilder to create a rule that runs the command inside an sbox sandbox.
|
||||
rule := android.NewRuleBuilder().Sbox(task.genDir)
|
||||
cmd := rule.Command()
|
||||
cmd.Text(rawCommand)
|
||||
cmd.ImplicitOutputs(task.out)
|
||||
cmd.Implicits(task.in)
|
||||
cmd.Implicits(g.deps)
|
||||
if Bool(g.properties.Depfile) {
|
||||
cmd.ImplicitDepFile(task.depFile)
|
||||
}
|
||||
|
||||
// Create the rule to run the genrule command inside sbox.
|
||||
rule.Build(pctx, ctx, name, desc)
|
||||
|
||||
if len(task.copyTo) > 0 {
|
||||
// If copyTo is set, multiple shards need to be copied into a single directory.
|
||||
// task.out contains the per-shard paths, and copyTo contains the corresponding
|
||||
// final path. The files need to be copied into the final directory by a
|
||||
// single rule so it can remove the directory before it starts to ensure no
|
||||
// old files remain. zipsync already does this, so build up zipArgs that
|
||||
// zip all the per-shard directories into a single zip.
|
||||
outputFiles = append(outputFiles, task.copyTo...)
|
||||
copyFrom = append(copyFrom, task.out.Paths()...)
|
||||
zipArgs.WriteString(" -C " + task.genDir.String())
|
||||
|
@ -464,6 +458,8 @@ func (g *Module) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||
}
|
||||
|
||||
if len(copyFrom) > 0 {
|
||||
// Create a rule that zips all the per-shard directories into a single zip and then
|
||||
// uses zipsync to unzip it into the final directory.
|
||||
ctx.Build(pctx, android.BuildParams{
|
||||
Rule: gensrcsMerge,
|
||||
Implicits: copyFrom,
|
||||
|
@ -501,51 +497,6 @@ func (g *Module) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||
}
|
||||
}
|
||||
}
|
||||
func hashSrcFiles(srcFiles android.Paths) string {
|
||||
h := sha256.New()
|
||||
for _, src := range srcFiles {
|
||||
h.Write([]byte(src.String()))
|
||||
}
|
||||
return fmt.Sprintf(" --input-hash %x", h.Sum(nil))
|
||||
}
|
||||
|
||||
func (g *Module) generateSourceFile(ctx android.ModuleContext, task generateTask, rule blueprint.Rule) {
|
||||
desc := "generate"
|
||||
if len(task.out) == 0 {
|
||||
ctx.ModuleErrorf("must have at least one output file")
|
||||
return
|
||||
}
|
||||
if len(task.out) == 1 {
|
||||
desc += " " + task.out[0].Base()
|
||||
}
|
||||
|
||||
var depFile android.ModuleGenPath
|
||||
if Bool(g.properties.Depfile) {
|
||||
depFile = android.PathForModuleGen(ctx, task.out[0].Rel()+".d")
|
||||
}
|
||||
|
||||
if task.shards > 1 {
|
||||
desc += " " + strconv.Itoa(task.shard)
|
||||
}
|
||||
|
||||
params := android.BuildParams{
|
||||
Rule: rule,
|
||||
Description: desc,
|
||||
Output: task.out[0],
|
||||
ImplicitOutputs: task.out[1:],
|
||||
Inputs: task.in,
|
||||
Implicits: g.deps,
|
||||
Args: map[string]string{
|
||||
"allouts": strings.Join(task.sandboxOuts, " "),
|
||||
},
|
||||
}
|
||||
if Bool(g.properties.Depfile) {
|
||||
params.Depfile = android.PathForModuleGen(ctx, task.out[0].Rel()+".d")
|
||||
params.Args["depfileArgs"] = "--depfile-out " + depFile.String()
|
||||
}
|
||||
|
||||
ctx.Build(pctx, params)
|
||||
}
|
||||
|
||||
// Collect information for opening IDE project files in java/jdeps.go.
|
||||
func (g *Module) IDEInfo(dpInfo *android.IdeInfo) {
|
||||
|
@ -610,16 +561,6 @@ func (x noopImageInterface) ExtraImageVariations(ctx android.BaseModuleContext)
|
|||
func (x noopImageInterface) SetImageVariation(ctx android.BaseModuleContext, variation string, module android.Module) {
|
||||
}
|
||||
|
||||
// replace "out" with "__SBOX_OUT_DIR__/<the value of ${out}>"
|
||||
func pathToSandboxOut(path android.Path, genDir android.Path) string {
|
||||
relOut, err := filepath.Rel(genDir.String(), path.String())
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Could not make ${out} relative: %v", err))
|
||||
}
|
||||
return filepath.Join("__SBOX_OUT_DIR__", relOut)
|
||||
|
||||
}
|
||||
|
||||
func NewGenSrcs() *Module {
|
||||
properties := &genSrcsProperties{}
|
||||
|
||||
|
@ -638,7 +579,7 @@ func NewGenSrcs() *Module {
|
|||
var outFiles android.WritablePaths
|
||||
var copyTo android.WritablePaths
|
||||
var shardDir android.WritablePath
|
||||
var sandboxOuts []string
|
||||
var depFile android.WritablePath
|
||||
|
||||
if len(shards) > 1 {
|
||||
shardDir = android.PathForModuleGen(ctx, strconv.Itoa(i))
|
||||
|
@ -646,9 +587,11 @@ func NewGenSrcs() *Module {
|
|||
shardDir = genDir
|
||||
}
|
||||
|
||||
for _, in := range shard {
|
||||
for j, in := range shard {
|
||||
outFile := android.GenPathWithExt(ctx, "gensrcs", in, String(properties.Output_extension))
|
||||
sandboxOutfile := pathToSandboxOut(outFile, genDir)
|
||||
if j == 0 {
|
||||
depFile = outFile.ReplaceExtension(ctx, "d")
|
||||
}
|
||||
|
||||
if len(shards) > 1 {
|
||||
shardFile := android.GenPathWithExt(ctx, strconv.Itoa(i), in, String(properties.Output_extension))
|
||||
|
@ -657,14 +600,13 @@ func NewGenSrcs() *Module {
|
|||
}
|
||||
|
||||
outFiles = append(outFiles, outFile)
|
||||
sandboxOuts = append(sandboxOuts, sandboxOutfile)
|
||||
|
||||
command, err := android.Expand(rawCommand, func(name string) (string, error) {
|
||||
switch name {
|
||||
case "in":
|
||||
return in.String(), nil
|
||||
case "out":
|
||||
return sandboxOutfile, nil
|
||||
return android.SboxPathForOutput(outFile, shardDir), nil
|
||||
default:
|
||||
return "$(" + name + ")", nil
|
||||
}
|
||||
|
@ -682,9 +624,9 @@ func NewGenSrcs() *Module {
|
|||
generateTasks = append(generateTasks, generateTask{
|
||||
in: shard,
|
||||
out: outFiles,
|
||||
depFile: depFile,
|
||||
copyTo: copyTo,
|
||||
genDir: shardDir,
|
||||
sandboxOuts: sandboxOuts,
|
||||
cmd: fullCommand,
|
||||
shard: i,
|
||||
shards: len(shards),
|
||||
|
@ -720,17 +662,19 @@ func NewGenRule() *Module {
|
|||
|
||||
taskGenerator := func(ctx android.ModuleContext, rawCommand string, srcFiles android.Paths) []generateTask {
|
||||
outs := make(android.WritablePaths, len(properties.Out))
|
||||
sandboxOuts := make([]string, len(properties.Out))
|
||||
genDir := android.PathForModuleGen(ctx)
|
||||
var depFile android.WritablePath
|
||||
for i, out := range properties.Out {
|
||||
outs[i] = android.PathForModuleGen(ctx, out)
|
||||
sandboxOuts[i] = pathToSandboxOut(outs[i], genDir)
|
||||
outPath := android.PathForModuleGen(ctx, out)
|
||||
if i == 0 {
|
||||
depFile = outPath.ReplaceExtension(ctx, "d")
|
||||
}
|
||||
outs[i] = outPath
|
||||
}
|
||||
return []generateTask{{
|
||||
in: srcFiles,
|
||||
out: outs,
|
||||
depFile: depFile,
|
||||
genDir: android.PathForModuleGen(ctx),
|
||||
sandboxOuts: sandboxOuts,
|
||||
cmd: rawCommand,
|
||||
}}
|
||||
}
|
||||
|
|
|
@ -141,7 +141,7 @@ func TestGenruleCmd(t *testing.T) {
|
|||
out: ["out"],
|
||||
cmd: "$(location) > $(out)",
|
||||
`,
|
||||
expect: "out/tool > __SBOX_OUT_FILES__",
|
||||
expect: "out/tool > __SBOX_OUT_DIR__/out",
|
||||
},
|
||||
{
|
||||
name: "empty location tool2",
|
||||
|
@ -150,7 +150,7 @@ func TestGenruleCmd(t *testing.T) {
|
|||
out: ["out"],
|
||||
cmd: "$(location) > $(out)",
|
||||
`,
|
||||
expect: "out/tool > __SBOX_OUT_FILES__",
|
||||
expect: "out/tool > __SBOX_OUT_DIR__/out",
|
||||
},
|
||||
{
|
||||
name: "empty location tool file",
|
||||
|
@ -159,7 +159,7 @@ func TestGenruleCmd(t *testing.T) {
|
|||
out: ["out"],
|
||||
cmd: "$(location) > $(out)",
|
||||
`,
|
||||
expect: "tool_file1 > __SBOX_OUT_FILES__",
|
||||
expect: "tool_file1 > __SBOX_OUT_DIR__/out",
|
||||
},
|
||||
{
|
||||
name: "empty location tool file fg",
|
||||
|
@ -168,7 +168,7 @@ func TestGenruleCmd(t *testing.T) {
|
|||
out: ["out"],
|
||||
cmd: "$(location) > $(out)",
|
||||
`,
|
||||
expect: "tool_file1 > __SBOX_OUT_FILES__",
|
||||
expect: "tool_file1 > __SBOX_OUT_DIR__/out",
|
||||
},
|
||||
{
|
||||
name: "empty location tool and tool file",
|
||||
|
@ -178,7 +178,7 @@ func TestGenruleCmd(t *testing.T) {
|
|||
out: ["out"],
|
||||
cmd: "$(location) > $(out)",
|
||||
`,
|
||||
expect: "out/tool > __SBOX_OUT_FILES__",
|
||||
expect: "out/tool > __SBOX_OUT_DIR__/out",
|
||||
},
|
||||
{
|
||||
name: "tool",
|
||||
|
@ -187,7 +187,7 @@ func TestGenruleCmd(t *testing.T) {
|
|||
out: ["out"],
|
||||
cmd: "$(location tool) > $(out)",
|
||||
`,
|
||||
expect: "out/tool > __SBOX_OUT_FILES__",
|
||||
expect: "out/tool > __SBOX_OUT_DIR__/out",
|
||||
},
|
||||
{
|
||||
name: "tool2",
|
||||
|
@ -196,7 +196,7 @@ func TestGenruleCmd(t *testing.T) {
|
|||
out: ["out"],
|
||||
cmd: "$(location :tool) > $(out)",
|
||||
`,
|
||||
expect: "out/tool > __SBOX_OUT_FILES__",
|
||||
expect: "out/tool > __SBOX_OUT_DIR__/out",
|
||||
},
|
||||
{
|
||||
name: "tool file",
|
||||
|
@ -205,7 +205,7 @@ func TestGenruleCmd(t *testing.T) {
|
|||
out: ["out"],
|
||||
cmd: "$(location tool_file1) > $(out)",
|
||||
`,
|
||||
expect: "tool_file1 > __SBOX_OUT_FILES__",
|
||||
expect: "tool_file1 > __SBOX_OUT_DIR__/out",
|
||||
},
|
||||
{
|
||||
name: "tool file fg",
|
||||
|
@ -214,7 +214,7 @@ func TestGenruleCmd(t *testing.T) {
|
|||
out: ["out"],
|
||||
cmd: "$(location :1tool_file) > $(out)",
|
||||
`,
|
||||
expect: "tool_file1 > __SBOX_OUT_FILES__",
|
||||
expect: "tool_file1 > __SBOX_OUT_DIR__/out",
|
||||
},
|
||||
{
|
||||
name: "tool files",
|
||||
|
@ -223,7 +223,7 @@ func TestGenruleCmd(t *testing.T) {
|
|||
out: ["out"],
|
||||
cmd: "$(locations :tool_files) > $(out)",
|
||||
`,
|
||||
expect: "tool_file1 tool_file2 > __SBOX_OUT_FILES__",
|
||||
expect: "tool_file1 tool_file2 > __SBOX_OUT_DIR__/out",
|
||||
},
|
||||
{
|
||||
name: "in1",
|
||||
|
@ -232,7 +232,7 @@ func TestGenruleCmd(t *testing.T) {
|
|||
out: ["out"],
|
||||
cmd: "cat $(in) > $(out)",
|
||||
`,
|
||||
expect: "cat ${in} > __SBOX_OUT_FILES__",
|
||||
expect: "cat in1 > __SBOX_OUT_DIR__/out",
|
||||
},
|
||||
{
|
||||
name: "in1 fg",
|
||||
|
@ -241,7 +241,7 @@ func TestGenruleCmd(t *testing.T) {
|
|||
out: ["out"],
|
||||
cmd: "cat $(in) > $(out)",
|
||||
`,
|
||||
expect: "cat ${in} > __SBOX_OUT_FILES__",
|
||||
expect: "cat in1 > __SBOX_OUT_DIR__/out",
|
||||
},
|
||||
{
|
||||
name: "ins",
|
||||
|
@ -250,7 +250,7 @@ func TestGenruleCmd(t *testing.T) {
|
|||
out: ["out"],
|
||||
cmd: "cat $(in) > $(out)",
|
||||
`,
|
||||
expect: "cat ${in} > __SBOX_OUT_FILES__",
|
||||
expect: "cat in1 in2 > __SBOX_OUT_DIR__/out",
|
||||
},
|
||||
{
|
||||
name: "ins fg",
|
||||
|
@ -259,7 +259,7 @@ func TestGenruleCmd(t *testing.T) {
|
|||
out: ["out"],
|
||||
cmd: "cat $(in) > $(out)",
|
||||
`,
|
||||
expect: "cat ${in} > __SBOX_OUT_FILES__",
|
||||
expect: "cat in1 in2 > __SBOX_OUT_DIR__/out",
|
||||
},
|
||||
{
|
||||
name: "location in1",
|
||||
|
@ -268,7 +268,7 @@ func TestGenruleCmd(t *testing.T) {
|
|||
out: ["out"],
|
||||
cmd: "cat $(location in1) > $(out)",
|
||||
`,
|
||||
expect: "cat in1 > __SBOX_OUT_FILES__",
|
||||
expect: "cat in1 > __SBOX_OUT_DIR__/out",
|
||||
},
|
||||
{
|
||||
name: "location in1 fg",
|
||||
|
@ -277,7 +277,7 @@ func TestGenruleCmd(t *testing.T) {
|
|||
out: ["out"],
|
||||
cmd: "cat $(location :1in) > $(out)",
|
||||
`,
|
||||
expect: "cat in1 > __SBOX_OUT_FILES__",
|
||||
expect: "cat in1 > __SBOX_OUT_DIR__/out",
|
||||
},
|
||||
{
|
||||
name: "location ins",
|
||||
|
@ -286,7 +286,7 @@ func TestGenruleCmd(t *testing.T) {
|
|||
out: ["out"],
|
||||
cmd: "cat $(location in1) > $(out)",
|
||||
`,
|
||||
expect: "cat in1 > __SBOX_OUT_FILES__",
|
||||
expect: "cat in1 > __SBOX_OUT_DIR__/out",
|
||||
},
|
||||
{
|
||||
name: "location ins fg",
|
||||
|
@ -295,7 +295,7 @@ func TestGenruleCmd(t *testing.T) {
|
|||
out: ["out"],
|
||||
cmd: "cat $(locations :ins) > $(out)",
|
||||
`,
|
||||
expect: "cat in1 in2 > __SBOX_OUT_FILES__",
|
||||
expect: "cat in1 in2 > __SBOX_OUT_DIR__/out",
|
||||
},
|
||||
{
|
||||
name: "outs",
|
||||
|
@ -303,7 +303,7 @@ func TestGenruleCmd(t *testing.T) {
|
|||
out: ["out", "out2"],
|
||||
cmd: "echo foo > $(out)",
|
||||
`,
|
||||
expect: "echo foo > __SBOX_OUT_FILES__",
|
||||
expect: "echo foo > __SBOX_OUT_DIR__/out __SBOX_OUT_DIR__/out2",
|
||||
},
|
||||
{
|
||||
name: "location out",
|
||||
|
@ -320,7 +320,7 @@ func TestGenruleCmd(t *testing.T) {
|
|||
depfile: true,
|
||||
cmd: "echo foo > $(out) && touch $(depfile)",
|
||||
`,
|
||||
expect: "echo foo > __SBOX_OUT_FILES__ && touch __SBOX_DEPFILE__",
|
||||
expect: "echo foo > __SBOX_OUT_DIR__/out && touch __SBOX_DEPFILE__",
|
||||
},
|
||||
{
|
||||
name: "gendir",
|
||||
|
@ -328,7 +328,7 @@ func TestGenruleCmd(t *testing.T) {
|
|||
out: ["out"],
|
||||
cmd: "echo foo > $(genDir)/foo && cp $(genDir)/foo $(out)",
|
||||
`,
|
||||
expect: "echo foo > __SBOX_OUT_DIR__/foo && cp __SBOX_OUT_DIR__/foo __SBOX_OUT_FILES__",
|
||||
expect: "echo foo > __SBOX_OUT_DIR__/foo && cp __SBOX_OUT_DIR__/foo __SBOX_OUT_DIR__/out",
|
||||
},
|
||||
|
||||
{
|
||||
|
@ -443,7 +443,7 @@ func TestGenruleCmd(t *testing.T) {
|
|||
|
||||
allowMissingDependencies: true,
|
||||
|
||||
expect: "cat ***missing srcs :missing*** > __SBOX_OUT_FILES__",
|
||||
expect: "cat ***missing srcs :missing*** > __SBOX_OUT_DIR__/out",
|
||||
},
|
||||
{
|
||||
name: "tool allow missing dependencies",
|
||||
|
@ -455,7 +455,7 @@ func TestGenruleCmd(t *testing.T) {
|
|||
|
||||
allowMissingDependencies: true,
|
||||
|
||||
expect: "***missing tool :missing*** > __SBOX_OUT_FILES__",
|
||||
expect: "***missing tool :missing*** > __SBOX_OUT_DIR__/out",
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -495,7 +495,7 @@ func TestGenruleCmd(t *testing.T) {
|
|||
}
|
||||
|
||||
gen := ctx.ModuleForTests("gen", "").Module().(*Module)
|
||||
if g, w := gen.rawCommands[0], "'"+test.expect+"'"; w != g {
|
||||
if g, w := gen.rawCommands[0], test.expect; w != g {
|
||||
t.Errorf("want %q, got %q", w, g)
|
||||
}
|
||||
})
|
||||
|
@ -542,18 +542,18 @@ func TestGenruleHashInputs(t *testing.T) {
|
|||
}{
|
||||
{
|
||||
name: "hash0",
|
||||
// sha256 value obtained from: echo -n 'in1.txtin2.txt' | sha256sum
|
||||
expectedHash: "031097e11e0a8c822c960eb9742474f46336360a515744000d086d94335a9cb9",
|
||||
// sha256 value obtained from: echo -en 'in1.txt\nin2.txt' | sha256sum
|
||||
expectedHash: "18da75b9b1cc74b09e365b4ca2e321b5d618f438cc632b387ad9dc2ab4b20e9d",
|
||||
},
|
||||
{
|
||||
name: "hash1",
|
||||
// sha256 value obtained from: echo -n 'in1.txtin2.txtin3.txt' | sha256sum
|
||||
expectedHash: "de5d22a4a7ab50d250cc59fcdf7a7e0775790d270bfca3a7a9e1f18a70dd996c",
|
||||
// sha256 value obtained from: echo -en 'in1.txt\nin2.txt\nin3.txt' | sha256sum
|
||||
expectedHash: "a38d432a4b19df93140e1f1fe26c97ff0387dae01fe506412b47208f0595fb45",
|
||||
},
|
||||
{
|
||||
name: "hash2",
|
||||
// $(in) is present, option should not appear
|
||||
expectedHash: "",
|
||||
// sha256 value obtained from: echo -en 'in1.txt\nin2.txt\nin3.txt' | sha256sum
|
||||
expectedHash: "a38d432a4b19df93140e1f1fe26c97ff0387dae01fe506412b47208f0595fb45",
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -575,7 +575,7 @@ func TestGenruleHashInputs(t *testing.T) {
|
|||
if len(test.expectedHash) > 0 {
|
||||
// We add spaces before and after to make sure that
|
||||
// this option doesn't abutt another sbox option.
|
||||
expectedInputHashOption := " --input-hash " + test.expectedHash + " "
|
||||
expectedInputHashOption := " --input-hash " + test.expectedHash
|
||||
|
||||
if !strings.Contains(command, expectedInputHashOption) {
|
||||
t.Errorf("Expected command \"%s\" to contain \"%s\"", command, expectedInputHashOption)
|
||||
|
@ -609,7 +609,7 @@ func TestGenSrcs(t *testing.T) {
|
|||
cmd: "$(location) $(in) > $(out)",
|
||||
`,
|
||||
cmds: []string{
|
||||
"'bash -c '\\''out/tool in1.txt > __SBOX_OUT_DIR__/in1.h'\\'' && bash -c '\\''out/tool in2.txt > __SBOX_OUT_DIR__/in2.h'\\'''",
|
||||
"bash -c 'out/tool in1.txt > __SBOX_OUT_DIR__/in1.h' && bash -c 'out/tool in2.txt > __SBOX_OUT_DIR__/in2.h'",
|
||||
},
|
||||
deps: []string{buildDir + "/.intermediates/gen/gen/gensrcs/in1.h", buildDir + "/.intermediates/gen/gen/gensrcs/in2.h"},
|
||||
files: []string{buildDir + "/.intermediates/gen/gen/gensrcs/in1.h", buildDir + "/.intermediates/gen/gen/gensrcs/in2.h"},
|
||||
|
@ -623,8 +623,8 @@ func TestGenSrcs(t *testing.T) {
|
|||
shard_size: 2,
|
||||
`,
|
||||
cmds: []string{
|
||||
"'bash -c '\\''out/tool in1.txt > __SBOX_OUT_DIR__/in1.h'\\'' && bash -c '\\''out/tool in2.txt > __SBOX_OUT_DIR__/in2.h'\\'''",
|
||||
"'bash -c '\\''out/tool in3.txt > __SBOX_OUT_DIR__/in3.h'\\'''",
|
||||
"bash -c 'out/tool in1.txt > __SBOX_OUT_DIR__/in1.h' && bash -c 'out/tool in2.txt > __SBOX_OUT_DIR__/in2.h'",
|
||||
"bash -c 'out/tool in3.txt > __SBOX_OUT_DIR__/in3.h'",
|
||||
},
|
||||
deps: []string{buildDir + "/.intermediates/gen/gen/gensrcs/in1.h", buildDir + "/.intermediates/gen/gen/gensrcs/in2.h", buildDir + "/.intermediates/gen/gen/gensrcs/in3.h"},
|
||||
files: []string{buildDir + "/.intermediates/gen/gen/gensrcs/in1.h", buildDir + "/.intermediates/gen/gen/gensrcs/in2.h", buildDir + "/.intermediates/gen/gen/gensrcs/in3.h"},
|
||||
|
@ -710,7 +710,7 @@ func TestGenruleDefaults(t *testing.T) {
|
|||
}
|
||||
gen := ctx.ModuleForTests("gen", "").Module().(*Module)
|
||||
|
||||
expectedCmd := "'cp ${in} __SBOX_OUT_FILES__'"
|
||||
expectedCmd := "cp in1 __SBOX_OUT_DIR__/out"
|
||||
if gen.rawCommands[0] != expectedCmd {
|
||||
t.Errorf("Expected cmd: %q, actual: %q", expectedCmd, gen.rawCommands[0])
|
||||
}
|
||||
|
|
|
@ -1379,8 +1379,8 @@ func TestJarGenrules(t *testing.T) {
|
|||
baz := ctx.ModuleForTests("baz", "android_common").Output("javac/baz.jar")
|
||||
barCombined := ctx.ModuleForTests("bar", "android_common").Output("combined/bar.jar")
|
||||
|
||||
if len(jargen.Inputs) != 1 || jargen.Inputs[0].String() != foo.Output.String() {
|
||||
t.Errorf("expected jargen inputs [%q], got %q", foo.Output.String(), jargen.Inputs.Strings())
|
||||
if g, w := jargen.Implicits.Strings(), foo.Output.String(); !android.InList(w, g) {
|
||||
t.Errorf("expected jargen inputs [%q], got %q", w, g)
|
||||
}
|
||||
|
||||
if !strings.Contains(bar.Args["classpath"], jargen.Output.String()) {
|
||||
|
|
Loading…
Reference in a new issue