Merge changes I73abb992,Ifcd42073

* changes:
  Have sbox remove its output directory before running
  Consolidate gensrcs implementation into one task each
This commit is contained in:
Jeff Gaston 2017-11-09 00:23:37 +00:00 committed by Gerrit Code Review
commit 06643be323
2 changed files with 80 additions and 30 deletions

View file

@ -45,6 +45,7 @@ func init() {
flag.StringVar(&depfileOut, "depfile-out", "", 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__") "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) { func usageViolation(violation string) {
@ -53,10 +54,11 @@ func usageViolation(violation string) {
} }
fmt.Fprintf(os.Stderr, 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"+ "\n"+
"Runs <commandToRun> and moves each <outputFile> out of <sandboxPath>\n"+ "Deletes <outputRoot>,"+
"and into <outputRoot>\n") "runs <commandToRun>,"+
"and moves each <outputFile> out of <sandboxPath> and into <outputRoot>\n")
flag.PrintDefaults() flag.PrintDefaults()
@ -101,7 +103,19 @@ func run() error {
// all outputs // all outputs
var allOutputs []string 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") tempDir, err := ioutil.TempDir(sandboxesRoot, "sbox")
@ -207,7 +221,11 @@ func run() error {
if len(outputRoot) != 0 { if len(outputRoot) != 0 {
destPath = filepath.Join(outputRoot, filePath) 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 { if err != nil {
return err return err
} }

View file

@ -24,6 +24,8 @@ import (
"android/soong/android" "android/soong/android"
"android/soong/shared" "android/soong/shared"
"path/filepath" "path/filepath"
"github.com/google/blueprint/proptools"
) )
func init() { func init() {
@ -98,7 +100,7 @@ type Module struct {
properties generatorProperties properties generatorProperties
tasks taskFunc taskGenerator taskFunc
deps android.Paths deps android.Paths
rule blueprint.Rule rule blueprint.Rule
@ -108,11 +110,12 @@ type Module struct {
outputFiles android.Paths 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 { type generateTask struct {
in android.Paths in android.Paths
out android.WritablePaths out android.WritablePaths
cmd string
} }
func (g *Module) GeneratedSourceFiles() android.Paths { func (g *Module) GeneratedSourceFiles() android.Paths {
@ -210,9 +213,10 @@ func (g *Module) GenerateAndroidBuildActions(ctx android.ModuleContext) {
referencedDepfile := false 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 { switch name {
case "location": case "location":
if len(g.properties.Tools) > 0 { if len(g.properties.Tools) > 0 {
@ -265,7 +269,8 @@ func (g *Module) GenerateAndroidBuildActions(ctx android.ModuleContext) {
depfilePlaceholder = "$depfileArgs" 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{ ruleParams := blueprint.RuleParams{
Command: sandboxCommand, Command: sandboxCommand,
@ -278,10 +283,8 @@ func (g *Module) GenerateAndroidBuildActions(ctx android.ModuleContext) {
} }
g.rule = ctx.Rule(pctx, "generator", ruleParams, args...) g.rule = ctx.Rule(pctx, "generator", ruleParams, args...)
srcFiles := ctx.ExpandSources(g.properties.Srcs, nil) g.generateSourceFile(ctx, task)
for _, task := range g.tasks(ctx, srcFiles) {
g.generateSourceFile(ctx, task)
}
} }
func (g *Module) generateSourceFile(ctx android.ModuleContext, task generateTask) { 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{ module := &Module{
tasks: tasks, taskGenerator: taskGenerator,
} }
module.AddProperties(props...) module.AddProperties(props...)
@ -336,18 +339,48 @@ func generatorFactory(tasks taskFunc, props ...interface{}) *Module {
func NewGenSrcs() *Module { func NewGenSrcs() *Module {
properties := &genSrcsProperties{} properties := &genSrcsProperties{}
tasks := func(ctx android.ModuleContext, srcFiles android.Paths) []generateTask { taskGenerator := func(ctx android.ModuleContext, rawCommand string, srcFiles android.Paths) generateTask {
tasks := make([]generateTask, 0, len(srcFiles)) commands := []string{}
outFiles := android.WritablePaths{}
genPath := android.PathForModuleGen(ctx).String()
for _, in := range srcFiles { for _, in := range srcFiles {
tasks = append(tasks, generateTask{ outFile := android.GenPathWithExt(ctx, "", in, properties.Output_extension)
in: android.Paths{in}, outFiles = append(outFiles, outFile)
out: android.WritablePaths{android.GenPathWithExt(ctx, "", in, properties.Output_extension)},
// 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 { func GenSrcsFactory() android.Module {
@ -364,20 +397,19 @@ type genSrcsProperties struct {
func NewGenRule() *Module { func NewGenRule() *Module {
properties := &genRuleProperties{} 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)) outs := make(android.WritablePaths, len(properties.Out))
for i, out := range properties.Out { for i, out := range properties.Out {
outs[i] = android.PathForModuleGen(ctx, out) outs[i] = android.PathForModuleGen(ctx, out)
} }
return []generateTask{ return generateTask{
{ in: srcFiles,
in: srcFiles, out: outs,
out: outs, cmd: rawCommand,
},
} }
} }
return generatorFactory(tasks, properties) return generatorFactory(taskGenerator, properties)
} }
func GenRuleFactory() android.Module { func GenRuleFactory() android.Module {