aboutsummaryrefslogtreecommitdiffstats
path: root/genrule
diff options
context:
space:
mode:
authorJeff Gaston <jeffrygaston@google.com>2017-03-29 17:29:06 -0700
committerJeff Gaston <jeffrygaston@google.com>2017-06-09 17:57:18 +0000
commitefc1b412f199bbbe2474d4c5396dc4b39a6beff7 (patch)
treec324ef0de2b4a59c76b5c78637852f567be0038b /genrule
parent6b78fa8c012d3e84684d458f3271e91f0312423f (diff)
downloadbuild_soong-efc1b412f199bbbe2474d4c5396dc4b39a6beff7.tar.gz
build_soong-efc1b412f199bbbe2474d4c5396dc4b39a6beff7.tar.bz2
build_soong-efc1b412f199bbbe2474d4c5396dc4b39a6beff7.zip
Have Soong try to enforce that genrules declare all their outputs.
This causes Soong to put the outputs of each genrule into a temporary location and copy the declared outputs back to the output directory. This gets the process closer to having an actual sandbox. Bug: 35562758 Test: make Change-Id: I8048fbf1a3899a86fb99d71b60669b6633b07b3e
Diffstat (limited to 'genrule')
-rw-r--r--genrule/genrule.go46
1 files changed, 38 insertions, 8 deletions
diff --git a/genrule/genrule.go b/genrule/genrule.go
index 2ff018f5..b98ccfdb 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -16,11 +16,14 @@ package genrule
import (
"fmt"
+ "path"
"strings"
"github.com/google/blueprint"
"android/soong/android"
+ "android/soong/shared"
+ "path/filepath"
)
func init() {
@@ -32,6 +35,10 @@ var (
pctx = android.NewPackageContext("android/soong/genrule")
)
+func init() {
+ pctx.HostBinToolVariable("sboxCmd", "sbox")
+}
+
type SourceFileGenerator interface {
GeneratedSourceFiles() android.Paths
GeneratedHeaderDirs() android.Paths
@@ -42,7 +49,11 @@ type HostToolProvider interface {
}
type generatorProperties struct {
- // command to run on one or more input files. Available variables for substitution:
+ // The command to run on one or more input files. Cmd supports substitution of a few variables
+ // (the actual substitution is implemented in GenerateAndroidBuildActions below)
+ //
+ // Available variables for substitution:
+ //
// $(location): the path to the first entry in tools or tool_files
// $(location <label>): the path to the tool or tool_file with name <label>
// $(in): one or more input files
@@ -51,9 +62,8 @@ type generatorProperties struct {
// $(genDir): the sandbox directory for this tool; contains $(out)
// $$: a literal $
//
- // DO NOT directly reference paths to files in the source tree, or the
- // command will be missing proper dependencies to re-run if the files
- // change.
+ // All files used must be declared as inputs (to ensure proper up-to-date checks).
+ // Use "$(in)" directly in Cmd to ensure that all inputs used are declared.
Cmd string
// Enable reading a file containing dependencies in gcc format after the command completes
@@ -164,7 +174,7 @@ func (g *generator) GenerateAndroidBuildActions(ctx android.ModuleContext) {
}
}
- cmd, err := android.Expand(g.properties.Cmd, func(name string) (string, error) {
+ rawCommand, err := android.Expand(g.properties.Cmd, func(name string) (string, error) {
switch name {
case "location":
if len(g.properties.Tools) > 0 {
@@ -175,14 +185,26 @@ func (g *generator) GenerateAndroidBuildActions(ctx android.ModuleContext) {
case "in":
return "${in}", nil
case "out":
- return "${out}", nil
+ return "__SBOX_OUT_FILES__", nil
case "depfile":
if !g.properties.Depfile {
return "", fmt.Errorf("$(depfile) used without depfile property")
}
return "${depfile}", nil
case "genDir":
- return android.PathForModuleGen(ctx, "").String(), nil
+ genPath := android.PathForModuleGen(ctx, "").String()
+ var relativePath string
+ if path.IsAbs(genPath) {
+ var err error
+ outputPath := android.PathForOutput(ctx).String()
+ relativePath, err = filepath.Rel(genPath, outputPath)
+ if err != nil {
+ panic(err)
+ }
+ } else {
+ relativePath = genPath
+ }
+ return path.Join("__SBOX_OUT_DIR__", relativePath), nil
default:
if strings.HasPrefix(name, "location ") {
label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
@@ -201,8 +223,16 @@ func (g *generator) GenerateAndroidBuildActions(ctx android.ModuleContext) {
return
}
+ // tell the sbox command which directory to use as its sandbox root
+ sandboxPath := shared.TempDirForOutDir(android.PathForOutput(ctx).String())
+
+ // recall that Sprintf replaces percent sign expressions, whereas dollar signs expressions remain as written,
+ // to be replaced later by ninja_strings.go
+ sandboxCommand := fmt.Sprintf("$sboxCmd --sandbox-path %s -c %q $out", sandboxPath, rawCommand)
+
ruleParams := blueprint.RuleParams{
- Command: cmd,
+ Command: sandboxCommand,
+ CommandDeps: []string{"$sboxCmd"},
}
var args []string
if g.properties.Depfile {