Merge changes from topic "buildnumberfromfile"

* changes:
  Allow jar wrapper to take quoted arguments
  Add rspfile support to RuleBuilder
  Prepare droiddoc for using RuleBuilder
  Manually escape BuildNumberFromFile
  Fix android.Expand and ninja escaping
  Add RuleBuilder helper functions for built and prebuilt tools
  Add documentation to droiddoc.go module types
This commit is contained in:
Colin Cross
2019-07-17 02:45:03 +00:00
committed by Gerrit Code Review
16 changed files with 383 additions and 106 deletions

View File

@@ -18,12 +18,30 @@ import (
"fmt"
"strings"
"unicode"
"github.com/google/blueprint/proptools"
)
// ExpandNinjaEscaped substitutes $() variables in a string
// $(var) is passed to mapping(var), which should return the expanded value, a bool for whether the result should
// be left unescaped when using in a ninja value (generally false, true if the expanded value is a ninja variable like
// '${in}'), and an error.
// $$ is converted to $, which is escaped back to $$.
func ExpandNinjaEscaped(s string, mapping func(string) (string, bool, error)) (string, error) {
return expand(s, true, mapping)
}
// Expand substitutes $() variables in a string
// $(var) is passed to Expander(var)
// $$ is converted to $
// $(var) is passed to mapping(var), which should return the expanded value and an error.
// $$ is converted to $.
func Expand(s string, mapping func(string) (string, error)) (string, error) {
return expand(s, false, func(s string) (string, bool, error) {
s, err := mapping(s)
return s, false, err
})
}
func expand(s string, ninjaEscape bool, mapping func(string) (string, bool, error)) (string, error) {
// based on os.Expand
buf := make([]byte, 0, 2*len(s))
i := 0
@@ -33,10 +51,13 @@ func Expand(s string, mapping func(string) (string, error)) (string, error) {
return "", fmt.Errorf("expected character after '$'")
}
buf = append(buf, s[i:j]...)
value, w, err := getMapping(s[j+1:], mapping)
value, ninjaVariable, w, err := getMapping(s[j+1:], mapping)
if err != nil {
return "", err
}
if !ninjaVariable && ninjaEscape {
value = proptools.NinjaEscape(value)
}
buf = append(buf, value...)
j += w
i = j + 1
@@ -45,26 +66,26 @@ func Expand(s string, mapping func(string) (string, error)) (string, error) {
return string(buf) + s[i:], nil
}
func getMapping(s string, mapping func(string) (string, error)) (string, int, error) {
func getMapping(s string, mapping func(string) (string, bool, error)) (string, bool, int, error) {
switch s[0] {
case '(':
// Scan to closing brace
for i := 1; i < len(s); i++ {
if s[i] == ')' {
ret, err := mapping(strings.TrimSpace(s[1:i]))
return ret, i + 1, err
ret, ninjaVariable, err := mapping(strings.TrimSpace(s[1:i]))
return ret, ninjaVariable, i + 1, err
}
}
return "", len(s), fmt.Errorf("missing )")
return "", false, len(s), fmt.Errorf("missing )")
case '$':
return "$$", 1, nil
return "$", false, 1, nil
default:
i := strings.IndexFunc(s, unicode.IsSpace)
if i == 0 {
return "", 0, fmt.Errorf("unexpected character '%c' after '$'", s[0])
return "", false, 0, fmt.Errorf("unexpected character '%c' after '$'", s[0])
} else if i == -1 {
i = len(s)
}
return "", 0, fmt.Errorf("expected '(' after '$', did you mean $(%s)?", s[:i])
return "", false, 0, fmt.Errorf("expected '(' after '$', did you mean $(%s)?", s[:i])
}
}

View File

@@ -20,88 +20,111 @@ import (
)
var vars = map[string]string{
"var1": "abc",
"var2": "",
"var3": "def",
"💩": "😃",
"var1": "abc",
"var2": "",
"var3": "def",
"💩": "😃",
"escape": "${in}",
}
func expander(s string) (string, error) {
func expander(s string) (string, bool, error) {
if val, ok := vars[s]; ok {
return val, nil
return val, s == "escape", nil
} else {
return "", fmt.Errorf("unknown variable %q", s)
return "", false, fmt.Errorf("unknown variable %q", s)
}
}
var expandTestCases = []struct {
in string
out string
err bool
in string
out string
out_escaped string
err bool
}{
{
in: "$(var1)",
out: "abc",
in: "$(var1)",
out: "abc",
out_escaped: "abc",
},
{
in: "$( var1 )",
out: "abc",
in: "$( var1 )",
out: "abc",
out_escaped: "abc",
},
{
in: "def$(var1)",
out: "defabc",
in: "def$(var1)",
out: "defabc",
out_escaped: "defabc",
},
{
in: "$(var1)def",
out: "abcdef",
in: "$(var1)def",
out: "abcdef",
out_escaped: "abcdef",
},
{
in: "def$(var1)def",
out: "defabcdef",
in: "def$(var1)def",
out: "defabcdef",
out_escaped: "defabcdef",
},
{
in: "$(var2)",
out: "",
in: "$(var2)",
out: "",
out_escaped: "",
},
{
in: "def$(var2)",
out: "def",
in: "def$(var2)",
out: "def",
out_escaped: "def",
},
{
in: "$(var2)def",
out: "def",
in: "$(var2)def",
out: "def",
out_escaped: "def",
},
{
in: "def$(var2)def",
out: "defdef",
in: "def$(var2)def",
out: "defdef",
out_escaped: "defdef",
},
{
in: "$(var1)$(var3)",
out: "abcdef",
in: "$(var1)$(var3)",
out: "abcdef",
out_escaped: "abcdef",
},
{
in: "$(var1)g$(var3)",
out: "abcgdef",
in: "$(var1)g$(var3)",
out: "abcgdef",
out_escaped: "abcgdef",
},
{
in: "$$",
out: "$$",
in: "$$",
out: "$",
out_escaped: "$$",
},
{
in: "$$(var1)",
out: "$$(var1)",
in: "$$(var1)",
out: "$(var1)",
out_escaped: "$$(var1)",
},
{
in: "$$$(var1)",
out: "$$abc",
in: "$$$(var1)",
out: "$abc",
out_escaped: "$$abc",
},
{
in: "$(var1)$$",
out: "abc$$",
in: "$(var1)$$",
out: "abc$",
out_escaped: "abc$$",
},
{
in: "$(💩)",
out: "😃",
in: "$(💩)",
out: "😃",
out_escaped: "😃",
},
{
in: "$$a$(escape)$$b",
out: "$a${in}$b",
out_escaped: "$$a${in}$$b",
},
// Errors
@@ -141,7 +164,10 @@ var expandTestCases = []struct {
func TestExpand(t *testing.T) {
for _, test := range expandTestCases {
got, err := Expand(test.in, expander)
got, err := Expand(test.in, func(s string) (string, error) {
s, _, err := expander(s)
return s, err
})
if err != nil && !test.err {
t.Errorf("%q: unexpected error %s", test.in, err.Error())
} else if err == nil && test.err {
@@ -151,3 +177,16 @@ func TestExpand(t *testing.T) {
}
}
}
func TestExpandNinjaEscaped(t *testing.T) {
for _, test := range expandTestCases {
got, err := ExpandNinjaEscaped(test.in, expander)
if err != nil && !test.err {
t.Errorf("%q: unexpected error %s", test.in, err.Error())
} else if err == nil && test.err {
t.Errorf("%q: expected error, got %q", test.in, got)
} else if !test.err && got != test.out_escaped {
t.Errorf("%q: expected %q, got %q", test.in, test.out, got)
}
}
}

View File

@@ -135,7 +135,7 @@ func ProtoRule(ctx ModuleContext, rule *RuleBuilder, protoFile Path, flags Proto
}
rule.Command().
Tool(ctx.Config().HostToolPath(ctx, "aprotoc")).
BuiltTool(ctx, "aprotoc").
FlagWithArg(flags.OutTypeFlag+"=", strings.Join(flags.OutParams, ",")+":"+outDir.String()).
FlagWithDepFile("--dependency_out=", depFile).
FlagWithArg("-I ", protoBase).
@@ -145,5 +145,5 @@ func ProtoRule(ctx ModuleContext, rule *RuleBuilder, protoFile Path, flags Proto
ImplicitOutputs(outputs)
rule.Command().
Tool(ctx.Config().HostToolPath(ctx, "dep_fixer")).Flag(depFile.String())
BuiltTool(ctx, "dep_fixer").Flag(depFile.String())
}

View File

@@ -263,11 +263,36 @@ func (r *RuleBuilder) Tools() Paths {
return toolsList
}
// Commands returns a slice containing a the built command line for each call to RuleBuilder.Command.
// RspFileInputs returns the list of paths that were passed to the RuleBuilderCommand.FlagWithRspFileInputList method.
func (r *RuleBuilder) RspFileInputs() Paths {
var rspFileInputs Paths
for _, c := range r.commands {
if c.rspFileInputs != nil {
if rspFileInputs != nil {
panic("Multiple commands in a rule may not have rsp file inputs")
}
rspFileInputs = c.rspFileInputs
}
}
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
for _, c := range r.commands {
commands = append(commands, c.buf.String())
commands = append(commands, c.String())
}
return commands
}
// NinjaEscapedCommands returns a slice containin the built command line after ninja escaping for each call to
// RuleBuilder.Command.
func (r *RuleBuilder) NinjaEscapedCommands() []string {
var commands []string
for _, c := range r.commands {
commands = append(commands, c.NinjaEscapedString())
}
return commands
}
@@ -284,7 +309,7 @@ var _ BuilderContext = SingletonContext(nil)
func (r *RuleBuilder) depFileMergerCmd(ctx PathContext, depFiles WritablePaths) *RuleBuilderCommand {
return r.Command().
Tool(ctx.Config().HostToolPath(ctx, "dep_fixer")).
BuiltTool(ctx, "dep_fixer").
Inputs(depFiles.Paths())
}
@@ -324,7 +349,7 @@ func (r *RuleBuilder) Build(pctx PackageContext, ctx BuilderContext, name string
}
tools := r.Tools()
commands := r.Commands()
commands := r.NinjaEscapedCommands()
outputs := r.Outputs()
if len(commands) == 0 {
@@ -334,7 +359,7 @@ func (r *RuleBuilder) Build(pctx PackageContext, ctx BuilderContext, name string
panic("No outputs specified from any Commands")
}
commandString := strings.Join(proptools.NinjaEscapeList(commands), " && ")
commandString := strings.Join(commands, " && ")
if r.sbox {
sboxOutputs := make([]string, len(outputs))
@@ -352,7 +377,7 @@ func (r *RuleBuilder) Build(pctx PackageContext, ctx BuilderContext, name string
}
sboxCmd := &RuleBuilderCommand{}
sboxCmd.Tool(ctx.Config().HostToolPath(ctx, "sbox")).
sboxCmd.BuiltTool(ctx, "sbox").
Flag("-c").Text(commandString).
Flag("--sandbox-path").Text(shared.TempDirForOutDir(PathForOutput(ctx).String())).
Flag("--output-root").Text(r.sboxOutDir.String()).
@@ -363,17 +388,27 @@ func (r *RuleBuilder) Build(pctx PackageContext, ctx BuilderContext, name string
}
// Ninja doesn't like multiple outputs when depfiles are enabled, move all but the first output to
// ImplicitOutputs. RuleBuilder never uses "$out", so the distinction between Outputs and ImplicitOutputs
// doesn't matter.
// ImplicitOutputs. RuleBuilder only uses "$out" for the rsp file location, 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"
rspFileContent = "$in"
}
ctx.Build(pctx, BuildParams{
Rule: ctx.Rule(pctx, name, blueprint.RuleParams{
Command: commandString,
CommandDeps: tools.Strings(),
Restat: r.restat,
Command: commandString,
CommandDeps: tools.Strings(),
Restat: r.restat,
Rspfile: rspFile,
RspfileContent: rspFileContent,
}),
Inputs: rspFileInputs,
Implicits: r.Inputs(),
Output: output,
ImplicitOutputs: implicitOutputs,
@@ -388,11 +423,15 @@ func (r *RuleBuilder) Build(pctx PackageContext, ctx BuilderContext, name string
// RuleBuilderCommand, so they can be used chained or unchained. All methods that add text implicitly add a single
// space as a separator from the previous method.
type RuleBuilderCommand struct {
buf strings.Builder
inputs Paths
outputs WritablePaths
depFiles WritablePaths
tools Paths
buf strings.Builder
inputs Paths
outputs WritablePaths
depFiles WritablePaths
tools Paths
rspFileInputs Paths
// spans [start,end) of the command that should not be ninja escaped
unescapedSpans [][2]int
sbox bool
sboxOutDir WritablePath
@@ -478,6 +517,24 @@ func (c *RuleBuilderCommand) Tool(path Path) *RuleBuilderCommand {
return c.Text(path.String())
}
// BuiltTool adds the specified tool path that was built using a host Soong module to the command line. The path will
// be also added to the dependencies returned by RuleBuilder.Tools.
//
// It is equivalent to:
// cmd.Tool(ctx.Config().HostToolPath(ctx, tool))
func (c *RuleBuilderCommand) BuiltTool(ctx PathContext, tool string) *RuleBuilderCommand {
return c.Tool(ctx.Config().HostToolPath(ctx, tool))
}
// PrebuiltBuildTool adds the specified tool path from prebuils/build-tools. The path will be also added to the
// dependencies returned by RuleBuilder.Tools.
//
// It is equivalent to:
// cmd.Tool(ctx.Config().PrebuiltBuildTool(ctx, tool))
func (c *RuleBuilderCommand) PrebuiltBuildTool(ctx PathContext, tool string) *RuleBuilderCommand {
return c.Tool(ctx.Config().PrebuiltBuildTool(ctx, tool))
}
// Input adds the specified input path to the command line. The path will also be added to the dependencies returned by
// RuleBuilder.Inputs.
func (c *RuleBuilderCommand) Input(path Path) *RuleBuilderCommand {
@@ -606,11 +663,56 @@ func (c *RuleBuilderCommand) FlagWithDepFile(flag string, path WritablePath) *Ru
return c.Text(flag + c.outputStr(path))
}
// 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 {
if c.rspFileInputs != nil {
panic("FlagWithRspFileInputList cannot be called if rsp file inputs have already been provided")
}
// Use an empty slice if paths is nil, the non-nil slice is used as an indicator that the rsp file must be
// generated.
if paths == nil {
paths = Paths{}
}
c.rspFileInputs = paths
rspFile := "$out.rsp"
c.FlagWithArg(flag, rspFile)
c.unescapedSpans = append(c.unescapedSpans, [2]int{c.buf.Len() - len(rspFile), c.buf.Len()})
return c
}
// String returns the command line.
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)
}
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

View File

@@ -38,6 +38,7 @@ func pathContext() PathContext {
"ls": nil,
"turbine": nil,
"java": nil,
"javac": nil,
})
}
@@ -235,6 +236,34 @@ func ExampleRuleBuilderCommand_FlagWithList() {
// ls --sort=time,size
}
func ExampleRuleBuilderCommand_FlagWithRspFileInputList() {
ctx := pathContext()
fmt.Println(NewRuleBuilder().Command().
Tool(PathForSource(ctx, "javac")).
FlagWithRspFileInputList("@", PathsForTesting("a.java", "b.java")).
NinjaEscapedString())
// Output:
// javac @$out.rsp
}
func ExampleRuleBuilderCommand_String() {
fmt.Println(NewRuleBuilder().Command().
Text("FOO=foo").
Text("echo $FOO").
String())
// Output:
// FOO=foo echo $FOO
}
func ExampleRuleBuilderCommand_NinjaEscapedString() {
fmt.Println(NewRuleBuilder().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,
@@ -503,3 +532,77 @@ func TestRuleBuilder_Build(t *testing.T) {
"cp bar "+outFile, outFile, outFile+".d", true, nil)
})
}
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)
}
})
}
}

View File

@@ -99,7 +99,7 @@ func genYacc(ctx android.ModuleContext, rule *android.RuleBuilder, yaccFile andr
cmd.Text("BISON_PKGDATADIR=prebuilts/build-tools/common/bison").
FlagWithInput("M4=", ctx.Config().PrebuiltBuildTool(ctx, "m4")).
Tool(ctx.Config().PrebuiltBuildTool(ctx, "bison")).
PrebuiltBuildTool(ctx, "bison").
Flag("-d").
Flags(flags).
FlagWithOutput("--defines=", headerFile).
@@ -121,7 +121,7 @@ func genAidl(ctx android.ModuleContext, rule *android.RuleBuilder, aidlFile andr
headerBp := outDir.Join(ctx, aidlPackage, "Bp"+shortName+".h")
cmd := rule.Command()
cmd.Tool(ctx.Config().HostToolPath(ctx, "aidl-cpp")).
cmd.BuiltTool(ctx, "aidl-cpp").
FlagWithDepFile("-d", depFile).
Flag("--ninja").
Flag(aidlFlags).

View File

@@ -483,7 +483,7 @@ func (linker *baseLinker) injectVersionSymbol(ctx ModuleContext, in android.Path
Input: in,
Output: out,
Args: map[string]string{
"buildNumberFromFile": ctx.Config().BuildNumberFromFile(),
"buildNumberFromFile": proptools.NinjaEscape(ctx.Config().BuildNumberFromFile()),
},
})
}

View File

@@ -284,12 +284,12 @@ func (g *Module) GenerateAndroidBuildActions(ctx android.ModuleContext) {
referencedDepfile := false
rawCommand, err := android.Expand(task.cmd, func(name string) (string, error) {
rawCommand, err := android.ExpandNinjaEscaped(task.cmd, func(name string) (string, bool, 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, error) {
reportError := func(fmt string, args ...interface{}) (string, bool, error) {
ctx.PropertyErrorf("cmd", fmt, args...)
return "SOONG_ERROR", nil
return "SOONG_ERROR", false, nil
}
switch name {
@@ -304,19 +304,19 @@ 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], nil
return locationLabels[firstLabel][0], false, nil
case "in":
return "${in}", nil
return "${in}", true, nil
case "out":
return "__SBOX_OUT_FILES__", nil
return "__SBOX_OUT_FILES__", false, nil
case "depfile":
referencedDepfile = true
if !Bool(g.properties.Depfile) {
return reportError("$(depfile) used without depfile property")
}
return "__SBOX_DEPFILE__", nil
return "__SBOX_DEPFILE__", false, nil
case "genDir":
return "__SBOX_OUT_DIR__", nil
return "__SBOX_OUT_DIR__", false, nil
default:
if strings.HasPrefix(name, "location ") {
label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
@@ -327,7 +327,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], nil
return paths[0], false, nil
} else {
return reportError("unknown location label %q", label)
}
@@ -337,7 +337,7 @@ func (g *Module) GenerateAndroidBuildActions(ctx android.ModuleContext) {
if len(paths) == 0 {
return reportError("label %q has no files", label)
}
return strings.Join(paths, " "), nil
return strings.Join(paths, " "), false, nil
} else {
return reportError("unknown locations label %q", label)
}

View File

@@ -816,7 +816,7 @@ func (a *AndroidAppImport) uncompressEmbeddedJniLibs(
rule := android.NewRuleBuilder()
rule.Command().
Textf(`if (zipinfo %s 'lib/*.so' 2>/dev/null | grep -v ' stor ' >/dev/null) ; then`, inputPath).
Tool(ctx.Config().HostToolPath(ctx, "zip2zip")).
BuiltTool(ctx, "zip2zip").
FlagWithInput("-i ", inputPath).
FlagWithOutput("-o ", outputPath).
FlagWithArg("-0 ", "'lib/**/*.so'").
@@ -843,7 +843,7 @@ func (a *AndroidAppImport) uncompressDex(
rule := android.NewRuleBuilder()
rule.Command().
Textf(`if (zipinfo %s '*.dex' 2>/dev/null | grep -v ' stor ' >/dev/null) ; then`, inputPath).
Tool(ctx.Config().HostToolPath(ctx, "zip2zip")).
BuiltTool(ctx, "zip2zip").
FlagWithInput("-i ", inputPath).
FlagWithOutput("-o ", outputPath).
FlagWithArg("-0 ", "'classes*.dex'").
@@ -1067,7 +1067,7 @@ func (u *usesLibrary) verifyUsesLibrariesManifest(ctx android.ModuleContext, man
outputFile := android.PathForModuleOut(ctx, "manifest_check", "AndroidManifest.xml")
rule := android.NewRuleBuilder()
cmd := rule.Command().Tool(ctx.Config().HostToolPath(ctx, "manifest_check")).
cmd := rule.Command().BuiltTool(ctx, "manifest_check").
Flag("--enforce-uses-libraries").
Input(manifest).
FlagWithOutput("-o ", outputFile)

View File

@@ -229,7 +229,7 @@ func buildBootImage(ctx android.SingletonContext, config bootImageConfig) *bootI
if image.zip != nil {
rule := android.NewRuleBuilder()
rule.Command().
Tool(ctx.Config().HostToolPath(ctx, "soong_zip")).
BuiltTool(ctx, "soong_zip").
FlagWithOutput("-o ", image.zip).
FlagWithArg("-C ", image.dir.String()).
FlagWithInputList("-f ", allFiles, " -f ")
@@ -438,7 +438,7 @@ func dumpOatRules(ctx android.SingletonContext, image *bootImage) {
rule := android.NewRuleBuilder()
rule.Command().
// TODO: for now, use the debug version for better error reporting
Tool(ctx.Config().HostToolPath(ctx, "oatdumpd")).
BuiltTool(ctx, "oatdumpd").
FlagWithInputList("--runtime-arg -Xbootclasspath:", image.dexPaths.Paths(), ":").
FlagWithList("--runtime-arg -Xbootclasspath-locations:", image.dexLocations, ":").
FlagWithArg("--image=", dexpreopt.PathToLocation(image.images[arch], arch)).Implicit(image.images[arch]).

View File

@@ -500,6 +500,7 @@ func (j *Javadoc) OutputFiles(tag string) (android.Paths, error) {
}
}
// javadoc converts .java source files to documentation using javadoc.
func JavadocFactory() android.Module {
module := &Javadoc{}
@@ -509,6 +510,7 @@ func JavadocFactory() android.Module {
return module
}
// javadoc_host converts .java source files to documentation using javadoc.
func JavadocHostFactory() android.Module {
module := &Javadoc{}
@@ -798,7 +800,7 @@ func (j *Javadoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
"srcJarDir": android.PathForModuleOut(ctx, "srcjars").String(),
"stubsDir": android.PathForModuleOut(ctx, "stubsDir").String(),
"srcJars": strings.Join(j.srcJars.Strings(), " "),
"opts": opts,
"opts": proptools.NinjaEscape(opts),
"bootclasspathArgs": bootClasspathArgs,
"classpathArgs": classpathArgs,
"sourcepathArgs": sourcepathArgs,
@@ -831,6 +833,7 @@ type Droiddoc struct {
apiFilePath android.Path
}
// droiddoc converts .java source files to documentation using doclava or dokka.
func DroiddocFactory() android.Module {
module := &Droiddoc{}
@@ -841,6 +844,7 @@ func DroiddocFactory() android.Module {
return module
}
// droiddoc_host converts .java source files to documentation using doclava or dokka.
func DroiddocHostFactory() android.Module {
module := &Droiddoc{}
@@ -918,7 +922,7 @@ func (d *Droiddoc) collectDoclavaDocsFlags(ctx android.ModuleContext, implicits
args := " -source 1.8 -J-Xmx1600m -J-XX:-OmitStackTraceInFastThrow -XDignore.symbol.file " +
"-doclet com.google.doclava.Doclava -docletpath " + jsilver.String() + ":" + doclava.String() + " " +
"-hdf page.build " + ctx.Config().BuildId() + "-" + ctx.Config().BuildNumberFromFile() + " " +
`-hdf page.now "$$(` + date + ` @$$(cat ` + ctx.Config().Getenv("BUILD_DATETIME_FILE") + `) "+%d %b %Y %k:%M")" `
`-hdf page.now "$(` + date + ` @$(cat ` + ctx.Config().Getenv("BUILD_DATETIME_FILE") + `) "+%d %b %Y %k:%M")" `
if String(d.properties.Custom_template) == "" {
// TODO: This is almost always droiddoc-templates-sdk
@@ -1095,7 +1099,7 @@ func (d *Droiddoc) transformDoclava(ctx android.ModuleContext, implicits android
"srcJarDir": android.PathForModuleOut(ctx, "srcjars").String(),
"stubsDir": android.PathForModuleOut(ctx, "stubsDir").String(),
"srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
"opts": opts,
"opts": proptools.NinjaEscape(opts),
"bootclasspathArgs": bootclasspathArgs,
"classpathArgs": classpathArgs,
"sourcepathArgs": sourcepathArgs,
@@ -1117,7 +1121,7 @@ func (d *Droiddoc) transformCheckApi(ctx android.ModuleContext, apiFile, removed
Args: map[string]string{
"msg": msg,
"classpath": checkApiClasspath.FormJavaClassPath(""),
"opts": opts,
"opts": proptools.NinjaEscape(opts),
"apiFile": apiFile.String(),
"apiFileToCheck": d.apiFile.String(),
"removedApiFile": removedApiFile.String(),
@@ -1140,7 +1144,7 @@ func (d *Droiddoc) transformDokka(ctx android.ModuleContext, implicits android.P
"stubsDir": android.PathForModuleOut(ctx, "dokka-stubsDir").String(),
"srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
"classpathArgs": classpathArgs,
"opts": opts,
"opts": proptools.NinjaEscape(opts),
"docZip": d.Javadoc.docZip.String(),
},
})
@@ -1258,6 +1262,9 @@ type Droidstubs struct {
jdiffStubsSrcJar android.WritablePath
}
// droidstubs passes sources files through Metalava to generate stub .java files that only contain the API to be
// documented, filtering out hidden classes and methods. The resulting .java files are intended to be passed to
// a droiddoc module to generate documentation.
func DroidstubsFactory() android.Module {
module := &Droidstubs{}
@@ -1268,6 +1275,10 @@ func DroidstubsFactory() android.Module {
return module
}
// droidstubs_host passes sources files through Metalava to generate stub .java files that only contain the API
// to be documented, filtering out hidden classes and methods. The resulting .java files are intended to be
// passed to a droiddoc_host module to generate documentation. Use a droidstubs_host instead of a droidstubs
// module when symbols needed by the source files are provided by java_library_host modules.
func DroidstubsHostFactory() android.Module {
module := &Droidstubs{}
@@ -1558,7 +1569,7 @@ func (d *Droidstubs) transformMetalava(ctx android.ModuleContext, implicits andr
"bootclasspathArgs": bootclasspathArgs,
"classpathArgs": classpathArgs,
"sourcepathArgs": sourcepathArgs,
"opts": opts,
"opts": proptools.NinjaEscape(opts),
},
})
}
@@ -1581,7 +1592,7 @@ func (d *Droidstubs) transformCheckApi(ctx android.ModuleContext,
"bootclasspathArgs": bootclasspathArgs,
"classpathArgs": classpathArgs,
"sourcepathArgs": sourcepathArgs,
"opts": opts,
"opts": proptools.NinjaEscape(opts),
"msg": msg,
},
})
@@ -1602,7 +1613,7 @@ func (d *Droidstubs) transformJdiff(ctx android.ModuleContext, implicits android
"srcJarDir": android.PathForModuleOut(ctx, "jdiff-srcjars").String(),
"stubsDir": android.PathForModuleOut(ctx, "jdiff-stubsDir").String(),
"srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
"opts": opts,
"opts": proptools.NinjaEscape(opts),
"bootclasspathArgs": bootclasspathArgs,
"classpathArgs": classpathArgs,
"sourcepathArgs": sourcepathArgs,
@@ -1781,6 +1792,7 @@ type ExportedDroiddocDir struct {
dir android.Path
}
// droiddoc_exported_dir exports a directory of html templates or nullability annotations for use by doclava.
func ExportedDroiddocDirFactory() android.Module {
module := &ExportedDroiddocDir{}
module.AddProperties(&module.properties)

View File

@@ -2088,14 +2088,14 @@ func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
// use zip2zip to uncompress classes*.dex files
rule.Command().
Tool(ctx.Config().HostToolPath(ctx, "zip2zip")).
BuiltTool(ctx, "zip2zip").
FlagWithInput("-i ", inputJar).
FlagWithOutput("-o ", temporary).
FlagWithArg("-0 ", "'classes*.dex'")
// use zipalign to align uncompressed classes*.dex files
rule.Command().
Tool(ctx.Config().HostToolPath(ctx, "zipalign")).
BuiltTool(ctx, "zipalign").
Flag("-f").
Text("4").
Input(temporary).

View File

@@ -34,7 +34,7 @@ func genProto(ctx android.ModuleContext, protoFile android.Path, flags android.P
// Proto generated java files have an unknown package name in the path, so package the entire output directory
// into a srcjar.
rule.Command().
Tool(ctx.Config().HostToolPath(ctx, "soong_zip")).
BuiltTool(ctx, "soong_zip").
Flag("-jar").
FlagWithOutput("-o ", srcJarFile).
FlagWithArg("-C ", outDir.String()).

View File

@@ -296,7 +296,7 @@ func createSdkFrameworkAidl(ctx android.SingletonContext) {
rule.Command().
Text("rm -f").Output(aidl)
rule.Command().
Tool(ctx.Config().HostToolPath(ctx, "sdkparcelables")).
BuiltTool(ctx, "sdkparcelables").
Input(jar).
Output(aidl)

View File

@@ -34,7 +34,7 @@ func genProto(ctx android.ModuleContext, protoFile android.Path, flags android.P
// Proto generated python files have an unknown package name in the path, so package the entire output directory
// into a srcszip.
zipCmd := rule.Command().
Tool(ctx.Config().HostToolPath(ctx, "soong_zip")).
BuiltTool(ctx, "soong_zip").
FlagWithOutput("-o ", srcsZipFile)
if pkgPath != "" {
zipCmd.FlagWithArg("-P ", pkgPath)

View File

@@ -48,11 +48,11 @@ if [ ! -r "${jardir}/${jarfile}" ]; then
exit 1
fi
javaOpts=""
declare -a javaOpts=()
while expr "x$1" : 'x-J' >/dev/null; do
opt=`expr "$1" : '-J\(.*\)'`
javaOpts="${javaOpts} -${opt}"
opt=`expr "$1" : '-J-\{0,1\}\(.*\)'`
javaOpts+=("-${opt}")
shift
done
exec java ${javaOpts} -jar ${jardir}/${jarfile} "$@"
exec java "${javaOpts[@]}" -jar ${jardir}/${jarfile} "$@"