aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Blueprints11
-rw-r--r--androidbp/cmd/androidbp.go195
-rw-r--r--androidbp/cmd/soong.go80
-rw-r--r--build.ninja.in33
4 files changed, 315 insertions, 4 deletions
diff --git a/Blueprints b/Blueprints
index 958c79e4..0a66b431 100644
--- a/Blueprints
+++ b/Blueprints
@@ -182,6 +182,17 @@ bootstrap_go_package {
],
}
+bootstrap_go_binary {
+ name: "androidbp",
+ srcs: [
+ "androidbp/cmd/androidbp.go",
+ "androidbp/cmd/soong.go",
+ ],
+ deps: [
+ "blueprint-parser",
+ ],
+}
+
//
// C static libraries extracted from the gcc toolchain
//
diff --git a/androidbp/cmd/androidbp.go b/androidbp/cmd/androidbp.go
new file mode 100644
index 00000000..dbca35a8
--- /dev/null
+++ b/androidbp/cmd/androidbp.go
@@ -0,0 +1,195 @@
+package main
+
+import (
+ "bufio"
+ "fmt"
+ "os"
+ "path"
+ "strings"
+
+ bpparser "github.com/google/blueprint/parser"
+)
+
+type androidMkWriter struct {
+ *bufio.Writer
+
+ file *bpparser.File
+ path string
+}
+
+func (w *androidMkWriter) valueToString(value bpparser.Value) string {
+ if value.Variable != "" {
+ return fmt.Sprintf("$(%s)", value.Variable)
+ } else {
+ switch value.Type {
+ case bpparser.Bool:
+ return fmt.Sprintf(`"%t"`, value.BoolValue)
+ case bpparser.String:
+ return fmt.Sprintf(`"%s"`, value.StringValue)
+ case bpparser.List:
+ return fmt.Sprintf("\\\n%s\n", w.listToMkString(value.ListValue))
+ case bpparser.Map:
+ w.errorf("maps not supported in assignment")
+ return "ERROR: unsupported type map in assignment"
+ }
+ }
+
+ return ""
+}
+
+func (w *androidMkWriter) listToMkString(list []bpparser.Value) string {
+ lines := make([]string, 0, len(list))
+ for _, tok := range list {
+ lines = append(lines, fmt.Sprintf("\t\"%s\"", tok.StringValue))
+ }
+
+ return strings.Join(lines, " \\\n")
+}
+
+func (w *androidMkWriter) errorf(format string, values ...interface{}) {
+ s := fmt.Sprintf(format, values)
+ w.WriteString("# ANDROIDBP ERROR:\n")
+ for _, line := range strings.Split(s, "\n") {
+ fmt.Fprintf(w, "# %s\n", line)
+ }
+}
+
+func (w *androidMkWriter) handleComment(comment *bpparser.Comment) {
+ for _, c := range comment.Comment {
+ mkComment := strings.Replace(c, "//", "#", 1)
+ // TODO: handle /* comments?
+ fmt.Fprintf(w, "%s\n", mkComment)
+ }
+}
+
+func (w *androidMkWriter) handleModule(module *bpparser.Module) {
+ if moduleName, ok := moduleTypes[module.Type.Name]; ok {
+ w.WriteString("include $(CLEAR_VARS)\n")
+ standardProps := make([]string, 0, len(module.Properties))
+ //condProps := make([]string, len(module.Properties))
+ for _, prop := range module.Properties {
+ if mkProp, ok := standardProperties[prop.Name.Name]; ok {
+ standardProps = append(standardProps, fmt.Sprintf("%s := %s", mkProp.string,
+ w.valueToString(prop.Value)))
+ }
+ }
+
+ mkModule := strings.Join(standardProps, "\n")
+ w.WriteString(mkModule)
+
+ fmt.Fprintf(w, "include $(%s)\n\n", moduleName)
+ } else {
+ w.errorf("Unsupported module %s", module.Type.Name)
+ }
+}
+
+func (w *androidMkWriter) handleAssignment(assignment *bpparser.Assignment) {
+ assigner := ":="
+ if assignment.Assigner != "=" {
+ assigner = assignment.Assigner
+ }
+ fmt.Fprintf(w, "%s %s %s\n", assignment.Name.Name, assigner,
+ w.valueToString(assignment.OrigValue))
+}
+
+func (w *androidMkWriter) iter() <-chan interface{} {
+ ch := make(chan interface{}, len(w.file.Comments)+len(w.file.Defs))
+ go func() {
+ commIdx := 0
+ defsIdx := 0
+ for defsIdx < len(w.file.Defs) || commIdx < len(w.file.Comments) {
+ if defsIdx == len(w.file.Defs) {
+ ch <- w.file.Comments[commIdx]
+ commIdx++
+ } else if commIdx == len(w.file.Comments) {
+ ch <- w.file.Defs[defsIdx]
+ defsIdx++
+ } else {
+ commentsPos := 0
+ defsPos := 0
+
+ def := w.file.Defs[defsIdx]
+ switch def := def.(type) {
+ case *bpparser.Module:
+ defsPos = def.LbracePos.Line
+ case *bpparser.Assignment:
+ defsPos = def.Pos.Line
+ }
+
+ comment := w.file.Comments[commIdx]
+ commentsPos = comment.Pos.Line
+
+ if commentsPos < defsPos {
+ commIdx++
+ ch <- comment
+ } else {
+ defsIdx++
+ ch <- def
+ }
+ }
+ }
+ close(ch)
+ }()
+ return ch
+}
+
+func (w *androidMkWriter) write() {
+ outFilePath := fmt.Sprintf("%s/Android.mk.out", w.path)
+ fmt.Printf("Writing %s\n", outFilePath)
+
+ f, err := os.Create(outFilePath)
+ if err != nil {
+ panic(err)
+ }
+
+ defer func() {
+ if err := f.Close(); err != nil {
+ panic(err)
+ }
+ }()
+
+ w.Writer = bufio.NewWriter(f)
+
+ for block := range w.iter() {
+ switch block := block.(type) {
+ case *bpparser.Module:
+ w.handleModule(block)
+ case *bpparser.Assignment:
+ w.handleAssignment(block)
+ case bpparser.Comment:
+ w.handleComment(&block)
+ }
+ }
+
+ if err = w.Flush(); err != nil {
+ panic(err)
+ }
+}
+
+func main() {
+ if len(os.Args) < 2 {
+ fmt.Println("No filename supplied")
+ return
+ }
+
+ reader, err := os.Open(os.Args[1])
+ if err != nil {
+ fmt.Println(err.Error())
+ return
+ }
+
+ scope := bpparser.NewScope(nil)
+ file, errs := bpparser.Parse(os.Args[1], reader, scope)
+ if len(errs) > 0 {
+ fmt.Println("%d errors parsing %s", len(errs), os.Args[1])
+ fmt.Println(errs)
+ return
+ }
+
+ writer := &androidMkWriter{
+ file: file,
+ path: path.Dir(os.Args[1]),
+ }
+
+ writer.write()
+}
diff --git a/androidbp/cmd/soong.go b/androidbp/cmd/soong.go
new file mode 100644
index 00000000..488390fe
--- /dev/null
+++ b/androidbp/cmd/soong.go
@@ -0,0 +1,80 @@
+package main
+
+import bpparser "github.com/google/blueprint/parser"
+
+var standardProperties = map[string]struct {
+ string
+ bpparser.ValueType
+}{
+ // ==== STRING PROPERTIES ====
+ "name": {"LOCAL_MODULE", bpparser.String},
+ "stem": {"LOCAL_MODULE_STEM", bpparser.String},
+ "class": {"LOCAL_MODULE_CLASS", bpparser.String},
+ "stl": {"LOCAL_CXX_STL", bpparser.String},
+ "strip": {"LOCAL_STRIP_MODULE", bpparser.String},
+ "compile_multilib": {"LOCAL_MULTILIB", bpparser.String},
+ "instruction_set": {"LOCAL_ARM_MODE_HACK", bpparser.String},
+ "sdk_version": {"LOCAL_SDK_VERSION", bpparser.String},
+ //"stl": "LOCAL_NDK_STL_VARIANT", TODO
+ "manifest": {"LOCAL_JAR_MANIFEST", bpparser.String},
+ "jarjar_rules": {"LOCAL_JARJAR_RULES", bpparser.String},
+ "certificate": {"LOCAL_CERTIFICATE", bpparser.String},
+ //"name": "LOCAL_PACKAGE_NAME", TODO
+
+ // ==== LIST PROPERTIES ====
+ "srcs": {"LOCAL_SRC_FILES", bpparser.List},
+ "shared_libs": {"LOCAL_SHARED_LIBRARIES", bpparser.List},
+ "static_libs": {"LOCAL_STATIC_LIBRARIES", bpparser.List},
+ "whole_static_libs": {"LOCAL_WHOLE_STATIC_LIBRARIES", bpparser.List},
+ "system_shared_libs": {"LOCAL_SYSTEM_SHARED_LIBRARIES", bpparser.List},
+ "include_dirs": {"LOCAL_C_INCLUDES", bpparser.List},
+ "export_include_dirs": {"LOCAL_EXPORT_C_INCLUDE_DIRS", bpparser.List},
+ "asflags": {"LOCAL_ASFLAGS", bpparser.List},
+ "clang_asflags": {"LOCAL_CLANG_ASFLAGS", bpparser.List},
+ "cflags": {"LOCAL_CFLAGS", bpparser.List},
+ "conlyflags": {"LOCAL_CONLYFLAGS", bpparser.List},
+ "cppflags": {"LOCAL_CPPFLAGS", bpparser.List},
+ "ldflags": {"LOCAL_LDFLAGS", bpparser.List},
+ "required": {"LOCAL_REQUIRED_MODULES", bpparser.List},
+ "tags": {"LOCAL_MODULE_TAGS", bpparser.List},
+ "host_ldlibs": {"LOCAL_LDLIBS", bpparser.List},
+ "clang_cflags": {"LOCAL_CLANG_CFLAGS", bpparser.List},
+ "yaccflags": {"LOCAL_YACCFLAGS", bpparser.List},
+ "java_resource_dirs": {"LOCAL_JAVA_RESOURCE_DIRS", bpparser.List},
+ "javacflags": {"LOCAL_JAVACFLAGS", bpparser.List},
+ "dxflags": {"LOCAL_DX_FLAGS", bpparser.List},
+ "java_libs": {"LOCAL_JAVA_LIBRARIES", bpparser.List},
+ "java_static_libs": {"LOCAL_STATIC_JAVA_LIBRARIES", bpparser.List},
+ "aidl_includes": {"LOCAL_AIDL_INCLUDES", bpparser.List},
+ "aaptflags": {"LOCAL_AAPT_FLAGS", bpparser.List},
+ "package_splits": {"LOCAL_PACKAGE_SPLITS", bpparser.List},
+
+ // ==== BOOL PROPERTIES ====
+ "host": {"LOCAL_IS_HOST_MODULE", bpparser.Bool},
+ "clang": {"LOCAL_CLANG", bpparser.Bool},
+ "static": {"LOCAL_FORCE_STATIC_EXECUTABLE", bpparser.Bool},
+ "asan": {"LOCAL_ADDRESS_SANITIZER", bpparser.Bool},
+ "native_coverage": {"LOCAL_NATIVE_COVERAGE", bpparser.Bool},
+ "nocrt": {"LOCAL_NO_CRT", bpparser.Bool},
+ "allow_undefined_symbols": {"LOCAL_ALLOW_UNDEFINED_SYMBOLS", bpparser.Bool},
+ "rtti": {"LOCAL_RTTI_FLAG", bpparser.Bool},
+ "no_standard_libraries": {"LOCAL_NO_STANDARD_LIBRARIES", bpparser.Bool},
+ "export_package_resources": {"LOCAL_EXPORT_PACKAGE_RESOURCES", bpparser.Bool},
+}
+
+var moduleTypes = map[string]string{
+ "cc_library_shared": "BUILD_SHARED_LIBRARY",
+ "cc_library_static": "BUILD_STATIC_LIBRARY",
+ "cc_library_host_shared": "BUILD_HOST_SHARED_LIBRARY",
+ "cc_library_host_static": "BUILD_HOST_STATIC_LIBRARY",
+ "cc_binary": "BUILD_EXECUTABLE",
+ "cc_binary_host": "BUILD_HOST_EXECUTABLE",
+ "cc_test": "BUILD_NATIVE_TEST",
+ "cc_test_host": "BUILD_HOST_NATIVE_TEST",
+ "java_library": "BUILD_JAVA_LIBRARY",
+ "java_library_static": "BUILD_STATIC_JAVA_LIBRARY",
+ "java_library_host": "BUILD_HOST_JAVA_LIBRARY",
+ "java_library_host_dalvik": "BUILD_HOST_DALVIK_JAVA_LIBRARY",
+ "android_app": "BUILD_PACKAGE",
+ "prebuilt": "BUILD_PREBUILT",
+}
diff --git a/build.ninja.in b/build.ninja.in
index f579c576..f9aef06c 100644
--- a/build.ninja.in
+++ b/build.ninja.in
@@ -49,6 +49,30 @@ rule g.bootstrap.link
description = ${g.bootstrap.goChar}l ${out}
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+# Module: androidbp
+# Variant:
+# Type: bootstrap_go_binary
+# Factory: github.com/google/blueprint/bootstrap.newGoBinaryModule
+# Defined: build/soong/Blueprints:183:1
+
+build .bootstrap/androidbp/obj/androidbp.a: g.bootstrap.gc $
+ ${g.bootstrap.srcDir}/build/soong/androidbp/cmd/androidbp.go $
+ ${g.bootstrap.srcDir}/build/soong/androidbp/cmd/soong.go | $
+ ${g.bootstrap.gcCmd} $
+ .bootstrap/blueprint-parser/pkg/github.com/google/blueprint/parser.a
+ incFlags = -I .bootstrap/blueprint-parser/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
+default .bootstrap/androidbp/obj/a.out
+
+build .bootstrap/bin/androidbp: g.bootstrap.cp .bootstrap/androidbp/obj/a.out
+default .bootstrap/bin/androidbp
+
+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Module: androidmk
# Variant:
# Type: bootstrap_go_binary
@@ -565,10 +589,11 @@ rule s.bootstrap.minibp
generator = true
build .bootstrap/main.ninja.in: s.bootstrap.bigbp $
- ${g.bootstrap.srcDir}/Blueprints | .bootstrap/bin/androidmk $
- .bootstrap/bin/bpfmt .bootstrap/bin/bpmodify .bootstrap/bin/minibp $
- .bootstrap/bin/soong_build .bootstrap/bin/soong_env $
- .bootstrap/bin/soong_glob .bootstrap/bin/soong_jar
+ ${g.bootstrap.srcDir}/Blueprints | .bootstrap/bin/androidbp $
+ .bootstrap/bin/androidmk .bootstrap/bin/bpfmt .bootstrap/bin/bpmodify $
+ .bootstrap/bin/minibp .bootstrap/bin/soong_build $
+ .bootstrap/bin/soong_env .bootstrap/bin/soong_glob $
+ .bootstrap/bin/soong_jar
default .bootstrap/main.ninja.in
build .bootstrap/notAFile: phony
default .bootstrap/notAFile