diff --git a/Android.bp b/Android.bp index 2a21d3db2..8185a2c23 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 abbaf4bf3..a5cf91ae4 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]) + 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 } - val2, err := valueToString(value.Expression.Args[1]) - 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 { - scope := bpparser.NewScope(nil) - blueprint, errs := bpparser.Parse(androidBp, reader, scope) + ctx := blueprint.NewContext() + + var blueprintFile *bpparser.File + + _, 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 56ceca561..87170ed58 100644 --- a/androidbp/cmd/androidbp_test.go +++ b/androidbp/cmd/androidbp_test.go @@ -17,10 +17,6 @@ var valueTestCases = []struct { blueprint: `test = false`, expected: `false`, }, - { - blueprint: `test = Variable`, - expected: `$(Variable)`, - }, { blueprint: `test = "string"`, expected: `string`, @@ -28,18 +24,9 @@ var valueTestCases = []struct { { 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 8a507f2bd..c015c641c 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 98464fef3..f5b02fe54 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", })