diff options
-rw-r--r-- | cmd/sbox/sbox.go | 28 | ||||
-rw-r--r-- | genrule/genrule.go | 82 |
2 files changed, 80 insertions, 30 deletions
diff --git a/cmd/sbox/sbox.go b/cmd/sbox/sbox.go index 4b008eb8..558bc3fb 100644 --- a/cmd/sbox/sbox.go +++ b/cmd/sbox/sbox.go @@ -45,6 +45,7 @@ func init() { flag.StringVar(&depfileOut, "depfile-out", "", "file path of the depfile to generate. This value will replace '__SBOX_DEPFILE__' in the command and will be treated as an output but won't be added to __SBOX_OUT_FILES__") + } func usageViolation(violation string) { @@ -53,10 +54,11 @@ func usageViolation(violation string) { } fmt.Fprintf(os.Stderr, - "Usage: sbox -c <commandToRun> --sandbox-path <sandboxPath> --output-root <outputRoot> [--depfile-out depFile] <outputFile> [<outputFile>...]\n"+ + "Usage: sbox -c <commandToRun> --sandbox-path <sandboxPath> --output-root <outputRoot> --overwrite [--depfile-out depFile] <outputFile> [<outputFile>...]\n"+ "\n"+ - "Runs <commandToRun> and moves each <outputFile> out of <sandboxPath>\n"+ - "and into <outputRoot>\n") + "Deletes <outputRoot>,"+ + "runs <commandToRun>,"+ + "and moves each <outputFile> out of <sandboxPath> and into <outputRoot>\n") flag.PrintDefaults() @@ -101,7 +103,19 @@ func run() error { // all outputs var allOutputs []string - os.MkdirAll(sandboxesRoot, 0777) + // setup directories + err := os.MkdirAll(sandboxesRoot, 0777) + if err != nil { + return err + } + err = os.RemoveAll(outputRoot) + if err != nil { + return err + } + err = os.MkdirAll(outputRoot, 0777) + if err != nil { + return err + } tempDir, err := ioutil.TempDir(sandboxesRoot, "sbox") @@ -207,7 +221,11 @@ func run() error { if len(outputRoot) != 0 { destPath = filepath.Join(outputRoot, filePath) } - err := os.Rename(tempPath, destPath) + err := os.MkdirAll(filepath.Dir(destPath), 0777) + if err != nil { + return err + } + err = os.Rename(tempPath, destPath) if err != nil { return err } diff --git a/genrule/genrule.go b/genrule/genrule.go index cffbf738..b26b1a21 100644 --- a/genrule/genrule.go +++ b/genrule/genrule.go @@ -24,6 +24,8 @@ import ( "android/soong/android" "android/soong/shared" "path/filepath" + + "github.com/google/blueprint/proptools" ) func init() { @@ -98,7 +100,7 @@ type Module struct { properties generatorProperties - tasks taskFunc + taskGenerator taskFunc deps android.Paths rule blueprint.Rule @@ -108,11 +110,12 @@ type Module struct { outputFiles android.Paths } -type taskFunc func(ctx android.ModuleContext, srcFiles android.Paths) []generateTask +type taskFunc func(ctx android.ModuleContext, rawCommand string, srcFiles android.Paths) generateTask type generateTask struct { in android.Paths out android.WritablePaths + cmd string } func (g *Module) GeneratedSourceFiles() android.Paths { @@ -210,9 +213,10 @@ func (g *Module) GenerateAndroidBuildActions(ctx android.ModuleContext) { referencedDepfile := false - ruleOutputDir := android.PathForModuleGen(ctx, "").String() + srcFiles := ctx.ExpandSources(g.properties.Srcs, nil) + task := g.taskGenerator(ctx, g.properties.Cmd, srcFiles) - rawCommand, err := android.Expand(g.properties.Cmd, func(name string) (string, error) { + rawCommand, err := android.Expand(task.cmd, func(name string) (string, error) { switch name { case "location": if len(g.properties.Tools) > 0 { @@ -265,7 +269,8 @@ func (g *Module) GenerateAndroidBuildActions(ctx android.ModuleContext) { depfilePlaceholder = "$depfileArgs" } - sandboxCommand := fmt.Sprintf("$sboxCmd --sandbox-path %s --output-root %s -c %q %s $allouts", sandboxPath, ruleOutputDir, rawCommand, depfilePlaceholder) + genDir := android.PathForModuleGen(ctx) + sandboxCommand := fmt.Sprintf("$sboxCmd --sandbox-path %s --output-root %s -c %q %s $allouts", sandboxPath, genDir, rawCommand, depfilePlaceholder) ruleParams := blueprint.RuleParams{ Command: sandboxCommand, @@ -278,10 +283,8 @@ func (g *Module) GenerateAndroidBuildActions(ctx android.ModuleContext) { } g.rule = ctx.Rule(pctx, "generator", ruleParams, args...) - srcFiles := ctx.ExpandSources(g.properties.Srcs, nil) - for _, task := range g.tasks(ctx, srcFiles) { - g.generateSourceFile(ctx, task) - } + g.generateSourceFile(ctx, task) + } func (g *Module) generateSourceFile(ctx android.ModuleContext, task generateTask) { @@ -322,9 +325,9 @@ func (g *Module) generateSourceFile(ctx android.ModuleContext, task generateTask } } -func generatorFactory(tasks taskFunc, props ...interface{}) *Module { +func generatorFactory(taskGenerator taskFunc, props ...interface{}) *Module { module := &Module{ - tasks: tasks, + taskGenerator: taskGenerator, } module.AddProperties(props...) @@ -336,18 +339,48 @@ func generatorFactory(tasks taskFunc, props ...interface{}) *Module { func NewGenSrcs() *Module { properties := &genSrcsProperties{} - tasks := func(ctx android.ModuleContext, srcFiles android.Paths) []generateTask { - tasks := make([]generateTask, 0, len(srcFiles)) + taskGenerator := func(ctx android.ModuleContext, rawCommand string, srcFiles android.Paths) generateTask { + commands := []string{} + outFiles := android.WritablePaths{} + genPath := android.PathForModuleGen(ctx).String() for _, in := range srcFiles { - tasks = append(tasks, generateTask{ - in: android.Paths{in}, - out: android.WritablePaths{android.GenPathWithExt(ctx, "", in, properties.Output_extension)}, + outFile := android.GenPathWithExt(ctx, "", in, properties.Output_extension) + outFiles = append(outFiles, outFile) + + // replace "out" with "__SBOX_OUT_DIR__/<the value of ${out}>" + relOut, err := filepath.Rel(genPath, outFile.String()) + if err != nil { + panic(fmt.Sprintf("Could not make ${out} relative: %v", err)) + } + sandboxOutfile := filepath.Join("__SBOX_OUT_DIR__", relOut) + command, err := android.Expand(rawCommand, func(name string) (string, error) { + switch name { + case "in": + return in.String(), nil + case "out": + return sandboxOutfile, nil + default: + return "$(" + name + ")", nil + } }) + if err != nil { + ctx.PropertyErrorf("cmd", err.Error()) + } + + // escape the command in case for example it contains '#', an odd number of '"', etc + command = fmt.Sprintf("bash -c %v", proptools.ShellEscape([]string{command})[0]) + commands = append(commands, command) + } + fullCommand := strings.Join(commands, " && ") + + return generateTask{ + in: srcFiles, + out: outFiles, + cmd: fullCommand, } - return tasks } - return generatorFactory(tasks, properties) + return generatorFactory(taskGenerator, properties) } func GenSrcsFactory() android.Module { @@ -364,20 +397,19 @@ type genSrcsProperties struct { func NewGenRule() *Module { properties := &genRuleProperties{} - tasks := func(ctx android.ModuleContext, srcFiles android.Paths) []generateTask { + taskGenerator := func(ctx android.ModuleContext, rawCommand string, srcFiles android.Paths) generateTask { outs := make(android.WritablePaths, len(properties.Out)) for i, out := range properties.Out { outs[i] = android.PathForModuleGen(ctx, out) } - return []generateTask{ - { - in: srcFiles, - out: outs, - }, + return generateTask{ + in: srcFiles, + out: outs, + cmd: rawCommand, } } - return generatorFactory(tasks, properties) + return generatorFactory(taskGenerator, properties) } func GenRuleFactory() android.Module { |