summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Colin Cross <ccross@android.com> 2019-01-30 17:32:39 -0800
committer Colin Cross <ccross@android.com> 2019-02-05 13:28:43 -0800
commitfeec25b08460d1eb1c31296463a9ec61eca9754c (patch)
tree04b767a6cb2954e7014328b4176375db7bcd04d9
parenta55b12bec27b6e69ee4973d1645d8f61c2c89530 (diff)
Move dexpreopt.Script to android.RuleBuilder
Move dexpreopt.Script to android.RuleBuilder so that the builder style can be used in more places. Also add tests for it. Test: rule_builder_test.go Change-Id: I92a963bd112bf033b08899e930094b908acfcdfd
-rw-r--r--Android.bp2
-rw-r--r--android/rule_builder.go230
-rw-r--r--android/rule_builder_test.go148
-rw-r--r--dexpreopt/Android.bp4
-rw-r--r--dexpreopt/dexpreopt.go16
-rw-r--r--dexpreopt/dexpreopt_gen/dexpreopt_gen.go3
-rw-r--r--dexpreopt/dexpreopt_test.go7
-rw-r--r--dexpreopt/script.go178
-rw-r--r--java/dexpreopt.go60
-rw-r--r--java/hiddenapi.go16
10 files changed, 413 insertions, 251 deletions
diff --git a/Android.bp b/Android.bp
index a70f73c92..5e9c600b0 100644
--- a/Android.bp
+++ b/Android.bp
@@ -61,6 +61,7 @@ bootstrap_go_package {
"android/prebuilt_etc.go",
"android/proto.go",
"android/register.go",
+ "android/rule_builder.go",
"android/sh_binary.go",
"android/singleton.go",
"android/testing.go",
@@ -80,6 +81,7 @@ bootstrap_go_package {
"android/paths_test.go",
"android/prebuilt_test.go",
"android/prebuilt_etc_test.go",
+ "android/rule_builder_test.go",
"android/util_test.go",
"android/variable_test.go",
],
diff --git a/android/rule_builder.go b/android/rule_builder.go
new file mode 100644
index 000000000..b7e84323d
--- /dev/null
+++ b/android/rule_builder.go
@@ -0,0 +1,230 @@
+// Copyright 2018 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package android
+
+import (
+ "fmt"
+ "path/filepath"
+ "sort"
+ "strings"
+
+ "github.com/google/blueprint"
+ "github.com/google/blueprint/proptools"
+)
+
+type RuleBuilderInstall struct {
+ From, To string
+}
+
+type RuleBuilder struct {
+ commands []*RuleBuilderCommand
+ installs []RuleBuilderInstall
+ restat bool
+}
+
+func (r *RuleBuilder) Restat() *RuleBuilder {
+ r.restat = true
+ return r
+}
+
+func (r *RuleBuilder) Install(from, to string) {
+ r.installs = append(r.installs, RuleBuilderInstall{from, to})
+}
+
+func (r *RuleBuilder) Command() *RuleBuilderCommand {
+ command := &RuleBuilderCommand{}
+ r.commands = append(r.commands, command)
+ return command
+}
+
+func (r *RuleBuilder) Inputs() []string {
+ outputs := r.outputSet()
+
+ inputs := make(map[string]bool)
+ for _, c := range r.commands {
+ for _, input := range c.inputs {
+ if !outputs[input] {
+ inputs[input] = true
+ }
+ }
+ }
+
+ var inputList []string
+ for input := range inputs {
+ inputList = append(inputList, input)
+ }
+ sort.Strings(inputList)
+
+ return inputList
+}
+
+func (r *RuleBuilder) outputSet() map[string]bool {
+ outputs := make(map[string]bool)
+ for _, c := range r.commands {
+ for _, output := range c.outputs {
+ outputs[output] = true
+ }
+ }
+ return outputs
+}
+
+func (r *RuleBuilder) Outputs() []string {
+ outputs := r.outputSet()
+
+ var outputList []string
+ for output := range outputs {
+ outputList = append(outputList, output)
+ }
+ sort.Strings(outputList)
+ return outputList
+}
+
+func (r *RuleBuilder) Installs() []RuleBuilderInstall {
+ return append([]RuleBuilderInstall(nil), r.installs...)
+}
+
+func (r *RuleBuilder) Tools() []string {
+ var tools []string
+ for _, c := range r.commands {
+ tools = append(tools, c.tools...)
+ }
+ return tools
+}
+
+func (r *RuleBuilder) Commands() []string {
+ var commands []string
+ for _, c := range r.commands {
+ commands = append(commands, string(c.buf))
+ }
+ return commands
+}
+
+func (r *RuleBuilder) Build(pctx PackageContext, ctx ModuleContext, name string, desc string) {
+ var inputs Paths
+ for _, input := range r.Inputs() {
+ rel, isRel := MaybeRel(ctx, PathForModuleOut(ctx).String(), input)
+ if isRel {
+ inputs = append(inputs, PathForModuleOut(ctx, rel))
+ } else {
+ // TODO: use PathForOutput once boot image is moved to where PathForOutput can find it.
+ inputs = append(inputs, &unknownRulePath{input})
+ }
+ }
+
+ var outputs WritablePaths
+ for _, output := range r.Outputs() {
+ rel := Rel(ctx, PathForModuleOut(ctx).String(), output)
+ outputs = append(outputs, PathForModuleOut(ctx, rel))
+ }
+
+ if len(r.Commands()) > 0 {
+ ctx.Build(pctx, BuildParams{
+ Rule: ctx.Rule(pctx, name, blueprint.RuleParams{
+ Command: strings.Join(proptools.NinjaEscape(r.Commands()), " && "),
+ CommandDeps: r.Tools(),
+ }),
+ Implicits: inputs,
+ Outputs: outputs,
+ Description: desc,
+ })
+ }
+}
+
+type RuleBuilderCommand struct {
+ buf []byte
+ inputs []string
+ outputs []string
+ tools []string
+}
+
+func (c *RuleBuilderCommand) Text(text string) *RuleBuilderCommand {
+ if len(c.buf) > 0 {
+ c.buf = append(c.buf, ' ')
+ }
+ c.buf = append(c.buf, text...)
+ return c
+}
+
+func (c *RuleBuilderCommand) Textf(format string, a ...interface{}) *RuleBuilderCommand {
+ return c.Text(fmt.Sprintf(format, a...))
+}
+
+func (c *RuleBuilderCommand) Flag(flag string) *RuleBuilderCommand {
+ return c.Text(flag)
+}
+
+func (c *RuleBuilderCommand) FlagWithArg(flag, arg string) *RuleBuilderCommand {
+ return c.Text(flag + arg)
+}
+
+func (c *RuleBuilderCommand) FlagWithList(flag string, list []string, sep string) *RuleBuilderCommand {
+ return c.Text(flag + strings.Join(list, sep))
+}
+
+func (c *RuleBuilderCommand) Tool(path string) *RuleBuilderCommand {
+ c.tools = append(c.tools, path)
+ return c.Text(path)
+}
+
+func (c *RuleBuilderCommand) Input(path string) *RuleBuilderCommand {
+ c.inputs = append(c.inputs, path)
+ return c.Text(path)
+}
+
+func (c *RuleBuilderCommand) Implicit(path string) *RuleBuilderCommand {
+ c.inputs = append(c.inputs, path)
+ return c
+}
+
+func (c *RuleBuilderCommand) Implicits(paths []string) *RuleBuilderCommand {
+ c.inputs = append(c.inputs, paths...)
+ return c
+}
+
+func (c *RuleBuilderCommand) Output(path string) *RuleBuilderCommand {
+ c.outputs = append(c.outputs, path)
+ return c.Text(path)
+}
+
+func (c *RuleBuilderCommand) ImplicitOutput(path string) *RuleBuilderCommand {
+ c.outputs = append(c.outputs, path)
+ return c
+}
+
+func (c *RuleBuilderCommand) FlagWithInput(flag, path string) *RuleBuilderCommand {
+ c.inputs = append(c.inputs, path)
+ return c.Text(flag + path)
+}
+
+func (c *RuleBuilderCommand) FlagWithInputList(flag string, paths []string, sep string) *RuleBuilderCommand {
+ c.inputs = append(c.inputs, paths...)
+ return c.FlagWithList(flag, paths, sep)
+}
+
+func (c *RuleBuilderCommand) FlagWithOutput(flag, path string) *RuleBuilderCommand {
+ c.outputs = append(c.outputs, path)
+ return c.Text(flag + path)
+}
+
+type unknownRulePath struct {
+ path string
+}
+
+var _ Path = (*unknownRulePath)(nil)
+
+func (p *unknownRulePath) String() string { return p.path }
+func (p *unknownRulePath) Ext() string { return filepath.Ext(p.path) }
+func (p *unknownRulePath) Base() string { return filepath.Base(p.path) }
+func (p *unknownRulePath) Rel() string { return p.path }
diff --git a/android/rule_builder_test.go b/android/rule_builder_test.go
new file mode 100644
index 000000000..b4c9e0eb6
--- /dev/null
+++ b/android/rule_builder_test.go
@@ -0,0 +1,148 @@
+// Copyright 2019 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package android
+
+import (
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "reflect"
+ "testing"
+)
+
+func TestRuleBuilder(t *testing.T) {
+ rule := RuleBuilder{}
+
+ cmd := rule.Command().
+ Flag("Flag").
+ FlagWithArg("FlagWithArg=", "arg").
+ FlagWithInput("FlagWithInput=", "input").
+ FlagWithOutput("FlagWithOutput=", "output").
+ Implicit("Implicit").
+ ImplicitOutput("ImplicitOutput").
+ Input("Input").
+ Output("Output").
+ Text("Text").
+ Tool("Tool")
+
+ rule.Command().
+ Text("command2").
+ Input("input2").
+ Output("output2").
+ Tool("tool2")
+
+ // Test updates to the first command after the second command has been started
+ cmd.Text("after command2")
+ // Test updating a command when the previous update did not replace the cmd variable
+ cmd.Text("old cmd")
+
+ // Test a command that uses the output of a previous command as an input
+ rule.Command().
+ Text("command3").
+ Input("input3").
+ Input("output2").
+ Output("output3")
+
+ wantCommands := []string{
+ "Flag FlagWithArg=arg FlagWithInput=input FlagWithOutput=output Input Output Text Tool after command2 old cmd",
+ "command2 input2 output2 tool2",
+ "command3 input3 output2 output3",
+ }
+ wantInputs := []string{"Implicit", "Input", "input", "input2", "input3"}
+ wantOutputs := []string{"ImplicitOutput", "Output", "output", "output2", "output3"}
+ wantTools := []string{"Tool", "tool2"}
+
+ if !reflect.DeepEqual(rule.Commands(), wantCommands) {
+ t.Errorf("\nwant rule.Commands() = %#v\n got %#v", wantCommands, rule.Commands())
+ }
+ if !reflect.DeepEqual(rule.Inputs(), wantInputs) {
+ t.Errorf("\nwant rule.Inputs() = %#v\n got %#v", wantInputs, rule.Inputs())
+ }
+ if !reflect.DeepEqual(rule.Outputs(), wantOutputs) {
+ t.Errorf("\nwant rule.Outputs() = %#v\n got %#v", wantOutputs, rule.Outputs())
+ }
+ if !reflect.DeepEqual(rule.Tools(), wantTools) {
+ t.Errorf("\nwant rule.Tools() = %#v\n got %#v", wantTools, rule.Tools())
+ }
+}
+
+func testRuleBuilderFactory() Module {
+ module := &testRuleBuilderModule{}
+ module.AddProperties(&module.properties)
+ InitAndroidModule(module)
+ return module
+}
+
+type testRuleBuilderModule struct {
+ ModuleBase
+ properties struct {
+ Src string
+ }
+}
+
+func (t *testRuleBuilderModule) GenerateAndroidBuildActions(ctx ModuleContext) {
+ rule := RuleBuilder{}
+
+ in := PathForSource(ctx, t.properties.Src)
+ out := PathForModuleOut(ctx, ctx.ModuleName())
+
+ rule.Command().Tool("cp").Input(in.String()).Output(out.String())
+
+ rule.Build(pctx, ctx, "rule", "desc")
+}
+
+func TestRuleBuilder_Build(t *testing.T) {
+ buildDir, err := ioutil.TempDir("", "soong_test_rule_builder")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer os.RemoveAll(buildDir)
+
+ bp := `
+ rule_builder_test {
+ name: "foo",
+ src: "bar",
+ }
+ `
+
+ config := TestConfig(buildDir, nil)
+ ctx := NewTestContext()
+ ctx.MockFileSystem(map[string][]byte{
+ "Android.bp": []byte(bp),
+ "bar": nil,
+ "cp": nil,
+ })
+ ctx.RegisterModuleType("rule_builder_test", ModuleFactoryAdaptor(testRuleBuilderFactory))
+ ctx.Register()
+
+ _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
+ FailIfErrored(t, errs)
+ _, errs = ctx.PrepareBuildActions(config)
+ FailIfErrored(t, errs)
+
+ foo := ctx.ModuleForTests("foo", "").Rule("rule")
+
+ // TODO: make RuleParams accessible to tests and verify rule.Command().Tools() ends up in CommandDeps
+
+ if len(foo.Implicits) != 1 || foo.Implicits[0].String() != "bar" {
+ t.Errorf("want foo.Implicits = [%q], got %q", "bar", foo.Implicits.Strings())
+ }
+
+ wantOutput := filepath.Join(buildDir, ".intermediates", "foo", "foo")
+ if len(foo.Outputs) != 1 || foo.Outputs[0].String() != wantOutput {
+ t.Errorf("want foo.Outputs = [%q], got %q", wantOutput, foo.Outputs.Strings())
+ }
+
+}
diff --git a/dexpreopt/Android.bp b/dexpreopt/Android.bp
index b83252983..c5f24e273 100644
--- a/dexpreopt/Android.bp
+++ b/dexpreopt/Android.bp
@@ -4,12 +4,12 @@ bootstrap_go_package {
srcs: [
"config.go",
"dexpreopt.go",
- "script.go",
],
testSrcs: [
"dexpreopt_test.go",
],
deps: [
"blueprint-pathtools",
+ "soong-android",
],
-} \ No newline at end of file
+}
diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go
index f316be4b0..b12ca0b6b 100644
--- a/dexpreopt/dexpreopt.go
+++ b/dexpreopt/dexpreopt.go
@@ -39,6 +39,8 @@ import (
"path/filepath"
"strings"
+ "android/soong/android"
+
"github.com/google/blueprint/pathtools"
)
@@ -47,7 +49,7 @@ const SystemOtherPartition = "/system_other/"
// GenerateStripRule generates a set of commands that will take an APK or JAR as an input and strip the dex files if
// they are no longer necessary after preopting.
-func GenerateStripRule(global GlobalConfig, module ModuleConfig) (rule *Rule, err error) {
+func GenerateStripRule(global GlobalConfig, module ModuleConfig) (rule *android.RuleBuilder, err error) {
defer func() {
if r := recover(); r != nil {
if e, ok := r.(error); ok {
@@ -61,7 +63,7 @@ func GenerateStripRule(global GlobalConfig, module ModuleConfig) (rule *Rule, er
tools := global.Tools
- rule = &Rule{}
+ rule = &android.RuleBuilder{}
strip := shouldStripDex(module, global)
@@ -81,7 +83,7 @@ func GenerateStripRule(global GlobalConfig, module ModuleConfig) (rule *Rule, er
// GenerateDexpreoptRule generates a set of commands that will preopt a module based on a GlobalConfig and a
// ModuleConfig. The produced files and their install locations will be available through rule.Installs().
-func GenerateDexpreoptRule(global GlobalConfig, module ModuleConfig) (rule *Rule, err error) {
+func GenerateDexpreoptRule(global GlobalConfig, module ModuleConfig) (rule *android.RuleBuilder, err error) {
defer func() {
if r := recover(); r != nil {
if e, ok := r.(error); ok {
@@ -93,7 +95,7 @@ func GenerateDexpreoptRule(global GlobalConfig, module ModuleConfig) (rule *Rule
}
}()
- rule = &Rule{}
+ rule = &android.RuleBuilder{}
generateProfile := module.ProfileClassListing != "" && !global.DisableGenerateProfile
@@ -141,7 +143,7 @@ func dexpreoptDisabled(global GlobalConfig, module ModuleConfig) bool {
return false
}
-func profileCommand(global GlobalConfig, module ModuleConfig, rule *Rule) string {
+func profileCommand(global GlobalConfig, module ModuleConfig, rule *android.RuleBuilder) string {
profilePath := filepath.Join(filepath.Dir(module.BuildPath), "profile.prof")
profileInstalledPath := module.DexLocation + ".prof"
@@ -178,8 +180,8 @@ func profileCommand(global GlobalConfig, module ModuleConfig, rule *Rule) string
return profilePath
}
-func dexpreoptCommand(global GlobalConfig, module ModuleConfig, rule *Rule, profile, arch, bootImageLocation string,
- appImage, generateDM bool) {
+func dexpreoptCommand(global GlobalConfig, module ModuleConfig, rule *android.RuleBuilder,
+ profile, arch, bootImageLocation string, appImage, generateDM bool) {
// HACK: make soname in Soong-generated .odex files match Make.
base := filepath.Base(module.DexLocation)
diff --git a/dexpreopt/dexpreopt_gen/dexpreopt_gen.go b/dexpreopt/dexpreopt_gen/dexpreopt_gen.go
index 46d8795a8..1467a028a 100644
--- a/dexpreopt/dexpreopt_gen/dexpreopt_gen.go
+++ b/dexpreopt/dexpreopt_gen/dexpreopt_gen.go
@@ -22,6 +22,7 @@ import (
"path/filepath"
"runtime"
+ "android/soong/android"
"android/soong/dexpreopt"
"github.com/google/blueprint/pathtools"
@@ -121,7 +122,7 @@ func writeScripts(global dexpreopt.GlobalConfig, module dexpreopt.ModuleConfig,
panic(err)
}
- write := func(rule *dexpreopt.Rule, file string) {
+ write := func(rule *android.RuleBuilder, file string) {
script := &bytes.Buffer{}
script.WriteString(scriptHeader)
for _, c := range rule.Commands() {
diff --git a/dexpreopt/dexpreopt_test.go b/dexpreopt/dexpreopt_test.go
index 073d46378..6e520f136 100644
--- a/dexpreopt/dexpreopt_test.go
+++ b/dexpreopt/dexpreopt_test.go
@@ -15,6 +15,7 @@
package dexpreopt
import (
+ "android/soong/android"
"reflect"
"strings"
"testing"
@@ -100,7 +101,7 @@ func TestDexPreopt(t *testing.T) {
t.Error(err)
}
- wantInstalls := []Install{
+ wantInstalls := []android.RuleBuilderInstall{
{"out/test/oat/arm/package.odex", "/system/app/test/oat/arm/test.odex"},
{"out/test/oat/arm/package.vdex", "/system/app/test/oat/arm/test.vdex"},
}
@@ -126,7 +127,7 @@ func TestDexPreoptSystemOther(t *testing.T) {
t.Error(err)
}
- wantInstalls := []Install{
+ wantInstalls := []android.RuleBuilderInstall{
{"out/test/oat/arm/package.odex", "/system_other/app/test/oat/arm/test.odex"},
{"out/test/oat/arm/package.vdex", "/system_other/app/test/oat/arm/test.vdex"},
}
@@ -150,7 +151,7 @@ func TestDexPreoptProfile(t *testing.T) {
t.Error(err)
}
- wantInstalls := []Install{
+ wantInstalls := []android.RuleBuilderInstall{
{"out/test/profile.prof", "/system/app/test/test.apk.prof"},
{"out/test/oat/arm/package.art", "/system/app/test/oat/arm/test.art"},
{"out/test/oat/arm/package.odex", "/system/app/test/oat/arm/test.odex"},
diff --git a/dexpreopt/script.go b/dexpreopt/script.go
deleted file mode 100644
index 9d4329c5b..000000000
--- a/dexpreopt/script.go
+++ /dev/null
@@ -1,178 +0,0 @@
-// Copyright 2018 Google Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package dexpreopt
-
-import (
- "fmt"
- "sort"
- "strings"
-)
-
-type Install struct {
- From, To string
-}
-
-type Rule struct {
- commands []*Command
- installs []Install
-}
-
-func (r *Rule) Install(from, to string) {
- r.installs = append(r.installs, Install{from, to})
-}
-
-func (r *Rule) Command() *Command {
- command := &Command{}
- r.commands = append(r.commands, command)
- return command
-}
-
-func (r *Rule) Inputs() []string {
- outputs := r.outputSet()
-
- inputs := make(map[string]bool)
- for _, c := range r.commands {
- for _, input := range c.inputs {
- if !outputs[input] {
- inputs[input] = true
- }
- }
- }
-
- var inputList []string
- for input := range inputs {
- inputList = append(inputList, input)
- }
- sort.Strings(inputList)
-
- return inputList
-}
-
-func (r *Rule) outputSet() map[string]bool {
- outputs := make(map[string]bool)
- for _, c := range r.commands {
- for _, output := range c.outputs {
- outputs[output] = true
- }
- }
- return outputs
-}
-
-func (r *Rule) Outputs() []string {
- outputs := r.outputSet()
-
- var outputList []string
- for output := range outputs {
- outputList = append(outputList, output)
- }
- sort.Strings(outputList)
- return outputList
-}
-
-func (r *Rule) Installs() []Install {
- return append([]Install(nil), r.installs...)
-}
-
-func (r *Rule) Tools() []string {
- var tools []string
- for _, c := range r.commands {
- tools = append(tools, c.tools...)
- }
- return tools
-}
-
-func (r *Rule) Commands() []string {
- var commands []string
- for _, c := range r.commands {
- commands = append(commands, string(c.buf))
- }
- return commands
-}
-
-type Command struct {
- buf []byte
- inputs []string
- outputs []string
- tools []string
-}
-
-func (c *Command) Text(text string) *Command {
- if len(c.buf) > 0 {
- c.buf = append(c.buf, ' ')
- }
- c.buf = append(c.buf, text...)
- return c
-}
-
-func (c *Command) Textf(format string, a ...interface{}) *Command {
- return c.Text(fmt.Sprintf(format, a...))
-}
-
-func (c *Command) Flag(flag string) *Command {
- return c.Text(flag)
-}
-
-func (c *Command) FlagWithArg(flag, arg string) *Command {
- return c.Text(flag + arg)
-}
-
-func (c *Command) FlagWithList(flag string, list []string, sep string) *Command {
- return c.Text(flag + strings.Join(list, sep))
-}
-
-func (c *Command) Tool(path string) *Command {
- c.tools = append(c.tools, path)
- return c.Text(path)
-}
-
-func (c *Command) Input(path string) *Command {
- c.inputs = append(c.inputs, path)
- return c.Text(path)
-}
-
-func (c *Command) Implicit(path string) *Command {
- c.inputs = append(c.inputs, path)
- return c
-}
-
-func (c *Command) Implicits(paths []string) *Command {
- c.inputs = append(c.inputs, paths...)
- return c
-}
-
-func (c *Command) Output(path string) *Command {
- c.outputs = append(c.outputs, path)
- return c.Text(path)
-}
-
-func (c *Command) ImplicitOutput(path string) *Command {
- c.outputs = append(c.outputs, path)
- return c
-}
-
-func (c *Command) FlagWithInput(flag, path string) *Command {
- c.inputs = append(c.inputs, path)
- return c.Text(flag + path)
-}
-
-func (c *Command) FlagWithInputList(flag string, paths []string, sep string) *Command {
- c.inputs = append(c.inputs, paths...)
- return c.FlagWithList(flag, paths, sep)
-}
-
-func (c *Command) FlagWithOutput(flag, path string) *Command {
- c.outputs = append(c.outputs, path)
- return c.Text(flag + path)
-}
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index 6e46bc91a..bb72b7dec 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -15,12 +15,6 @@
package java
import (
- "path/filepath"
- "strings"
-
- "github.com/google/blueprint"
- "github.com/google/blueprint/proptools"
-
"android/soong/android"
"android/soong/dexpreopt"
)
@@ -185,69 +179,19 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Mo
return dexJarFile
}
- var inputs android.Paths
- for _, input := range dexpreoptRule.Inputs() {
- if input == "" {
- // Tests sometimes have empty configuration values that lead to empty inputs
- continue
- }
- rel, isRel := android.MaybeRel(ctx, android.PathForModuleOut(ctx).String(), input)
- if isRel {
- inputs = append(inputs, android.PathForModuleOut(ctx, rel))
- } else {
- // TODO: use PathForOutput once boot image is moved to where PathForOutput can find it.
- inputs = append(inputs, &bootImagePath{input})
- }
- }
-
- var outputs android.WritablePaths
- for _, output := range dexpreoptRule.Outputs() {
- rel := android.Rel(ctx, android.PathForModuleOut(ctx).String(), output)
- outputs = append(outputs, android.PathForModuleOut(ctx, rel))
- }
+ dexpreoptRule.Build(pctx, ctx, "dexpreopt", "dexpreopt")
for _, install := range dexpreoptRule.Installs() {
d.builtInstalled = append(d.builtInstalled, install.From+":"+install.To)
}
- if len(dexpreoptRule.Commands()) > 0 {
- ctx.Build(pctx, android.BuildParams{
- Rule: ctx.Rule(pctx, "dexpreopt", blueprint.RuleParams{
- Command: strings.Join(proptools.NinjaEscape(dexpreoptRule.Commands()), " && "),
- CommandDeps: dexpreoptRule.Tools(),
- }),
- Implicits: inputs,
- Outputs: outputs,
- Description: "dexpreopt",
- })
- }
-
stripRule, err := dexpreopt.GenerateStripRule(globalConfig, dexpreoptConfig)
if err != nil {
ctx.ModuleErrorf("error generating dexpreopt strip rule: %s", err.Error())
return dexJarFile
}
- ctx.Build(pctx, android.BuildParams{
- Rule: ctx.Rule(pctx, "dexpreopt_strip", blueprint.RuleParams{
- Command: strings.Join(proptools.NinjaEscape(stripRule.Commands()), " && "),
- CommandDeps: stripRule.Tools(),
- }),
- Input: dexJarFile,
- Output: strippedDexJarFile,
- Description: "dexpreopt strip",
- })
+ stripRule.Build(pctx, ctx, "dexpreopt_strip", "dexpreopt strip")
return strippedDexJarFile
}
-
-type bootImagePath struct {
- path string
-}
-
-var _ android.Path = (*bootImagePath)(nil)
-
-func (p *bootImagePath) String() string { return p.path }
-func (p *bootImagePath) Ext() string { return filepath.Ext(p.path) }
-func (p *bootImagePath) Base() string { return filepath.Base(p.path) }
-func (p *bootImagePath) Rel() string { return p.path }
diff --git a/java/hiddenapi.go b/java/hiddenapi.go
index 67df57552..983daa79c 100644
--- a/java/hiddenapi.go
+++ b/java/hiddenapi.go
@@ -15,6 +15,7 @@
package java
import (
+ "path/filepath"
"sort"
"strings"
"sync"
@@ -32,7 +33,7 @@ var hiddenAPIGenerateCSVRule = pctx.AndroidStaticRule("hiddenAPIGenerateCSV", bl
func hiddenAPIGenerateCSV(ctx android.ModuleContext, classesJar android.Path) {
flagsCSV := android.PathForModuleOut(ctx, "hiddenapi", "flags.csv")
metadataCSV := android.PathForModuleOut(ctx, "hiddenapi", "metadata.csv")
- stubFlagsCSV := &bootImagePath{ctx.Config().HiddenAPIStubFlags()}
+ stubFlagsCSV := &hiddenAPIPath{ctx.Config().HiddenAPIStubFlags()}
ctx.Build(pctx, android.BuildParams{
Rule: hiddenAPIGenerateCSVRule,
@@ -80,7 +81,7 @@ var hiddenAPIEncodeDexRule = pctx.AndroidStaticRule("hiddenAPIEncodeDex", bluepr
func hiddenAPIEncodeDex(ctx android.ModuleContext, output android.WritablePath, dexInput android.WritablePath,
uncompressDex bool) {
- flagsCsv := &bootImagePath{ctx.Config().HiddenAPIFlags()}
+ flagsCsv := &hiddenAPIPath{ctx.Config().HiddenAPIFlags()}
// The encode dex rule requires unzipping and rezipping the classes.dex files, ensure that if it was uncompressed
// in the input it stays uncompressed in the output.
@@ -168,3 +169,14 @@ func hiddenAPIMakeVars(ctx android.MakeVarsContext) {
export("SOONG_HIDDENAPI_GREYLIST_METADATA", metadataCSVList)
export("SOONG_HIDDENAPI_DEX_INPUTS", dexInputList)
}
+
+type hiddenAPIPath struct {
+ path string
+}
+
+var _ android.Path = (*hiddenAPIPath)(nil)
+
+func (p *hiddenAPIPath) String() string { return p.path }
+func (p *hiddenAPIPath) Ext() string { return filepath.Ext(p.path) }
+func (p *hiddenAPIPath) Base() string { return filepath.Base(p.path) }
+func (p *hiddenAPIPath) Rel() string { return p.path }