aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorColin Cross <ccross@android.com>2015-06-30 16:27:57 -0700
committerColin Cross <ccross@android.com>2015-06-30 17:51:25 -0700
commitb3245e9cf6452e799dddcec85ae46b6d8b8d1ea8 (patch)
treedde09269bd1915eaa37a56c57e01bba11704b0d6
parent70a5f07663f00def2265056f2b008978248cb2b2 (diff)
downloadbuild_soong-b3245e9cf6452e799dddcec85ae46b6d8b8d1ea8.tar.gz
build_soong-b3245e9cf6452e799dddcec85ae46b6d8b8d1ea8.tar.bz2
build_soong-b3245e9cf6452e799dddcec85ae46b6d8b8d1ea8.zip
androidbp: simplify translation by evaluating all expressions in Blueprint
Translation is getting complicated because the expressions supported by Blueprint are difficult to support in Make. Modify androidbp to use context aware parsing so it can evaluate all expressions at parse time, so it only needs to deal with constant values. Change-Id: I57047645fb48475baecd0361f78a93ec0a26011e
-rw-r--r--Android.bp1
-rw-r--r--androidbp/cmd/androidbp.go158
-rw-r--r--androidbp/cmd/androidbp_test.go20
-rw-r--r--build.ninja.in18
-rw-r--r--common/defs.go4
5 files changed, 63 insertions, 138 deletions
diff --git a/Android.bp b/Android.bp
index 2a21d3db..8185a2c2 100644
--- a/Android.bp
+++ b/Android.bp
@@ -198,6 +198,7 @@ bootstrap_go_binary {
"androidbp/cmd/androidbp_test.go",
],
deps: [
+ "blueprint",
"blueprint-parser",
],
}
diff --git a/androidbp/cmd/androidbp.go b/androidbp/cmd/androidbp.go
index abbaf4bf..a5cf91ae 100644
--- a/androidbp/cmd/androidbp.go
+++ b/androidbp/cmd/androidbp.go
@@ -12,6 +12,7 @@ import (
"strings"
"text/scanner"
+ "github.com/google/blueprint"
bpparser "github.com/google/blueprint/parser"
)
@@ -59,10 +60,6 @@ type androidMkWriter struct {
blueprint *bpparser.File
path string
-
- printedLocalPath bool
-
- mapScope map[string][]*bpparser.Property
}
func (w *androidMkWriter) WriteString(s string) (int, error) {
@@ -70,38 +67,21 @@ func (w *androidMkWriter) WriteString(s string) (int, error) {
}
func valueToString(value bpparser.Value) (string, error) {
- if value.Variable != "" {
- return fmt.Sprintf("$(%s)", value.Variable), nil
- } else if value.Expression != nil {
- if value.Expression.Operator != '+' {
- return "", fmt.Errorf("unexpected operator '%c'", value.Expression.Operator)
- }
- val1, err := valueToString(value.Expression.Args[0])
- if err != nil {
- return "", err
- }
- val2, err := valueToString(value.Expression.Args[1])
+ switch value.Type {
+ case bpparser.Bool:
+ return fmt.Sprintf("%t", value.BoolValue), nil
+ case bpparser.String:
+ return fmt.Sprintf("%s", processWildcards(value.StringValue)), nil
+ case bpparser.List:
+ val, err := listToMkString(value.ListValue)
if err != nil {
return "", err
}
- return fmt.Sprintf("%s%s", val1, val2), nil
- } else {
- switch value.Type {
- case bpparser.Bool:
- return fmt.Sprintf("%t", value.BoolValue), nil
- case bpparser.String:
- return fmt.Sprintf("%s", processWildcards(value.StringValue)), nil
- case bpparser.List:
- val, err := listToMkString(value.ListValue)
- if err != nil {
- return "", err
- }
- return fmt.Sprintf("\\\n%s", val), nil
- case bpparser.Map:
- return "", fmt.Errorf("Can't convert map to string")
- default:
- return "", fmt.Errorf("ERROR: unsupported type %d", value.Type)
- }
+ return fmt.Sprintf("\\\n%s", val), nil
+ case bpparser.Map:
+ return "", fmt.Errorf("Can't convert map to string")
+ default:
+ return "", fmt.Errorf("ERROR: unsupported type %d", value.Type)
}
}
@@ -273,15 +253,6 @@ func modulePropBool(module *bpparser.Module, name string) bool {
return false
}
-func (w *androidMkWriter) lookupMap(parent bpparser.Value) (mapValue []*bpparser.Property) {
- if parent.Variable != "" {
- mapValue = w.mapScope[parent.Variable]
- } else {
- mapValue = parent.MapValue
- }
- return
-}
-
func (w *androidMkWriter) writeModule(moduleRule string, props []string,
disabledBuilds map[string]bool, isHostRule bool) {
disabledConditionals := disabledTargetConditionals
@@ -317,15 +288,13 @@ func (w *androidMkWriter) parsePropsAndWriteModule(module *Module) error {
}
standardProps = append(standardProps, props...)
} else if suffixMap, ok := suffixProperties[prop.Name.Name]; ok {
- suffixProps := w.lookupMap(prop.Value)
- props, err := translateSuffixProperties(suffixProps, suffixMap)
+ props, err := translateSuffixProperties(prop.Value.MapValue, suffixMap)
if err != nil {
return err
}
standardProps = append(standardProps, props...)
} else if "target" == prop.Name.Name {
- suffixProps := w.lookupMap(prop.Value)
- props, err := translateTargetConditionals(suffixProps, disabledBuilds, module.isHostRule)
+ props, err := translateTargetConditionals(prop.Value.MapValue, disabledBuilds, module.isHostRule)
if err != nil {
return err
}
@@ -415,58 +384,8 @@ func (w *androidMkWriter) handleSubdirs(value bpparser.Value) {
fmt.Fprintf(w, "# include $(wildcard $(addsuffix $(LOCAL_PATH)/%s/, Android.mk))\n", strings.Join(subdirs, " "))
}
-func (w *androidMkWriter) handleAssignment(assignment *bpparser.Assignment) error {
- comment := w.getCommentBlock(assignment.Name.Pos)
- if translation, translated, err := getCommentTranslation(comment); err != nil {
- return err
- } else if translated {
- w.WriteString(translation)
- return nil
- }
-
- if "subdirs" == assignment.Name.Name {
- w.handleSubdirs(assignment.OrigValue)
- } else if assignment.OrigValue.Type == bpparser.Map {
- // maps may be assigned in Soong, but can only be translated to .mk
- // in the context of the module
- w.mapScope[assignment.Name.Name] = assignment.OrigValue.MapValue
- } else {
- assigner := ":="
- if assignment.Assigner != "=" {
- assigner = assignment.Assigner
- }
- val, err := valueToString(assignment.OrigValue)
- if err != nil {
- return err
- }
- fmt.Fprintf(w, "%s %s %s\n", assignment.Name.Name, assigner, val)
- }
-
- return nil
-}
-
func (w *androidMkWriter) handleLocalPath() error {
- if w.printedLocalPath {
- return nil
- }
- w.printedLocalPath = true
-
- localPath, err := filepath.Abs(w.path)
- if err != nil {
- return err
- }
-
- top, err := getTopOfAndroidTree(localPath)
- if err != nil {
- return err
- }
-
- rel, err := filepath.Rel(top, localPath)
- if err != nil {
- return err
- }
-
- w.WriteString("LOCAL_PATH := " + rel + "\n")
+ w.WriteString("LOCAL_PATH := " + w.path + "\n")
w.WriteString("LOCAL_MODULE_MAKEFILE := $(lastword $(MAKEFILE_LIST))\n\n")
return nil
}
@@ -568,7 +487,7 @@ func (w *androidMkWriter) write(writer io.Writer) (err error) {
case *bpparser.Module:
err = w.handleModule(block)
case *bpparser.Assignment:
- err = w.handleAssignment(block)
+ // Nothing
default:
return fmt.Errorf("Unhandled def %v", block)
}
@@ -580,27 +499,33 @@ func (w *androidMkWriter) write(writer io.Writer) (err error) {
return nil
}
-func translate(androidBp, androidMk string) error {
- reader, err := os.Open(androidBp)
- if err != nil {
- return err
- }
+func translate(rootFile, androidBp, androidMk string) error {
+
+ ctx := blueprint.NewContext()
+
+ var blueprintFile *bpparser.File
- scope := bpparser.NewScope(nil)
- blueprint, errs := bpparser.Parse(androidBp, reader, scope)
+ _, errs := ctx.WalkBlueprintsFiles(rootFile, func(file *bpparser.File) {
+ if file.Name == androidBp {
+ blueprintFile = file
+ }
+ })
if len(errs) > 0 {
return errs[0]
}
+ if blueprintFile == nil {
+ return fmt.Errorf("File %q wasn't parsed from %q", androidBp, rootFile)
+ }
+
writer := &androidMkWriter{
- blueprint: blueprint,
+ blueprint: blueprintFile,
path: path.Dir(androidBp),
- mapScope: make(map[string][]*bpparser.Property),
}
buf := &bytes.Buffer{}
- err = writer.write(buf)
+ err := writer.write(buf)
if err != nil {
os.Remove(androidMk)
return err
@@ -618,16 +543,21 @@ func translate(androidBp, androidMk string) error {
}
func main() {
- if len(os.Args) < 3 {
- fmt.Fprintln(os.Stderr, "Expected input and output filename arguments")
+ if len(os.Args) < 4 {
+ fmt.Fprintln(os.Stderr, "Expected root Android.bp, input and output filename arguments")
os.Exit(1)
}
- androidBp := os.Args[1]
- androidMk := os.Args[2]
-
- err := translate(androidBp, androidMk)
+ rootFile := os.Args[1]
+ androidBp, err := filepath.Rel(filepath.Dir(rootFile), os.Args[2])
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "Android.bp file %q is not relative to %q: %s\n",
+ os.Args[2], rootFile, err.Error())
+ os.Exit(1)
+ }
+ androidMk := os.Args[3]
+ err = translate(rootFile, androidBp, androidMk)
if err != nil {
fmt.Fprintf(os.Stderr, "Error translating %s: %s\n", androidBp, err.Error())
os.Exit(1)
diff --git a/androidbp/cmd/androidbp_test.go b/androidbp/cmd/androidbp_test.go
index 56ceca56..87170ed5 100644
--- a/androidbp/cmd/androidbp_test.go
+++ b/androidbp/cmd/androidbp_test.go
@@ -18,28 +18,15 @@ var valueTestCases = []struct {
expected: `false`,
},
{
- blueprint: `test = Variable`,
- expected: `$(Variable)`,
- },
- {
blueprint: `test = "string"`,
expected: `string`,
},
{
blueprint: `test = ["a", "b"]`,
expected: `\
- a \
- b`,
- },
- {
- blueprint: `test = Var + "b"`,
- expected: `$(Var)b`,
- },
- {
- blueprint: `test = ["a"] + ["b"]`,
- expected: `\
- a\
- b`,
+ a \
+ b
+ `,
},
}
@@ -144,7 +131,6 @@ func TestModules(t *testing.T) {
writer := &androidMkWriter{
blueprint: blueprint,
path: "",
- mapScope: make(map[string][]*bpparser.Property),
Writer: buf,
}
diff --git a/build.ninja.in b/build.ninja.in
index 8a507f2b..c015c641 100644
--- a/build.ninja.in
+++ b/build.ninja.in
@@ -70,8 +70,11 @@ build .bootstrap/androidbp/test/androidbp.a: g.bootstrap.gc $
${g.bootstrap.srcDir}/build/soong/androidbp/cmd/soong.go $
${g.bootstrap.srcDir}/build/soong/androidbp/cmd/androidbp_test.go | $
${g.bootstrap.gcCmd} $
- .bootstrap/blueprint-parser/pkg/github.com/google/blueprint/parser.a
- incFlags = -I .bootstrap/blueprint-parser/pkg
+ .bootstrap/blueprint-parser/pkg/github.com/google/blueprint/parser.a $
+ .bootstrap/blueprint-pathtools/pkg/github.com/google/blueprint/pathtools.a $
+ .bootstrap/blueprint-proptools/pkg/github.com/google/blueprint/proptools.a $
+ .bootstrap/blueprint/pkg/github.com/google/blueprint.a
+ incFlags = -I .bootstrap/blueprint-parser/pkg -I .bootstrap/blueprint-pathtools/pkg -I .bootstrap/blueprint-proptools/pkg -I .bootstrap/blueprint/pkg
pkgPath = androidbp
default .bootstrap/androidbp/test/androidbp.a
@@ -90,7 +93,7 @@ default .bootstrap/androidbp/test/test.a
build .bootstrap/androidbp/test/test: g.bootstrap.link $
.bootstrap/androidbp/test/test.a | ${g.bootstrap.linkCmd}
- libDirFlags = -L .bootstrap/androidbp/test -L .bootstrap/blueprint-parser/pkg
+ libDirFlags = -L .bootstrap/androidbp/test -L .bootstrap/blueprint-parser/pkg -L .bootstrap/blueprint-pathtools/pkg -L .bootstrap/blueprint-proptools/pkg -L .bootstrap/blueprint/pkg
default .bootstrap/androidbp/test/test
build .bootstrap/androidbp/test/test.passed: g.bootstrap.test $
@@ -104,14 +107,17 @@ build .bootstrap/androidbp/obj/androidbp.a: g.bootstrap.gc $
${g.bootstrap.srcDir}/build/soong/androidbp/cmd/soong.go | $
${g.bootstrap.gcCmd} $
.bootstrap/blueprint-parser/pkg/github.com/google/blueprint/parser.a $
- || .bootstrap/androidbp/test/test.passed
- incFlags = -I .bootstrap/blueprint-parser/pkg
+ .bootstrap/blueprint-pathtools/pkg/github.com/google/blueprint/pathtools.a $
+ .bootstrap/blueprint-proptools/pkg/github.com/google/blueprint/proptools.a $
+ .bootstrap/blueprint/pkg/github.com/google/blueprint.a || $
+ .bootstrap/androidbp/test/test.passed
+ incFlags = -I .bootstrap/blueprint-parser/pkg -I .bootstrap/blueprint-pathtools/pkg -I .bootstrap/blueprint-proptools/pkg -I .bootstrap/blueprint/pkg
pkgPath = androidbp
default .bootstrap/androidbp/obj/androidbp.a
build .bootstrap/androidbp/obj/a.out: g.bootstrap.link $
.bootstrap/androidbp/obj/androidbp.a | ${g.bootstrap.linkCmd}
- libDirFlags = -L .bootstrap/blueprint-parser/pkg
+ libDirFlags = -L .bootstrap/blueprint-parser/pkg -L .bootstrap/blueprint-pathtools/pkg -L .bootstrap/blueprint-proptools/pkg -L .bootstrap/blueprint/pkg
default .bootstrap/androidbp/obj/a.out
build .bootstrap/bin/androidbp: g.bootstrap.cp .bootstrap/androidbp/obj/a.out
diff --git a/common/defs.go b/common/defs.go
index 98464fef..f5b02fe5 100644
--- a/common/defs.go
+++ b/common/defs.go
@@ -27,10 +27,12 @@ var (
cpPreserveSymlinks = pctx.VariableConfigMethod("cpPreserveSymlinks",
Config.CpPreserveSymlinksFlags)
+ srcDir = pctx.VariableConfigMethod("srcDir", Config.SrcDir)
+
androidbpCmd = filepath.Join(bootstrap.BinDir, "androidbp")
androidbp = pctx.StaticRule("androidbp",
blueprint.RuleParams{
- Command: androidbpCmd + " $in $out",
+ Command: androidbpCmd + " ${srcDir}/Android.bp $in $out",
Description: "androidbp $out",
})